From bc8ca6b8cea325e6507839e576d0d7eaa44e2af1 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Fri, 28 Mar 2014 15:45:10 +0000 Subject: [crypto] Generalise X.509 cache to a full certificate store Expand the concept of the X.509 cache to provide the functionality of a certificate store. Certificates in the store will be automatically used to complete certificate chains where applicable. The certificate store may be prepopulated at build time using the CERT=... build command line option. For example: make bin/ipxe.usb CERT=mycert1.crt,mycert2.crt Certificates within the certificate store are not implicitly trusted; the trust list is specified using TRUST=... as before. For example: make bin/ipxe.usb CERT=root.crt TRUST=root.crt This can be used to embed the full trusted root certificate within the iPXE binary, which is potentially useful in an HTTPS-only environment in which there is no HTTP server from which to automatically download cross-signed certificates or other certificate chain fragments. This usage of CERT= extends the existing use of CERT= to specify the client certificate. The client certificate is now identified automatically by checking for a match against the private key. For example: make bin/ipxe.usb CERT=root.crt,client.crt TRUST=root.crt KEY=client.key Signed-off-by: Michael Brown --- src/include/ipxe/certstore.h | 21 +++++++++++++++++++++ src/include/ipxe/clientcert.h | 43 ------------------------------------------- src/include/ipxe/cms.h | 3 ++- src/include/ipxe/privkey.h | 16 ++++++++++++++++ src/include/ipxe/tls.h | 4 ++-- src/include/ipxe/x509.h | 41 ++++++++++++++++++++++------------------- 6 files changed, 63 insertions(+), 65 deletions(-) create mode 100644 src/include/ipxe/certstore.h delete mode 100644 src/include/ipxe/clientcert.h create mode 100644 src/include/ipxe/privkey.h (limited to 'src/include/ipxe') diff --git a/src/include/ipxe/certstore.h b/src/include/ipxe/certstore.h new file mode 100644 index 000000000..7456db621 --- /dev/null +++ b/src/include/ipxe/certstore.h @@ -0,0 +1,21 @@ +#ifndef _IPXE_CERTSTORE_H +#define _IPXE_CERTSTORE_H + +/** @file + * + * Certificate store + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include +#include + +extern struct x509_chain certstore; + +extern struct x509_certificate * certstore_find ( struct asn1_cursor *raw ); +extern struct x509_certificate * certstore_find_key ( struct asn1_cursor *key ); +extern void certstore_add ( struct x509_certificate *cert ); + +#endif /* _IPXE_CERTSTORE_H */ diff --git a/src/include/ipxe/clientcert.h b/src/include/ipxe/clientcert.h deleted file mode 100644 index 08f62eb73..000000000 --- a/src/include/ipxe/clientcert.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef _IPXE_CLIENTCERT_H -#define _IPXE_CLIENTCERT_H - -/** @file - * - * Client certificate store - * - */ - -FILE_LICENCE ( GPL2_OR_LATER ); - -#include - -/** A client certificate */ -struct client_certificate { - /** Data */ - const void *data; - /** Length */ - size_t len; -}; - -/** A client private key */ -struct client_private_key { - /** Data */ - const void *data; - /** Length */ - size_t len; -}; - -extern struct client_certificate client_certificate; -extern struct client_private_key client_private_key; - -/** - * Check for presence of a client certificate - * - * @ret have_cert We have a client certificate and private key - */ -static inline int have_client_certificate ( void ) { - return ( ( client_certificate.len > 0 ) && - ( client_private_key.len > 0 ) ); -} - -#endif /* _IPXE_CLIENTCERT_H */ diff --git a/src/include/ipxe/cms.h b/src/include/ipxe/cms.h index eadeca4b8..e026ebd2f 100644 --- a/src/include/ipxe/cms.h +++ b/src/include/ipxe/cms.h @@ -70,6 +70,7 @@ cms_put ( struct cms_signature *sig ) { extern int cms_signature ( const void *data, size_t len, struct cms_signature **sig ); extern int cms_verify ( struct cms_signature *sig, userptr_t data, size_t len, - const char *name, time_t time, struct x509_root *root ); + const char *name, time_t time, struct x509_chain *store, + struct x509_root *root ); #endif /* _IPXE_CMS_H */ diff --git a/src/include/ipxe/privkey.h b/src/include/ipxe/privkey.h new file mode 100644 index 000000000..39049ac9f --- /dev/null +++ b/src/include/ipxe/privkey.h @@ -0,0 +1,16 @@ +#ifndef _IPXE_PRIVKEY_H +#define _IPXE_PRIVKEY_H + +/** @file + * + * Private key + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include + +extern struct asn1_cursor private_key; + +#endif /* _IPXE_PRIVKEY_H */ diff --git a/src/include/ipxe/tls.h b/src/include/ipxe/tls.h index f8a754096..586da26ec 100644 --- a/src/include/ipxe/tls.h +++ b/src/include/ipxe/tls.h @@ -241,8 +241,8 @@ struct tls_session { struct digest_algorithm *handshake_digest; /** Digest algorithm context used for handshake verification */ uint8_t *handshake_ctx; - /** Public-key algorithm used for Certificate Verify (if sent) */ - struct pubkey_algorithm *verify_pubkey; + /** Client certificate (if used) */ + struct x509_certificate *cert; /** Server certificate chain */ struct x509_chain *chain; diff --git a/src/include/ipxe/x509.h b/src/include/ipxe/x509.h index 483153bbe..52302aeab 100644 --- a/src/include/ipxe/x509.h +++ b/src/include/ipxe/x509.h @@ -156,12 +156,29 @@ struct x509_extensions { struct x509_authority_info_access auth_info; }; +/** A link in an X.509 certificate chain */ +struct x509_link { + /** List of links */ + struct list_head list; + /** Certificate */ + struct x509_certificate *cert; +}; + +/** An X.509 certificate chain */ +struct x509_chain { + /** Reference count */ + struct refcnt refcnt; + /** List of links */ + struct list_head links; +}; + /** An X.509 certificate */ struct x509_certificate { /** Reference count */ struct refcnt refcnt; - /** List of certificates in cache */ - struct list_head list; + + /** Link in certificate store */ + struct x509_link store; /** Certificate has been validated */ int valid; @@ -212,22 +229,6 @@ x509_put ( struct x509_certificate *cert ) { ref_put ( &cert->refcnt ); } -/** A link in an X.509 certificate chain */ -struct x509_link { - /** List of links */ - struct list_head list; - /** Certificate */ - struct x509_certificate *cert; -}; - -/** An X.509 certificate chain */ -struct x509_chain { - /** Reference count */ - struct refcnt refcnt; - /** List of links */ - struct list_head links; -}; - /** * Get reference to X.509 certificate chain * @@ -331,7 +332,8 @@ struct x509_root { }; extern const char * x509_name ( struct x509_certificate *cert ); - +extern int x509_parse ( struct x509_certificate *cert, + const struct asn1_cursor *raw ); extern int x509_certificate ( const void *data, size_t len, struct x509_certificate **cert ); extern int x509_validate ( struct x509_certificate *cert, @@ -347,6 +349,7 @@ extern int x509_append_raw ( struct x509_chain *chain, const void *data, extern int x509_auto_append ( struct x509_chain *chain, struct x509_chain *certs ); extern int x509_validate_chain ( struct x509_chain *chain, time_t time, + struct x509_chain *store, struct x509_root *root ); /* Functions exposed only for unit testing */ -- cgit v1.2.3-55-g7522