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