Lars Silvén wrote: > Hi Douglas, > > The extra bite is not a flag. It is needed in indata to the decryption > command since it is one byte longer than the signing command.
Is this a card specific requirement? Is it RSA specific? > The change will not affect other cards since the pointer to the signing > function is now pointing on the second byte in the buffer. The first byte will > only be used by card decryption commands. > If pkcs15-sec.c should be untouched we could allocate a new buffer inside > card-cardos.c that is one byte longer than the input and copy. Just thought > it was more simple and more effective doing as I did. Then it is also > possible that some other card needs to have this extra byte for decryption in > the future. > But if you insist that I remove the changes from pkcs15-sec.c I will do that. I am not insisting, but suggesting that this appears to be a card specific modification, and so should be localized to the card-cardos.c module. You mod is more likely to be accepted if you can localize it. > > Lars > > Douglas E. Engert wrote: >> Lars Silvén wrote: >>> Hi list, >>> >>> This is an attempt to persuade you to add functionality to opensc. >>> I have already made a patch that implements what is needed. This file is >>> attached. >>> >>> The patch make it possible to sign with keys on CardOS cards that was >>> generated to use only the decryption card command. >>> This is because you can not generate keys on CardOS that accepts both the >>> sign and decryption commands. >>> >>> Sometimes you want keys that is capable of both signing and decryption. >>> Even when a key only should be used for signing it could be preferable to >>> use the decryption command. This is when you use a padding where the MSB in >>> the RSA input differs 0 in the input (of modulus length) to the RSA >>> algorithm. >>> >>> All CardOS keys created by PrimeCard (see >>> http://primekey.se/primekey/en/Products/PrimeCard.html) are keys where only >>> the decrypt card command could >>> be used. But some of these keys are intended only for signing. >>> >>> The patch is only tested with cards issued by PrimeCard. https >>> authentication works fine with firefox using the opensc p11. >>> So you have to test that I have not messed anything up regarding other card >>> but I don't think it will be any problems with that. >> You are proposing changes to pkcs15-sec.c. this is used by all cards, not >> just the cardOS. >> I don't understand the need to add the leading 0 in the buf, and how this >> change would effect >> other cards. Is this meant to be a flag? Then add a flag to the sc_card card >> structure. >> Can you move your code out of pkcs15-sec, and into card-cardos.c? >> >>> I will be happy to send PrimeCard issued cards to those of you that will >>> test and add this patch to opensc as well as to maintainers of the project. >>> Just give me the mailing addresses. >>> >>> Best Regards >>> Lars >>> >>> >>> ------------------------------------------------------------------------ >>> >>> diff -Naur opensc-0.11.3/src/libopensc/card-cardos.c >>> opensc-0.11.3-new/src/libopensc/card-cardos.c >>> --- opensc-0.11.3/src/libopensc/card-cardos.c 2007-07-09 >>> 10:17:32.000000000 +0200 >>> +++ opensc-0.11.3-new/src/libopensc/card-cardos.c 2007-08-01 >>> 22:46:30.000000000 +0200 >>> @@ -686,6 +686,12 @@ >>> SC_FUNC_RETURN(card->ctx, 1, r); >>> } >>> >>> +/* >>> + * Saved when cardos_set_security_env is called. >>> + * To be used when signing if decryption command must be used. >>> + * The object of the pointer is on the stack of >>> pkcs15-sec.c:sc_pkcs15_compute_signature >>> + */ >>> +static sc_security_env_t *pEnvSaved; >>> /* >>> * Set the security context >>> * Things get a little messy here. It seems you cannot do any >>> @@ -704,7 +710,7 @@ >>> sc_apdu_t apdu; >>> u8 data[3]; >>> int key_id, r; >>> - >>> + pEnvSaved = env; >>> assert(card != NULL && env != NULL); >>> >>> if (!(env->flags & SC_SEC_ENV_KEY_REF_PRESENT) >>> @@ -774,6 +780,35 @@ >>> SC_FUNC_RETURN(card->ctx, 4, sc_check_sw(card, apdu.sw1, >>> apdu.sw2)); >>> } >>> >>> +/* Internal function using the decryption command of the card to do the >>> RSA operation in a signing. Used when the signing command on the card does >>> not work for a key. */ >>> +static int >>> +do_decryption(sc_card_t *card, const u8 *data, size_t datalen, >>> + u8 *out, size_t outlen) >>> +{ >>> + int r; >>> + sc_apdu_t apdu; >>> + >>> + /* INS: 0x2A PERFORM SECURITY OPERATION >>> + * P1: 0x80 Resp: Decryption >>> + * P2: 0x86 Cmd: Input for Decrytption */ >>> + sc_format_apdu(card, &apdu, SC_APDU_CASE_4, 0x2A, 0x80, 0x86); >>> + apdu.resp = out; >>> + apdu.le = outlen; >>> + apdu.resplen = outlen; >>> + >>> + apdu.data = data-1; /* a first extra byte must be appended when the >>> decryption command is used for the RSA operation */ >>> + apdu.lc = datalen+1; /* this byte is allocated by >>> pkcs15-sec.c:sc_pkcs15_compute_signature */ >>> + apdu.datalen = datalen+1; >>> + apdu.sensitive = 1; >>> + r = sc_transmit_apdu(card, &apdu); >>> + SC_TEST_RET(card->ctx, r, "APDU transmit failed"); >>> + >>> + if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) >>> + SC_FUNC_RETURN(card->ctx, 4, apdu.resplen); >>> + else >>> + SC_FUNC_RETURN(card->ctx, 4, sc_check_sw(card, apdu.sw1, >>> apdu.sw2)); >>> +} >>> + >>> static int >>> cardos_compute_signature(sc_card_t *card, const u8 *data, size_t datalen, >>> u8 *out, size_t outlen) >>> @@ -831,7 +866,18 @@ >>> r = sc_pkcs1_strip_digest_info_prefix(NULL,buf,tmp_len,buf,&buf_len); >>> if (r != SC_SUCCESS) >>> SC_FUNC_RETURN(ctx, 4, r); >>> - return do_compute_signature(card, buf, buf_len, out, outlen); >>> + sc_ctx_suppress_errors_on(ctx); >>> + r = do_compute_signature(card, buf, buf_len, out, outlen); >>> + sc_ctx_suppress_errors_off(ctx); >>> + if (r >= SC_SUCCESS) >>> + SC_FUNC_RETURN(ctx, 4, r); >>> + /* maybe it is only possible to use the decryption command of the card >>> for this key.*/ >>> + /* pEnvSaved is set in the call to cardos_set_security_env */ >>> + pEnvSaved->operation = SC_SEC_OPERATION_DECIPHER; >>> + r = sc_set_security_env(card, pEnvSaved, 0); >>> + if (r != SC_SUCCESS) >>> + SC_FUNC_RETURN(ctx, 4, r); >>> + return do_decryption(card, data, datalen, out, outlen); >>> } >>> >>> static int >>> diff -Naur opensc-0.11.3/src/libopensc/pkcs15-sec.c >>> opensc-0.11.3-new/src/libopensc/pkcs15-sec.c >>> --- opensc-0.11.3/src/libopensc/pkcs15-sec.c 2007-04-20 >>> 09:12:54.000000000 +0200 >>> +++ opensc-0.11.3-new/src/libopensc/pkcs15-sec.c 2007-08-01 >>> 21:46:19.000000000 +0200 >>> @@ -143,7 +143,7 @@ >>> sc_context_t *ctx = p15card->card->ctx; >>> sc_algorithm_info_t *alg_info; >>> const struct sc_pkcs15_prkey_info *prkey = (const struct >>> sc_pkcs15_prkey_info *) obj->data; >>> - u8 buf[512], *tmp; >>> + u8 buf[513], *tmp; >>> size_t modlen = prkey->modulus_length / 8; >>> unsigned long pad_flags = 0, sec_flags = 0; >>> >>> @@ -167,10 +167,14 @@ >>> senv.algorithm = SC_ALGORITHM_RSA; >>> >>> /* Probably never happens, but better make sure */ >>> - if (inlen > sizeof(buf) || outlen < modlen) >>> + if (inlen+1 > sizeof(buf) || outlen < modlen) >>> return SC_ERROR_BUFFER_TOO_SMALL; >>> - memcpy(buf, in, inlen); >>> - tmp = buf; >>> + memcpy(buf+1, in, inlen); >>> + /* First byte buf[0] to be used when the decryption command of the card >>> has to be used for the RSA operation in the signing. */ >>> + /* Only used when the signing command of the card can't be used on a >>> key. When signing command is used for RSA operation buf[0] is not used.*/ >>> + /* All calls to the signing implementation function are done with the >>> data input pointer pointing to buf[1] */ >>> + tmp = buf+1; >>> + *buf = 0; >>> >>> /* flags: the requested algo >>> * algo_info->flags: what is supported by the card >>> @@ -181,7 +185,7 @@ >>> if ((flags == (SC_ALGORITHM_RSA_PAD_PKCS1 | >>> SC_ALGORITHM_RSA_HASH_NONE)) && >>> !(alg_info->flags & (SC_ALGORITHM_RSA_RAW | >>> SC_ALGORITHM_RSA_HASH_NONE))) { >>> unsigned int algo; >>> - size_t tmplen = sizeof(buf); >>> + size_t tmplen = sizeof(buf)-1; >>> r = sc_pkcs1_strip_digest_info_prefix(&algo, tmp, inlen, tmp, >>> &tmplen); >>> if (r != SC_SUCCESS || algo == SC_ALGORITHM_RSA_HASH_NONE) { >>> sc_mem_clear(buf, sizeof(buf)); >>> @@ -201,14 +205,14 @@ >>> >>> /* add the padding bytes (if necessary) */ >>> if (pad_flags != 0) { >>> - size_t tmplen = sizeof(buf); >>> + size_t tmplen = sizeof(buf)-1; >>> r = sc_pkcs1_encode(ctx, pad_flags, tmp, inlen, tmp, &tmplen, >>> modlen); >>> SC_TEST_RET(ctx, r, "Unable to add padding"); >>> inlen = tmplen; >>> } else if ((flags & SC_ALGORITHM_RSA_PADS) == >>> SC_ALGORITHM_RSA_PAD_NONE) { >>> /* Add zero-padding if input is shorter than the modulus */ >>> if (inlen < modlen) { >>> - if (modlen > sizeof(buf)) >>> + if (modlen+1 > sizeof(buf)) >>> return SC_ERROR_BUFFER_TOO_SMALL; >>> memmove(tmp+modlen-inlen, tmp, inlen); >>> memset(tmp, 0, modlen-inlen); >>> >>> >>> ------------------------------------------------------------------------ >>> >>> _______________________________________________ >>> opensc-devel mailing list >>> opensc-devel@lists.opensc-project.org >>> http://www.opensc-project.org/mailman/listinfo/opensc-devel > > -- Douglas E. Engert <[EMAIL PROTECTED]> Argonne National Laboratory 9700 South Cass Avenue Argonne, Illinois 60439 (630) 252-5444 _______________________________________________ opensc-devel mailing list opensc-devel@lists.opensc-project.org http://www.opensc-project.org/mailman/listinfo/opensc-devel