From 99c798d87a94838be62976cb1632e7d0a9550df3 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Tue, 8 May 2012 10:57:50 +0100 Subject: [PATCH] [crypto] Add x509_append_raw() Signed-off-by: Michael Brown --- src/crypto/cms.c | 27 ++++++--------------------- src/crypto/x509.c | 32 ++++++++++++++++++++++++++++++++ src/include/ipxe/x509.h | 16 ++++++++++++++++ src/net/tls.c | 23 +++++------------------ 4 files changed, 59 insertions(+), 39 deletions(-) diff --git a/src/crypto/cms.c b/src/crypto/cms.c index 660be69e..9198d03e 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 356b60a3..c83cd277 100644 --- a/src/crypto/x509.c +++ b/src/crypto/x509.c @@ -1646,6 +1646,38 @@ int x509_append ( struct x509_chain *chain, struct x509_certificate *cert ) { return 0; } +/** + * 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 * diff --git a/src/include/ipxe/x509.h b/src/include/ipxe/x509.h index b9db2047..78b180c9 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 3a8a0e05..6cb63be5 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 );