[openssl-users] How to properly use ui_method in ENGINE_load_private_key()?

Blumenthal, Uri - 0553 - MITLL uri at ll.mit.edu
Sun Feb 28 22:31:39 UTC 2016


I am writing an app that needs to use RSA keys on a PKCS11-accessible token to encrypt and decrypt symmetric keys. For the context (no pun intended :) think of creating or mounting an existing encrypted file system.

To begin with, and to grasp the finer details of the programmatic interface of libcrypto, I’m “sculpting” my code after apps/pkeyutl.c and apps/apps.c.

When I use “init_cx()” that in turn calls “load_key()” method in “apps.o” (and link my code with “apps.o” in addition to “-lcrypto”), everything works fine:

We expect an RSA token for this demo...
Input buffer:
01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10
10 0f 0e 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01

encrypt: allocating 256 bytes (rv=1)
RSA encryption succeeded (rv=1 len=256):
10 e5 a6 95 63 48 54 3f e2 84 7f 9c 39 6f 8c cd
9a ef 18 3b 66 32 46 bf 9f d4 76 91 ce 98 5d 33
cd a7 cf 4e b7 d5 98 51 2d e3 8e 4f 09 52 1d 0f
fa 3f 33 5c d9 d3 3b 2f a4 4f 87 17 73 09 c0 23
c7 56 40 ce 5f 3f 61 b1 b7 94 43 98 9f d0 cc c0
cd 38 e2 94 c4 64 a0 8f 3d fe e4 03 18 5f 83 9d
da 04 42 3a f3 ad c1 3b 0c f3 60 f9 f8 c8 bc 95
83 2f 67 9b b7 3a 38 fe 79 66 30 80 7f 17 00 31
71 ee 2e c6 cd 7b 09 f3 09 eb c0 bd 45 4b 88 a9
36 23 87 71 a0 12 78 ba c5 34 be 8e ca c4 07 73
cd ea a9 90 c2 bf 31 aa ee ba 49 18 74 2e 9b 8c
97 94 cb 11 5e cd fc 24 e5 84 e4 9f 17 5a ac 2b
6d a5 61 bf 5d 3e 00 49 99 b0 90 32 33 02 42 ac
fc 46 db 1d 8e 1d 7e 7e a4 a1 e3 c8 60 43 28 26
ef c4 84 d2 0d cf 92 61 75 bc 0c d9 47 b1 bb 9e
78 00 32 b8 4b 35 c2 08 ad f6 f7 f8 bf e1 13 b1
PKCS#11 token PIN: xxxxxxxx

decrypt: allocating 256 bytes (rv=1)
RSA decryption succeeded (rv=1 len=32):
01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10
10 0f 0e 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01

However when I try to call the EVP methods directly instead of going through the routines provided in apps.c, the decryption fails:

……

Encrypted symmetric key (256 bytes):
76 f8 e9 b0 38 45 b5 fd b4 8e 96 f9 8a 86 ab 5a
83 42 a4 b8 7e 06 e0 b7 ae 8c 7f 6c 5e 68 bd eb
bf 3f 87 0c f8 0e 90 8f cd ec 01 f7 80 a8 71 00
3d 7a 5d 30 db 7f 7b 18 e2 de c0 c2 9e 07 ca 1f
6c 9e dc 13 82 19 cd 49 7a fc 2c f0 52 ad 74 4a
da f5 e5 71 50 d3 f9 e6 fc eb 67 6c 82 fa 00 e6
8f 2f 0a a0 9d c7 a6 85 5f 8e 93 07 53 9c e5 b3
23 9b fe 36 88 e5 7f f4 cf 81 13 dc 58 de e6 e1
d5 fe bf 5b db 5d a1 63 29 3e 96 13 d2 1a b6 b2
1f 95 73 90 97 86 ce e3 de 08 8d bc a3 11 9f 04
f5 f4 8d 8f 32 29 2c 91 74 0f 85 ab 75 3a c3 58
3e e9 30 48 f2 ae 67 08 f7 14 ce 0c 73 50 3b d4
94 aa 15 a3 79 e1 5b 27 a4 80 b9 71 53 5b 46 13
f2 c5 4b 0e 1d c7 57 3b 9f f4 a3 55 09 37 1a 47
68 0c e4 fc 86 1e d0 cc 3d 4d d7 25 7c 40 77 ba
74 a5 ce 60 03 ea d4 54 a2 58 52 b5 aa bf 4a d2

PKCS#11 token PIN: xxxxxxxx

unwrap: loaded privkey of size 256
unwrap: allocating 256 bytes...
unwrap: decrypt returned 1 (0 bytes)
unwrapping returned 1
Decrypted symmetric key (0 bytes):

You can see that up to the actual loading of the private key things are the same, and both variants of the app (the one using apps.c, and the one trying to directly call the EVP API) show the same prompt for the token PIN, and in both cases it appears (though I’m not sure at all of that) that the private key handle gets loaded.

The opens-debug.log file shows that there was a problem with the authentication to the token:

0x7fff739f3000 16:10:25.4294968080 [opensc-pkcs11] card-piv.c:2310:piv_validate_general_authentication: returning with: -1208 (Card does not support the requested operation)
0x7fff739f3000 16:10:25.784 [opensc-pkcs11] card-piv.c:2419:piv_decipher: returning with: -1208 (Card does not support the requested operation)
0x7fff739f3000 16:10:25.784 [opensc-pkcs11] sec.c:44:sc_decipher: returning with: -1208 (Card does not support the requested operation)
0x7fff739f3000 16:10:25.784 [opensc-pkcs11] card-piv.c:2221:piv_set_security_env: called
0x7fff739f3000 16:10:25.784 [opensc-pkcs11] card-piv.c:2252:piv_set_security_env: returning with: 0 (Success)
0x7fff739f3000 16:10:25.140552804762384 [opensc-pkcs11] sec.c:72:sc_set_security_env: returning with: 0 (Success)
0x7fff739f3000 16:10:25.784 [opensc-pkcs11] card-piv.c:2417:piv_decipher: called
0x7fff739f3000 16:10:25.4294968080 [opensc-pkcs11] card-piv.c:2281:piv_validate_general_authentication: called
0x7fff739f3000 16:10:25.4294968080 [opensc-pkcs11] card-piv.c:2310:piv_validate_general_authentication: returning with: -1208 (Card does not support the requested operation)
0x7fff739f3000 16:10:25.784 [opensc-pkcs11] card-piv.c:2419:piv_decipher: returning with: -1208 (Card does not support the requested operation)
0x7fff739f3000 16:10:25.784 [opensc-pkcs11] sec.c:44:sc_decipher: returning with: -1208 (Card does not support the requested operation)

This differs from what the log shows when the private key was loaded with “load_key()”:

0x7fff739f3000 16:12:35.132 [opensc-pkcs11] reader-pcsc.c:313:refresh_attributes: returning with: 0 (Success)
0x7fff739f3000 16:12:35.140733193388164 [opensc-pkcs11] reader-pcsc.c:389:pcsc_detect_card_presence: returning with: 5
0x7fff739f3000 16:12:35.4294967435 [opensc-pkcs11] sec.c:206:sc_pin_cmd: returning with: 0 (Success)
0x7fff739f3000 16:12:37.939 [opensc-pkcs11] sec.c:206:sc_pin_cmd: returning with: 0 (Success)
0x7fff739f3000 16:12:37.940 [opensc-pkcs11] card-piv.c:2221:piv_set_security_env: called
0x7fff739f3000 16:12:37.940 [opensc-pkcs11] card-piv.c:2252:piv_set_security_env: returning with: 0 (Success)
0x7fff739f3000 16:12:37.140295106724780 [opensc-pkcs11] sec.c:72:sc_set_security_env: returning with: 0 (Success)
0x7fff739f3000 16:12:37.940 [opensc-pkcs11] card-piv.c:2417:piv_decipher: called
0x7fff739f3000 16:12:37.140733193388972 [opensc-pkcs11] card-piv.c:2281:piv_validate_general_authentication: called
0x7fff739f3000 16:12:37.4294968236 [opensc-pkcs11] card-piv.c:454:piv_general_io: called
0x7fff739f3000 16:12:38.608 [opensc-pkcs11] card-piv.c:2419:piv_decipher: returning with: 256
0x7fff739f3000 16:12:38.608 [opensc-pkcs11] sec.c:44:sc_decipher: returning with: 256
0x7fff739f3000 16:12:38.609 [opensc-pkcs11] card-piv.c:2819:piv_finish: called
0x7fff739f3000 16:12:38.140295106724457 [opensc-pkcs11] ctx.c:818:sc_release_context: called

Here’s the relevant excerpt from the code that fails:

/* Retrieve the handle to private key on the token */
/* Here need to get user PIN somehow ... */
PW_CB_DATA cb_data;
cb_data.password = NULL;
cb_data.prompt_info = "id_03";
privkey = ENGINE_load_private_key(*e, "id_03", NULL, &cb_data);
if (privkey == NULL) {
fprintf(stderr, "unwrap: failed to get handle to privkey id_03\n");
goto end;
}
printf("unwrap: loaded privkey of size %1d\n", EVP_PKEY_size(privkey));

/* Create context */
ctx = EVP_PKEY_CTX_new(privkey, NULL);
EVP_PKEY_free(privkey);
if (ctx == NULL) {
fprintf(stderr, "unwrap: failed to create context\n");
goto end;
}
rv = EVP_PKEY_decrypt_init(ctx);
EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING);
if (rv <= 0) {
fprintf(stderr, "unwrap: failed to initialize decrypt_ctx (rv=%d\n", rv);
goto end;
}

/* Unwrap the encrypted key */
*olen = 0;
rv = EVP_PKEY_decrypt(ctx, NULL, olen, in, inlen);
if ((rv <= 0) || (*olen == 0)) {
fprintf(stderr, "unwrap: failed to get required output buf len (rv=%d)\n", rv);
goto end;
}
printf("unwrap: allocating %1lu bytes...\n", *olen);
*out = OPENSSL_malloc(*olen);
if (*out == NULL) {
fprintf(stderr, "unwrap: failed to allocate output buf (%1lu bytes)\n", *olen);
rv = -1;
goto end;
}
rv = EVP_PKEY_decrypt(ctx, *out, olen, in, inlen);
if (rv <= 0) {
OPENSSL_free(*out);
fprintf(stderr, "unwrap: failed to decrypt (rv=%d)\n", rv);
goto end;
}
printf("unwrap: decrypt returned %d (%1lu bytes)\n", rv, *olen);


I tried, but could not figure out from looking at “apps.c” what structures and methods I need to pass to “ENGINE_load_private_key()”, and how to properly initialize them. Web searches did not help.

I’d appreciate guidance, as I’d rather not pull the entire “apps.c” into the app I’m building, it it can be avoided.

Thanks!
--
Regards,
Uri Blumenthal
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mta.openssl.org/pipermail/openssl-users/attachments/20160228/d9782b61/attachment-0001.html>


More information about the openssl-users mailing list