return NULL;
}
-/**
- * Identify CMS signature certificate by subject
- *
- * @v sig CMS signature
- * @v subject Subject
- * @ret cert X.509 certificate, or NULL if not found
- */
-static struct x509_certificate *
-cms_find_subject ( struct cms_signature *sig,
- const struct asn1_cursor *subject ) {
- struct x509_link *link;
- struct x509_certificate *cert;
-
- /* Scan through certificate list */
- list_for_each_entry ( link, &sig->certificates->links, list ) {
-
- /* Check subject */
- cert = link->cert;
- if ( asn1_compare ( subject, &cert->subject.raw ) == 0 )
- return cert;
- }
-
- return NULL;
-}
-
/**
* Parse CMS signature signer identifier
*
struct asn1_cursor serial;
struct asn1_cursor issuer;
struct x509_certificate *cert;
- struct x509_certificate *previous;
int rc;
/* Enter issuerAndSerialNumber */
return -ENOENT;
}
- /* Create certificate chain */
- do {
- /* Add certificate to chain */
- if ( ( rc = x509_append ( info->chain, cert ) ) != 0 ) {
- DBGC ( sig, "CMS %p/%p could not append certificate: "
- "%s\n", sig, info, strerror ( rc ) );
- return rc;
- }
- DBGC ( sig, "CMS %p/%p added certificate %s\n",
- sig, info, cert->subject.name );
-
- /* Locate next certificate in chain, if any */
- previous = cert;
- cert = cms_find_subject ( sig, &cert->issuer.raw );
+ /* Append certificate to chain */
+ if ( ( rc = x509_append ( info->chain, cert ) ) != 0 ) {
+ DBGC ( sig, "CMS %p/%p could not append certificate: %s\n",
+ sig, info, strerror ( rc ) );
+ return rc;
+ }
- } while ( ( cert != NULL ) && ( cert != previous ) );
+ /* Append remaining certificates to chain */
+ if ( ( rc = x509_auto_append ( info->chain,
+ sig->certificates ) ) != 0 ) {
+ DBGC ( sig, "CMS %p/%p could not append certificates: %s\n",
+ sig, info, strerror ( rc ) );
+ return rc;
+ }
return 0;
}
return rc;
}
+/**
+ * Identify X.509 certificate by subject
+ *
+ * @v certs X.509 certificate list
+ * @v subject Subject
+ * @ret cert X.509 certificate, or NULL if not found
+ */
+static struct x509_certificate *
+x509_find_subject ( struct x509_chain *certs,
+ const struct asn1_cursor *subject ) {
+ struct x509_link *link;
+ struct x509_certificate *cert;
+
+ /* Scan through certificate list */
+ list_for_each_entry ( link, &certs->links, list ) {
+
+ /* Check subject */
+ cert = link->cert;
+ if ( asn1_compare ( subject, &cert->subject.raw ) == 0 )
+ return cert;
+ }
+
+ return NULL;
+}
+
+/**
+ * Append X.509 certificates to X.509 certificate chain
+ *
+ * @v chain X.509 certificate chain
+ * @v certs X.509 certificate list
+ * @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 ) {
+ struct x509_certificate *cert;
+ struct x509_certificate *previous;
+ int rc;
+
+ /* Get current certificate */
+ cert = x509_last ( chain );
+ if ( ! cert ) {
+ DBGC ( chain, "X509 chain %p has no certificates\n", chain );
+ return -EINVAL;
+ }
+
+ /* Append certificates, in order */
+ while ( 1 ) {
+
+ /* Find issuing certificate */
+ previous = cert;
+ cert = x509_find_subject ( certs, &cert->issuer.raw );
+ if ( ! cert )
+ break;
+ if ( cert == previous )
+ break;
+
+ /* Append certificate to chain */
+ if ( ( rc = x509_append ( chain, cert ) ) != 0 )
+ return rc;
+ }
+
+ return 0;
+}
+
/**
* Validate X.509 certificate chain
*