krb5 commit: Get better at locating the just-loaded certificate

Greg Hudson ghudson at MIT.EDU
Mon May 13 02:00:06 EDT 2013


https://github.com/krb5/krb5/commit/9d429bb8a78060334d2a533723fe549c72cba68e
commit 9d429bb8a78060334d2a533723fe549c72cba68e
Author: Nalin Dahyabhai <nalin at dahyabhai.net>
Date:   Wed Apr 24 15:22:05 2013 -0400

    Get better at locating the just-loaded certificate
    
    When loading certificates using the PEM module, use a better method for
    finding the just-loaded certificate that will still work if we've
    already got a copy of the certificate loaded somewhere else.

 src/plugins/preauth/pkinit/pkinit_crypto_nss.c |   93 +++++++++---------------
 1 files changed, 35 insertions(+), 58 deletions(-)

diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_nss.c b/src/plugins/preauth/pkinit/pkinit_crypto_nss.c
index 4b46d62..0c798b5 100644
--- a/src/plugins/preauth/pkinit/pkinit_crypto_nss.c
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_nss.c
@@ -2498,15 +2498,13 @@ crypto_load_files(krb5_context context,
 {
     PK11SlotInfo *slot;
     struct _pkinit_identity_crypto_file *cobj, *kobj, **id_objects;
-    PRBool permanent, match;
-    CERTCertificate *cert;
-    CERTCertList *before, *after;
-    CERTCertListNode *anode, *bnode;
+    PRBool permanent;
     SECKEYPrivateKey *key;
     CK_ATTRIBUTE attrs[4];
     CK_BBOOL cktrue = CK_TRUE, cktrust;
     CK_OBJECT_CLASS keyclass = CKO_PRIVATE_KEY, certclass = CKO_CERTIFICATE;
-    SECItem a, b, tmp, *crl, **crls;
+    CERTCertificate *cert;
+    SECItem tmp, *crl, **crls;
     SECStatus status;
     int i, j, n_attrs, n_objs, n_crls;
 
@@ -2528,7 +2526,6 @@ crypto_load_files(krb5_context context,
     /* Load the certificate first to work around RHBZ#859535. */
     cobj = NULL;
     if (certfile != NULL) {
-        before = PK11_ListCertsInSlot(slot);
         n_attrs = 0;
         crypto_set_attributes(&attrs[n_attrs++], CKA_CLASS,
                               &certclass, sizeof(certclass));
@@ -2570,62 +2567,42 @@ crypto_load_files(krb5_context context,
                 id_objects[i++] = NULL;
                 id_cryptoctx->id_objects = id_objects;
             }
-        }
-        /* Add any certs which are in the slot now, but which weren't
-         * before, to the right list of certs.  (I don't see an API to
-         * get the certificate from the generic object that we just
-         * created, so we do it the hard way.) */
-        after = PK11_ListCertsInSlot(slot);
-        if (after != NULL) {
-            for (anode = CERT_LIST_HEAD(after);
-                 (anode != NULL) &&
-                     (anode->cert != NULL) &&
-                     !CERT_LIST_END(anode, after);
-                 anode = CERT_LIST_NEXT(anode)) {
-                match = PR_FALSE;
-                a = anode->cert->derCert;
-                if (before != NULL) {
-                    for (bnode = CERT_LIST_HEAD(before);
-                         (bnode != NULL) &&
-                             (bnode->cert != NULL) &&
-                             !CERT_LIST_END(bnode, before);
-                         bnode = CERT_LIST_NEXT(bnode)) {
-                        b = bnode->cert->derCert;
-                        if (SECITEM_ItemsAreEqual(&a, &b)) {
-                            match = PR_TRUE;
-                            break;
-                        }
-                    }
-                }
-                if (!match) {
-                    cert = CERT_DupCertificate(anode->cert);
-                    if (cert_self) {
-                        /* Add to the identity list. */
-                        if (cert_maybe_add_to_list
-                            (id_cryptoctx->id_certs, cert) != SECSuccess) {
-                            status = SECFailure;
-                        }
-                        cobj->cert = CERT_DupCertificate(cert);
-                    } else if (cert_mark_trusted) {
-                        /* Add to the CA list. */
-                        if (cert_maybe_add_to_list
-                            (id_cryptoctx->ca_certs, cert) != SECSuccess) {
-                            status = SECFailure;
-                        }
-                    } else {
-                        /* Don't just lose the ref. */
-                        CERT_DestroyCertificate(cert);
-                    }
+            /* Find the certificate that goes with this generic object. */
+            memset(&tmp, 0, sizeof(tmp));
+            status = PK11_ReadRawAttribute(PK11_TypeGeneric, cobj->obj,
+                                           CKA_VALUE, &tmp);
+            if (status == SECSuccess) {
+                cobj->cert = CERT_FindCertByDERCert(CERT_GetDefaultCertDB(),
+                                                    &tmp);
+                SECITEM_FreeItem(&tmp, PR_FALSE);
+            } else {
+                pkiDebug("%s: error locating certificate \"%s\"\n",
+                         __FUNCTION__, certfile);
+            }
+            /* Save a reference to the right list. */
+            if (cobj->cert != NULL) {
+                cert = CERT_DupCertificate(cobj->cert);
+                if (cert == NULL)
+                    return SECFailure;
+                if (cert_self) {
+                    /* Add to the identity list. */
+                    if (cert_maybe_add_to_list(id_cryptoctx->id_certs,
+                                               cert) != SECSuccess)
+                        status = SECFailure;
+                } else if (cert_mark_trusted) {
+                    /* Add to the CA list. */
+                    if (cert_maybe_add_to_list(id_cryptoctx->ca_certs,
+                                               cert) != SECSuccess)
+                        status = SECFailure;
+                } else {
+                    /* Don't just lose the reference. */
+                    CERT_DestroyCertificate(cert);
                 }
             }
-            CERT_DestroyCertList(after);
-        }
-        if (before != NULL) {
-            CERT_DestroyCertList(before);
         }
     }
 
-    /* Now what should be the corresponding private key. */
+    /* Now load what should be the corresponding private key. */
     kobj = NULL;
     if (status == SECSuccess && keyfile != NULL) {
         n_attrs = 0;
@@ -2666,7 +2643,7 @@ crypto_load_files(krb5_context context,
         }
 
         /* If we loaded a key and a certificate, see if they match. */
-        if (cobj != NULL && cobj->cert != NULL) {
+        if (cobj != NULL && cobj->cert != NULL && kobj->obj != NULL) {
             key = PK11_FindPrivateKeyFromCert(slot, cobj->cert,
                                               crypto_pwcb_prep(id_cryptoctx,
                                                                context));


More information about the cvs-krb5 mailing list