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

Reply via email to