summaryrefslogtreecommitdiffstats
path: root/src/include/ipxe
diff options
context:
space:
mode:
Diffstat (limited to 'src/include/ipxe')
-rw-r--r--src/include/ipxe/cms.h53
-rw-r--r--src/include/ipxe/tls.h3
-rw-r--r--src/include/ipxe/x509.h156
3 files changed, 174 insertions, 38 deletions
diff --git a/src/include/ipxe/cms.h b/src/include/ipxe/cms.h
index f355bf1cb..eadeca4b8 100644
--- a/src/include/ipxe/cms.h
+++ b/src/include/ipxe/cms.h
@@ -13,37 +13,62 @@ FILE_LICENCE ( GPL2_OR_LATER );
#include <ipxe/asn1.h>
#include <ipxe/crypto.h>
#include <ipxe/x509.h>
+#include <ipxe/refcnt.h>
#include <ipxe/uaccess.h>
/** CMS signer information */
struct cms_signer_info {
- /** Issuer name */
- struct asn1_cursor issuer;
- /** Serial number */
- struct asn1_cursor serial;
+ /** List of signer information blocks */
+ struct list_head list;
+
+ /** Certificate chain */
+ struct x509_chain *chain;
+
/** Digest algorithm */
struct digest_algorithm *digest;
/** Public-key algorithm */
struct pubkey_algorithm *pubkey;
+
/** Signature */
- const void *signature;
+ void *signature;
/** Length of signature */
size_t signature_len;
};
/** A CMS signature */
struct cms_signature {
- /** Raw certificate list */
- struct asn1_cursor certificates;
- /** Signer information
- *
- * We currently use only the first signer information block.
- */
- struct cms_signer_info info;
+ /** Reference count */
+ struct refcnt refcnt;
+ /** List of all certificates */
+ struct x509_chain *certificates;
+ /** List of signer information blocks */
+ struct list_head info;
};
-extern int cms_parse ( struct cms_signature *sig, const void *data,
- size_t len );
+/**
+ * Get reference to CMS signature
+ *
+ * @v sig CMS signature
+ * @ret sig CMS signature
+ */
+static inline __attribute__ (( always_inline )) struct cms_signature *
+cms_get ( struct cms_signature *sig ) {
+ ref_get ( &sig->refcnt );
+ return sig;
+}
+
+/**
+ * Drop reference to CMS signature
+ *
+ * @v sig CMS signature
+ */
+static inline __attribute__ (( always_inline )) void
+cms_put ( struct cms_signature *sig ) {
+ ref_put ( &sig->refcnt );
+}
+
+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 );
diff --git a/src/include/ipxe/tls.h b/src/include/ipxe/tls.h
index 772233369..07f5d3eb2 100644
--- a/src/include/ipxe/tls.h
+++ b/src/include/ipxe/tls.h
@@ -235,6 +235,9 @@ struct tls_session {
/** Public-key algorithm used for Certificate Verify (if sent) */
struct pubkey_algorithm *verify_pubkey;
+ /** Server certificate chain */
+ struct x509_chain *chain;
+
/** TX sequence number */
uint64_t tx_seq;
/** TX pending transmissions */
diff --git a/src/include/ipxe/x509.h b/src/include/ipxe/x509.h
index 271ed2e44..b9db20479 100644
--- a/src/include/ipxe/x509.h
+++ b/src/include/ipxe/x509.h
@@ -13,6 +13,8 @@ FILE_LICENCE ( GPL2_OR_LATER );
#include <stddef.h>
#include <time.h>
#include <ipxe/asn1.h>
+#include <ipxe/refcnt.h>
+#include <ipxe/list.h>
/** An X.509 bit string */
struct x509_bit_string {
@@ -50,14 +52,6 @@ struct x509_validity {
struct x509_time not_after;
};
-/** An X.509 string */
-struct x509_string {
- /** String (not NUL-terminated) */
- const void *data;
- /** Length of name */
- size_t len;
-};
-
/** An X.509 certificate public key */
struct x509_public_key {
/** Raw public key */
@@ -71,7 +65,7 @@ struct x509_subject {
/** Raw subject */
struct asn1_cursor raw;
/** Common name */
- struct x509_string name;
+ char *name;
/** Public key information */
struct x509_public_key public_key;
};
@@ -92,6 +86,13 @@ struct x509_basic_constraints {
unsigned int path_len;
};
+/** Unlimited path length
+ *
+ * We use -2U, since this quantity represents one *fewer* than the
+ * maximum number of remaining certificates in a chain.
+ */
+#define X509_PATH_LEN_UNLIMITED -2U
+
/** An X.509 certificate key usage */
struct x509_key_usage {
/** Key usage extension is present */
@@ -131,7 +132,7 @@ enum x509_extended_key_usage_bits {
/** X.509 certificate OCSP responder */
struct x509_ocsp_responder {
/** URI */
- struct x509_string uri;
+ char *uri;
};
/** X.509 certificate authority information access */
@@ -154,6 +155,16 @@ struct x509_extensions {
/** An X.509 certificate */
struct x509_certificate {
+ /** Reference count */
+ struct refcnt refcnt;
+ /** List of certificates in cache */
+ struct list_head list;
+
+ /** Certificate has been validated */
+ int valid;
+ /** Maximum number of subsequent certificates in chain */
+ unsigned int path_remaining;
+
/** Raw certificate */
struct asn1_cursor raw;
/** Version */
@@ -176,6 +187,80 @@ struct x509_certificate {
struct x509_extensions extensions;
};
+/**
+ * Get reference to X.509 certificate
+ *
+ * @v cert X.509 certificate
+ * @ret cert X.509 certificate
+ */
+static inline __attribute__ (( always_inline )) struct x509_certificate *
+x509_get ( struct x509_certificate *cert ) {
+ ref_get ( &cert->refcnt );
+ return cert;
+}
+
+/**
+ * Drop reference to X.509 certificate
+ *
+ * @v cert X.509 certificate
+ */
+static inline __attribute__ (( always_inline )) void
+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
+ *
+ * @v chain X.509 certificate chain
+ * @ret chain X.509 certificate chain
+ */
+static inline __attribute__ (( always_inline )) struct x509_chain *
+x509_chain_get ( struct x509_chain *chain ) {
+ ref_get ( &chain->refcnt );
+ return chain;
+}
+
+/**
+ * Drop reference to X.509 certificate chain
+ *
+ * @v chain X.509 certificate chain
+ */
+static inline __attribute__ (( always_inline )) void
+x509_chain_put ( struct x509_chain *chain ) {
+ ref_put ( &chain->refcnt );
+}
+
+/**
+ * Get first 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_first ( struct x509_chain *chain ) {
+ struct x509_link *link;
+
+ link = list_first_entry ( &chain->links, struct x509_link, list );
+ return ( link ? link->cert : NULL );
+}
+
/** An X.509 extension */
struct x509_extension {
/** Name */
@@ -228,22 +313,45 @@ struct x509_root {
const void *fingerprints;
};
-extern int x509_parse ( struct x509_certificate *cert,
- const void *data, size_t len );
-extern int x509_validate_issuer ( struct x509_certificate *cert,
- struct x509_certificate *issuer );
+extern int x509_certificate ( const void *data, size_t len,
+ struct x509_certificate **cert );
+
+extern struct x509_chain * x509_alloc_chain ( void );
+extern int x509_append ( struct x509_chain *chain,
+ struct x509_certificate *cert );
+extern int x509_validate_chain ( struct x509_chain *chain, time_t time,
+ struct x509_root *root );
+
+/* Functions exposed only for unit testing */
+extern int x509_check_issuer ( struct x509_certificate *cert,
+ struct x509_certificate *issuer );
extern void x509_fingerprint ( struct x509_certificate *cert,
struct digest_algorithm *digest,
void *fingerprint );
-extern int x509_validate_root ( struct x509_certificate *cert,
- struct x509_root *root );
-extern int x509_validate_time ( struct x509_certificate *cert, time_t time );
-extern int x509_validate_chain ( int ( * parse_next )
- ( struct x509_certificate *cert,
- const struct x509_certificate *previous,
- void *context ),
- void *context, time_t time,
- struct x509_root *root,
- struct x509_certificate *first );
+extern int x509_check_root ( struct x509_certificate *cert,
+ struct x509_root *root );
+extern int x509_check_time ( struct x509_certificate *cert, time_t time );
+
+/**
+ * Invalidate X.509 certificate
+ *
+ * @v cert X.509 certificate
+ */
+static inline void x509_invalidate ( struct x509_certificate *cert ) {
+ cert->valid = 0;
+ cert->path_remaining = 0;
+}
+
+/**
+ * Invalidate X.509 certificate chain
+ *
+ * @v chain X.509 certificate chain
+ */
+static inline void x509_invalidate_chain ( struct x509_chain *chain ) {
+ struct x509_link *link;
+
+ list_for_each_entry ( link, &chain->links, list )
+ x509_invalidate ( link->cert );
+}
#endif /* _IPXE_X509_H */