]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[crypto] Allow passing a NULL certificate store to x509_find() et al
authorMichael Brown <mcb30@ipxe.org>
Tue, 13 Aug 2024 11:25:25 +0000 (12:25 +0100)
committerMichael Brown <mcb30@ipxe.org>
Tue, 13 Aug 2024 11:26:31 +0000 (12:26 +0100)
Allow passing a NULL value for the certificate list to all functions
used for identifying an X.509 certificate from an existing set of
certificates, and rename function parameters to indicate that this
certificate list represents an unordered certificate store (rather
than an ordered certificate chain).

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/crypto/certstore.c
src/crypto/x509.c
src/include/ipxe/x509.h
src/net/tls.c

index f8ddbd3d7c5f7c6a24905d0a00ba7c179ea044a8..31797c4cd200967883c744035f1edce764bc7aab 100644 (file)
@@ -72,16 +72,16 @@ static struct x509_certificate certstore_certs[ sizeof ( certstore_raw ) /
 /**
  * Mark stored certificate as most recently used
  *
- * @v certs            X.509 certificate list
+ * @v store            Certificate store
  * @v cert             X.509 certificate
  */
-static void certstore_found ( struct x509_chain *certs,
+static void certstore_found ( struct x509_chain *store,
                              struct x509_certificate *cert ) {
 
        /* Mark as most recently used */
        list_del ( &cert->store.list );
-       list_add ( &cert->store.list, &certs->links );
-       DBGC2 ( certs, "CERTSTORE found certificate %s\n",
+       list_add ( &cert->store.list, &store->links );
+       DBGC2 ( store, "CERTSTORE found certificate %s\n",
                x509_name ( cert ) );
 }
 
index 341b91449fe32a854fd158b7458b047948056998..acb85620f987850656602aaf1086ed34fcf1f22f 100644 (file)
@@ -1079,7 +1079,7 @@ int x509_certificate ( const void *data, size_t len,
        asn1_shrink_any ( &cursor );
 
        /* Return stored certificate, if present */
-       if ( ( *cert = x509_find ( &certstore, &cursor ) ) != NULL ) {
+       if ( ( *cert = x509_find ( NULL, &cursor ) ) != NULL ) {
 
                /* Add caller's reference */
                x509_get ( *cert );
@@ -1714,16 +1714,19 @@ void x509_truncate ( struct x509_chain *chain, struct x509_link *link ) {
 /**
  * Mark X.509 certificate as found
  *
- * @v certs            X.509 certificate list
+ * @v store            Certificate store
  * @v cert             X.509 certificate
  * @ret cert           X.509 certificate
  */
-static struct x509_certificate * x509_found ( struct x509_chain *certs,
+static struct x509_certificate * x509_found ( struct x509_chain *store,
                                              struct x509_certificate *cert ) {
 
+       /* Sanity check */
+       assert ( store != NULL );
+
        /* Mark as found, if applicable */
-       if ( certs->found )
-               certs->found ( certs, cert );
+       if ( store->found )
+               store->found ( store, cert );
 
        return cert;
 }
@@ -1731,22 +1734,26 @@ static struct x509_certificate * x509_found ( struct x509_chain *certs,
 /**
  * Identify X.509 certificate by raw certificate data
  *
- * @v certs            X.509 certificate list
+ * @v store            Certificate store, or NULL to use default
  * @v raw              Raw certificate data
  * @ret cert           X.509 certificate, or NULL if not found
  */
-struct x509_certificate * x509_find ( struct x509_chain *certs,
+struct x509_certificate * x509_find ( struct x509_chain *store,
                                      const struct asn1_cursor *raw ) {
        struct x509_link *link;
        struct x509_certificate *cert;
 
+       /* Use default certificate store if none specified */
+       if ( ! store )
+               store = &certstore;
+
        /* Search for certificate within store */
-       list_for_each_entry ( link, &certs->links, list ) {
+       list_for_each_entry ( link, &store->links, list ) {
 
                /* Check raw certificate data */
                cert = link->cert;
                if ( asn1_compare ( raw, &cert->raw ) == 0 )
-                       return x509_found ( certs, cert );
+                       return x509_found ( store, cert );
        }
 
        return NULL;
@@ -1755,23 +1762,27 @@ struct x509_certificate * x509_find ( struct x509_chain *certs,
 /**
  * Identify X.509 certificate by subject
  *
- * @v certs            X.509 certificate list
+ * @v store            Certificate store, or NULL to use default
  * @v subject          Subject
  * @ret cert           X.509 certificate, or NULL if not found
  */
 struct x509_certificate *
-x509_find_subject ( struct x509_chain *certs,
+x509_find_subject ( struct x509_chain *store,
                    const struct asn1_cursor *subject ) {
        struct x509_link *link;
        struct x509_certificate *cert;
 
+       /* Use default certificate store if none specified */
+       if ( ! store )
+               store = &certstore;
+
        /* Scan through certificate list */
-       list_for_each_entry ( link, &certs->links, list ) {
+       list_for_each_entry ( link, &store->links, list ) {
 
                /* Check subject */
                cert = link->cert;
                if ( asn1_compare ( subject, &cert->subject.raw ) == 0 )
-                       return x509_found ( certs, cert );
+                       return x509_found ( store, cert );
        }
 
        return NULL;
@@ -1780,26 +1791,30 @@ x509_find_subject ( struct x509_chain *certs,
 /**
  * Identify X.509 certificate by issuer and serial number
  *
- * @v certs            X.509 certificate list
+ * @v store            Certificate store, or NULL to use default
  * @v issuer           Issuer
  * @v serial           Serial number
  * @ret cert           X.509 certificate, or NULL if not found
  */
 struct x509_certificate *
-x509_find_issuer_serial ( struct x509_chain *certs,
+x509_find_issuer_serial ( struct x509_chain *store,
                          const struct asn1_cursor *issuer,
                          const struct asn1_cursor *serial ) {
        struct x509_link *link;
        struct x509_certificate *cert;
 
+       /* Use default certificate store if none specified */
+       if ( ! store )
+               store = &certstore;
+
        /* Scan through certificate list */
-       list_for_each_entry ( link, &certs->links, list ) {
+       list_for_each_entry ( link, &store->links, list ) {
 
                /* Check issuer and serial number */
                cert = link->cert;
                if ( ( asn1_compare ( issuer, &cert->issuer.raw ) == 0 ) &&
                     ( asn1_compare ( serial, &cert->serial.raw ) == 0 ) )
-                       return x509_found ( certs, cert );
+                       return x509_found ( store, cert );
        }
 
        return NULL;
@@ -1808,17 +1823,21 @@ x509_find_issuer_serial ( struct x509_chain *certs,
 /**
  * Identify X.509 certificate by corresponding public key
  *
- * @v certs            X.509 certificate list
+ * @v store            Certificate store, or NULL to use default
  * @v key              Private key
  * @ret cert           X.509 certificate, or NULL if not found
  */
-struct x509_certificate * x509_find_key ( struct x509_chain *certs,
+struct x509_certificate * x509_find_key ( struct x509_chain *store,
                                          struct private_key *key ) {
        struct x509_link *link;
        struct x509_certificate *cert;
 
+       /* Use default certificate store if none specified */
+       if ( ! store )
+               store = &certstore;
+
        /* Scan through certificate list */
-       list_for_each_entry ( link, &certs->links, list ) {
+       list_for_each_entry ( link, &store->links, list ) {
 
                /* Check public key */
                cert = link->cert;
@@ -1826,7 +1845,7 @@ struct x509_certificate * x509_find_key ( struct x509_chain *certs,
                                    key->builder.data, key->builder.len,
                                    cert->subject.public_key.raw.data,
                                    cert->subject.public_key.raw.len ) == 0 )
-                       return x509_found ( certs, cert );
+                       return x509_found ( store, cert );
        }
 
        return NULL;
@@ -1836,13 +1855,13 @@ struct x509_certificate * x509_find_key ( struct x509_chain *certs,
  * Append X.509 certificates to X.509 certificate chain
  *
  * @v chain            X.509 certificate chain
- * @v certs            X.509 certificate list
+ * @v store            Certificate store, or NULL to use default
  * @ret rc             Return status code
  *
  * Certificates will be automatically appended to the chain based upon
  * the subject and issuer names.
  */
-int x509_auto_append ( struct x509_chain *chain, struct x509_chain *certs ) {
+int x509_auto_append ( struct x509_chain *chain, struct x509_chain *store ) {
        struct x509_certificate *cert;
        struct x509_certificate *previous;
        int rc;
@@ -1859,7 +1878,7 @@ int x509_auto_append ( struct x509_chain *chain, struct x509_chain *certs ) {
 
                /* Find issuing certificate */
                previous = cert;
-               cert = x509_find_subject ( certs, &cert->issuer.raw );
+               cert = x509_find_subject ( store, &cert->issuer.raw );
                if ( ! cert )
                        break;
                if ( cert == previous )
@@ -1888,10 +1907,6 @@ int x509_validate_chain ( struct x509_chain *chain, time_t time,
        struct x509_link *link;
        int rc;
 
-       /* Use default certificate store if none specified */
-       if ( ! store )
-               store = &certstore;
-
        /* Append any applicable certificates from the certificate store */
        if ( ( rc = x509_auto_append ( chain, store ) ) != 0 )
                return rc;
index 612743a77584fe54d92c3b8e21c4e8020c1713dc..e71cee8a3b2ff413c48ceda2646e590926249b7a 100644 (file)
@@ -204,10 +204,10 @@ struct x509_chain {
        struct list_head links;
        /** Mark certificate as found
         *
-        * @v certs             X.509 certificate list
+        * @v store             Certificate store
         * @v cert              X.509 certificate
         */
-       void ( * found ) ( struct x509_chain *certs,
+       void ( * found ) ( struct x509_chain *store,
                           struct x509_certificate *cert );
 };
 
@@ -432,19 +432,19 @@ extern int x509_append ( struct x509_chain *chain,
 extern int x509_append_raw ( struct x509_chain *chain, const void *data,
                             size_t len );
 extern void x509_truncate ( struct x509_chain *chain, struct x509_link *link );
-extern struct x509_certificate * x509_find ( struct x509_chain *certs,
+extern struct x509_certificate * x509_find ( struct x509_chain *store,
                                             const struct asn1_cursor *raw );
 extern struct x509_certificate *
-x509_find_subject ( struct x509_chain *certs,
+x509_find_subject ( struct x509_chain *store,
                    const struct asn1_cursor *subject );
 extern struct x509_certificate *
-x509_find_issuer_serial ( struct x509_chain *certs,
+x509_find_issuer_serial ( struct x509_chain *store,
                          const struct asn1_cursor *issuer,
                          const struct asn1_cursor *serial );
-extern struct x509_certificate * x509_find_key ( struct x509_chain *certs,
+extern struct x509_certificate * x509_find_key ( struct x509_chain *store,
                                                 struct private_key *key );
 extern int x509_auto_append ( struct x509_chain *chain,
-                             struct x509_chain *certs );
+                             struct x509_chain *store );
 extern int x509_validate_chain ( struct x509_chain *chain, time_t time,
                                 struct x509_chain *store,
                                 struct x509_root *root );
index 98414e2b19a97f030bb5279eda0888ade9069320..c0805710354019f4ba8f7a6bace95190f96bdb0e 100644 (file)
@@ -2467,7 +2467,7 @@ static int tls_new_certificate_request ( struct tls_connection *tls,
        tls->certs = NULL;
 
        /* Determine client certificate to be sent */
-       cert = x509_find_key ( &certstore, tls->key );
+       cert = x509_find_key ( NULL, tls->key );
        if ( ! cert ) {
                DBGC ( tls, "TLS %p could not find certificate corresponding "
                       "to private key\n", tls );