Hi,

I can't use it:

$ patch -p0 < ../pkcs11.diff
patching file src/pkcs11/framework-pkcs15.c
patch: **** malformed patch at line 10: struct pkcs15_prkey_object {

Please provide a new patch against trunk (which is not @ r18006) as an  
attachment.


Thanks,
Martin

On 02.10.2009, at 16:29, Pierre Ossman wrote:

> ===================================================================
> --- src/pkcs11/framework-pkcs15.c     (revision 18006)
> +++ src/pkcs11/framework-pkcs15.c     (working copy)
> @@ -82,6 +82,7 @@
> #define cert_p15obj           base.p15_object
> #define cert_pubkey           base.related_pubkey
> #define cert_issuer           base.related_cert
> +#define cert_prvkey          base.related_privkey
>
> struct pkcs15_prkey_object {
>       struct pkcs15_any_object        base;
> @@ -91,7 +92,6 @@
> #define prv_flags             base.base.flags
> #define prv_p15obj            base.p15_object
> #define prv_pubkey            base.related_pubkey
> -#define prv_cert             base.related_cert
> #define prv_next              base.related_privkey
>
> struct pkcs15_pubkey_object {
> @@ -102,7 +102,7 @@
> };
> #define pub_flags             base.base.flags
> #define pub_p15obj            base.p15_object
> -#define pub_cert             base.related_cert
> +#define pub_genfrom          base.related_cert
>
> #define __p15_type(obj)               (((obj) && (obj)->p15_object)? ((obj)- 
> >p15_object->type) : (unsigned int)-1)
> #define is_privkey(obj)               (__p15_type(obj) == 
> SC_PKCS15_TYPE_PRKEY_RSA)
> @@ -343,7 +343,7 @@
>       } else
>               obj2->pub_data = NULL; /* will copy from cert when cert is read 
> */
>
> -     obj2->pub_cert = object;
> +     obj2->pub_genfrom = object;
>       object->cert_pubkey = obj2;
>
>       if (cert_object != NULL)
> @@ -481,18 +481,12 @@
>                               *pp = (struct pkcs15_prkey_object *) obj;
>                       }
>               } else
> -             if (is_cert(obj) && !pk->prv_cert) {
> -                     struct pkcs15_cert_object *cert;
> -                     
> -                     cert = (struct pkcs15_cert_object *) obj;
> -                     if (sc_pkcs15_compare_id(&cert->cert_info->id, id))
> -                             pk->prv_cert = cert;
> -             } else
>               if (is_pubkey(obj) && !pk->prv_pubkey) {
>                       struct pkcs15_pubkey_object *pubkey;
>                       
>                       pubkey = (struct pkcs15_pubkey_object *) obj;
>                       if (sc_pkcs15_compare_id(&pubkey->pub_info->id, id)) {
> +                             sc_debug(context, "Associating object %d as 
> public key", i);
>                               pk->prv_pubkey = pubkey;
>                               if (pk->prv_info->modulus_length == 0)
>                                       pk->prv_info->modulus_length = 
> pubkey->pub_info->modulus_length;
> @@ -504,25 +498,37 @@
> static void
> __pkcs15_cert_bind_related(struct pkcs15_fw_data *fw_data, struct  
> pkcs15_cert_object *cert)
> {
> -     struct sc_pkcs15_cert *c1 = cert->cert_data, *c2;
> +     struct sc_pkcs15_cert *c1 = cert->cert_data;
> +     sc_pkcs15_id_t *id = &cert->cert_info->id;
>       unsigned int i;
>
> -     /* Loop over all certificates see if we find the certificate of
> -      * the issuer */
> +     /* Loop over all objects to see if we find the certificate of
> +      * the issuer and the associated private key */
>       for (i = 0; i < fw_data->num_objects; i++) {
>               struct pkcs15_any_object *obj = fw_data->objects[i];
>
> -             if (!is_cert(obj) || obj == (struct pkcs15_any_object *) cert)
> -                     continue;
> +             if (is_cert(obj) && obj != (struct pkcs15_any_object *) cert) {
> +                     struct sc_pkcs15_cert *c2;
>
> -             c2 = ((struct pkcs15_cert_object *) obj)->cert_data;
> +                     c2 = ((struct pkcs15_cert_object *) obj)->cert_data;
>
> -             if (!c1 || !c2 || !c1->issuer_len || !c2->subject_len)
> -                     continue;
> -             if (c1->issuer_len == c2->subject_len
> -              && !memcmp(c1->issuer, c2->subject, c1->issuer_len)) {
> -                     cert->cert_issuer = (struct pkcs15_cert_object *) obj;
> -                     return;
> +                     if (!c1 || !c2 || !c1->issuer_len || !c2->subject_len)
> +                             continue;
> +                     if (c1->issuer_len == c2->subject_len
> +                      && !memcmp(c1->issuer, c2->subject, c1->issuer_len)) {
> +                             sc_debug(context, "Associating object %d as 
> issuer", i);
> +                             cert->cert_issuer = (struct pkcs15_cert_object 
> *) obj;
> +                             return;
> +                     }
> +             } else
> +             if (is_privkey(obj) && !cert->cert_prvkey) {
> +                     struct pkcs15_prkey_object *pk;
> +                     
> +                     pk = (struct pkcs15_prkey_object *) obj;
> +                     if (sc_pkcs15_compare_id(&pk->prv_info->id, id)) {
> +                             sc_debug(context, "Associating object %d as 
> private key", i);
> +                             cert->cert_prvkey = pk;
> +                     }
>               }
>       }
> }
> @@ -540,6 +546,9 @@
>
>               if (obj->base.flags & SC_PKCS11_OBJECT_HIDDEN)
>                       continue;
> +
> +             sc_debug(context, "Looking for objects related to object %d", 
> i);
> +
>               if (is_privkey(obj)) {
>                       __pkcs15_prkey_bind_related(fw_data, (struct 
> pkcs15_prkey_object  
> *) obj);
>               } else if (is_cert(obj)) {
> @@ -606,6 +615,9 @@
>                 struct pkcs15_any_object *obj,
>                 CK_OBJECT_HANDLE_PTR pHandle)
> {
> +     int i;
> +     struct pkcs15_fw_data *card_fw_data;
> +
>       if (obj == NULL
>        || (obj->base.flags & (SC_PKCS11_OBJECT_HIDDEN |  
> SC_PKCS11_OBJECT_RECURS)))
>               return;
> @@ -630,9 +642,22 @@
>
>       switch (__p15_type(obj)) {
>       case SC_PKCS15_TYPE_PRKEY_RSA:
> -             if (obj->related_cert == NULL)
> -                     pkcs15_add_object(slot, (struct pkcs15_any_object *) 
> obj- 
> >related_pubkey, NULL);
> -             pkcs15_add_object(slot, (struct pkcs15_any_object *) obj- 
> >related_cert, NULL);
> +             pkcs15_add_object(slot, (struct pkcs15_any_object *) obj- 
> >related_pubkey, NULL);
> +             card_fw_data = (struct pkcs15_fw_data *) slot->card->fw_data;
> +             for (i = 0; i < card_fw_data->num_objects; i++) {
> +                     struct pkcs15_any_object *obj2 = 
> card_fw_data->objects[i];
> +                     struct pkcs15_cert_object *cert;
> +
> +                     if (!is_cert(obj2))
> +                             continue;
> +
> +                     cert = (struct pkcs15_cert_object*) obj2;
> +
> +                     if (cert->cert_prvkey != obj)
> +                             continue;
> +             
> +                     pkcs15_add_object(slot, obj2, NULL);
> +             }
>               break;
>       case SC_PKCS15_TYPE_CERT_X509:
>               pkcs15_add_object(slot, (struct pkcs15_any_object *) obj- 
> >related_pubkey, NULL);
> @@ -788,10 +813,15 @@
>               for (j=0; j < fw_data->num_objects; j++) {
>                       struct pkcs15_any_object *obj = fw_data->objects[j];
>
> +                     /* "Fake" objects we've generated */
>                       if (__p15_type(obj) == (unsigned int)-1)
>                               continue;
> -                     else if (!sc_pkcs15_compare_id(&pin_info->auth_id, 
> &obj- 
> >p15_object->auth_id))
> +                     /* Some objects have an auth_id even though they are
> +                      * not private. Just ignore those... */
> +                     if (!(obj->p15_object->flags & 
> SC_PKCS15_CO_FLAG_PRIVATE))
>                               continue;
> +                     if (!sc_pkcs15_compare_id(&pin_info->auth_id, 
> &obj->p15_object- 
> >auth_id))
> +                             continue;
>
>                       if (is_privkey(obj)) {
>                               sc_debug(context, "Adding private key %d to PIN 
> %d\n", j, i);
> @@ -1924,25 +1954,43 @@
>       unsigned int usage;
>       size_t len;
>
> -     /* will use modulus from cert, or pubkey if possible */
> -     if (prkey->prv_cert && prkey->prv_cert->cert_pubkey) {
> -             /* make sure we have read the cert to get modulus etc but only 
> if  
> needed. */
> -             switch(attr->type) {
> -                     case CKA_MODULUS:
> -                     case CKA_PUBLIC_EXPONENT:
> -                     case CKA_MODULUS_BITS:
> -                             if (check_cert_data_read(fw_data, 
> prkey->prv_cert) != 0) {
> -                                     /* no cert found, maybe we have a 
> pub_key */
> -                                     if (prkey->prv_pubkey && 
> prkey->prv_pubkey->pub_data)
> -                                             key = 
> prkey->prv_pubkey->pub_data; /* may be NULL */
> -                             } else
> -                                     key = 
> prkey->prv_cert->cert_pubkey->pub_data;
> -                             break;
> -                     default:
> -                             key = prkey->prv_cert->cert_pubkey->pub_data;
> +     /* PKCS#11 requires us to supply CKA_MODULUS for private keys,
> +      * although that is not generally available from a smart card
> +      * (the key is supposed to be safely locked away after all).
> +      *
> +      * To work around this, we hope that we either have an associated
> +      * public key, or we try to find a certificate with the
> +      * corresponding public key.
> +      *
> +      * Note: We do the same thing for CKA_PUBLIC_EXPONENT as some
> +      *       applications assume they can get that from the private
> +      *       key, something PKCS#11 doesn't guarantee.
> +      */
> +     if ((attr->type == CKA_MODULUS) || (attr->type ==  
> CKA_PUBLIC_EXPONENT)) {
> +             /* First see if we have a associated public key */
> +             if (prkey->prv_pubkey)
> +                     key = prkey->prv_pubkey->pub_data;
> +             else {
> +                     /* Try to find a certificate with the public key */
> +                     unsigned int i;
> +
> +                     for (i = 0; i < fw_data->num_objects; i++) {
> +                             struct pkcs15_any_object *obj = 
> fw_data->objects[i];
> +                             struct pkcs15_cert_object *cert;
> +
> +                             if (!is_cert(obj))
> +                                     continue;
> +
> +                             cert = (struct pkcs15_cert_object*) obj;
> +
> +                             if (cert->cert_prvkey != prkey)
> +                                     continue;
> +
> +                             if (check_cert_data_read(fw_data, cert) == 0)
> +                                     key = cert->cert_pubkey->pub_data;
> +                     }
>               }
> -     } else if (prkey->prv_pubkey)
> -             key = prkey->prv_pubkey->pub_data;
> +     }
>
>       switch (attr->type) {
>       case CKA_CLASS:
> @@ -2259,7 +2307,7 @@
>                               CK_ATTRIBUTE_PTR attr)
> {
>       struct pkcs15_pubkey_object *pubkey = (struct  
> pkcs15_pubkey_object*) object;
> -     struct pkcs15_cert_object *cert = pubkey->pub_cert;
> +     struct pkcs15_cert_object *cert = pubkey->pub_genfrom;
>       struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) session- 
> >slot->card->fw_data;
>       size_t len;

-- 
Martin Paljak
http://martin.paljak.pri.ee
+372.515.6495




_______________________________________________
opensc-devel mailing list
opensc-devel@lists.opensc-project.org
http://www.opensc-project.org/mailman/listinfo/opensc-devel

Reply via email to