aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/crypto/cms.c27
-rw-r--r--src/crypto/x509.c32
-rw-r--r--src/include/ipxe/x509.h16
-rw-r--r--src/net/tls.c23
4 files changed, 59 insertions, 39 deletions
diff --git a/src/crypto/cms.c b/src/crypto/cms.c
index 660be69e9..9198d03e4 100644
--- a/src/crypto/cms.c
+++ b/src/crypto/cms.c
@@ -128,38 +128,23 @@ static int cms_parse_certificates ( struct cms_signature *sig,
/* Add each certificate */
while ( cursor.len ) {
- /* Parse certificate */
- if ( ( rc = x509_certificate ( cursor.data, cursor.len,
- &cert ) ) != 0 ) {
- DBGC ( sig, "CMS %p could not parse certificate: %s\n",
+ /* Add certificate to chain */
+ if ( ( rc = x509_append_raw ( sig->certificates, cursor.data,
+ cursor.len ) ) != 0 ) {
+ DBGC ( sig, "CMS %p could not append certificate: %s\n",
sig, strerror ( rc) );
DBGC_HDA ( sig, 0, cursor.data, cursor.len );
- goto err_parse;
+ return rc;
}
+ cert = x509_last ( sig->certificates );
DBGC ( sig, "CMS %p found certificate %s\n",
sig, cert->subject.name );
- /* Add certificate to list */
- if ( ( rc = x509_append ( sig->certificates, cert ) ) != 0 ) {
- DBGC ( sig, "CMS %p could not append certificate: %s\n",
- sig, strerror ( rc ) );
- goto err_append;
- }
-
- /* Drop reference to certificate */
- x509_put ( cert );
- cert = NULL;
-
/* Move to next certificate */
asn1_skip_any ( &cursor );
}
return 0;
-
- err_append:
- x509_put ( cert );
- err_parse:
- return rc;
}
/**
diff --git a/src/crypto/x509.c b/src/crypto/x509.c
index 356b60a36..c83cd2777 100644
--- a/src/crypto/x509.c
+++ b/src/crypto/x509.c
@@ -1647,6 +1647,38 @@ int x509_append ( struct x509_chain *chain, struct x509_certificate *cert ) {
}
/**
+ * Append X.509 certificate to X.509 certificate chain
+ *
+ * @v chain X.509 certificate chain
+ * @v data Raw certificate data
+ * @v len Length of raw data
+ * @ret rc Return status code
+ */
+int x509_append_raw ( struct x509_chain *chain, const void *data,
+ size_t len ) {
+ struct x509_certificate *cert;
+ int rc;
+
+ /* Parse certificate */
+ if ( ( rc = x509_certificate ( data, len, &cert ) ) != 0 )
+ goto err_parse;
+
+ /* Append certificate to chain */
+ if ( ( rc = x509_append ( chain, cert ) ) != 0 )
+ goto err_append;
+
+ /* Drop reference to certificate */
+ x509_put ( cert );
+
+ return 0;
+
+ err_append:
+ x509_put ( cert );
+ err_parse:
+ return rc;
+}
+
+/**
* Validate X.509 certificate chain
*
* @v chain X.509 certificate chain
diff --git a/src/include/ipxe/x509.h b/src/include/ipxe/x509.h
index b9db20479..78b180c99 100644
--- a/src/include/ipxe/x509.h
+++ b/src/include/ipxe/x509.h
@@ -261,6 +261,20 @@ x509_first ( struct x509_chain *chain ) {
return ( link ? link->cert : NULL );
}
+/**
+ * Get last certificate in X.509 certificate chain
+ *
+ * @v chain X.509 certificate chain
+ * @ret cert X.509 certificate, or NULL
+ */
+static inline __attribute__ (( always_inline )) struct x509_certificate *
+x509_last ( struct x509_chain *chain ) {
+ struct x509_link *link;
+
+ link = list_last_entry ( &chain->links, struct x509_link, list );
+ return ( link ? link->cert : NULL );
+}
+
/** An X.509 extension */
struct x509_extension {
/** Name */
@@ -319,6 +333,8 @@ extern int x509_certificate ( const void *data, size_t len,
extern struct x509_chain * x509_alloc_chain ( void );
extern int x509_append ( struct x509_chain *chain,
struct x509_certificate *cert );
+extern int x509_append_raw ( struct x509_chain *chain, const void *data,
+ size_t len );
extern int x509_validate_chain ( struct x509_chain *chain, time_t time,
struct x509_root *root );
diff --git a/src/net/tls.c b/src/net/tls.c
index 3a8a0e05b..6cb63be5b 100644
--- a/src/net/tls.c
+++ b/src/net/tls.c
@@ -1312,37 +1312,24 @@ static int tls_parse_chain ( struct tls_session *tls,
goto err_overlength;
}
- /* Parse certificate */
- if ( ( rc = x509_certificate ( certificate->data,
- certificate_len,
- &cert ) ) != 0 ) {
- DBGC ( tls, "TLS %p could not parse certificate: %s\n",
+ /* Add certificate to chain */
+ if ( ( rc = x509_append_raw ( tls->chain, certificate->data,
+ certificate_len ) ) != 0 ) {
+ DBGC ( tls, "TLS %p could not append certificate: %s\n",
tls, strerror ( rc ) );
DBGC_HDA ( tls, 0, data, ( end - data ) );
goto err_parse;
}
+ cert = x509_last ( tls->chain );
DBGC ( tls, "TLS %p found certificate %s\n",
tls, cert->subject.name );
- /* Append certificate to chain */
- if ( ( rc = x509_append ( tls->chain, cert ) ) != 0 ) {
- DBGC ( tls, "TLS %p could not append certificate: %s\n",
- tls, strerror ( rc ) );
- goto err_append;
- }
-
- /* Drop reference to certificate */
- x509_put ( cert );
- cert = NULL;
-
/* Move to next certificate in list */
data = next;
}
return 0;
- err_append:
- x509_put ( cert );
err_parse:
err_overlength:
x509_chain_put ( tls->chain );