summaryrefslogtreecommitdiffstats
path: root/src/VBox/Devices/PC/ipxe/src/include/ipxe/x509.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/VBox/Devices/PC/ipxe/src/include/ipxe/x509.h435
1 files changed, 435 insertions, 0 deletions
diff --git a/src/VBox/Devices/PC/ipxe/src/include/ipxe/x509.h b/src/VBox/Devices/PC/ipxe/src/include/ipxe/x509.h
new file mode 100644
index 00000000..c703c8f1
--- /dev/null
+++ b/src/VBox/Devices/PC/ipxe/src/include/ipxe/x509.h
@@ -0,0 +1,435 @@
+#ifndef _IPXE_X509_H
+#define _IPXE_X509_H
+
+/** @file
+ *
+ * X.509 certificates
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <stdint.h>
+#include <stddef.h>
+#include <time.h>
+#include <ipxe/asn1.h>
+#include <ipxe/refcnt.h>
+#include <ipxe/list.h>
+
+struct image;
+
+/** An X.509 serial number */
+struct x509_serial {
+ /** Raw serial number */
+ struct asn1_cursor raw;
+};
+
+/** An X.509 issuer */
+struct x509_issuer {
+ /** Raw issuer */
+ struct asn1_cursor raw;
+};
+
+/** An X.509 time */
+struct x509_time {
+ /** Seconds since the Epoch */
+ time_t time;
+};
+
+/** An X.509 certificate validity period */
+struct x509_validity {
+ /** Not valid before */
+ struct x509_time not_before;
+ /** Not valid after */
+ struct x509_time not_after;
+};
+
+/** An X.509 certificate public key */
+struct x509_public_key {
+ /** Raw public key information */
+ struct asn1_cursor raw;
+ /** Public key algorithm */
+ struct asn1_algorithm *algorithm;
+ /** Raw public key bit string */
+ struct asn1_bit_string raw_bits;
+};
+
+/** An X.509 certificate subject */
+struct x509_subject {
+ /** Raw subject */
+ struct asn1_cursor raw;
+ /** Common name */
+ struct asn1_cursor common_name;
+ /** Public key information */
+ struct x509_public_key public_key;
+};
+
+/** An X.509 certificate signature */
+struct x509_signature {
+ /** Signature algorithm */
+ struct asn1_algorithm *algorithm;
+ /** Signature value */
+ struct asn1_bit_string value;
+};
+
+/** An X.509 certificate basic constraints set */
+struct x509_basic_constraints {
+ /** Subject is a CA */
+ int ca;
+ /** Path length */
+ 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 */
+ int present;
+ /** Usage bits */
+ unsigned int bits;
+};
+
+/** X.509 certificate key usage bits */
+enum x509_key_usage_bits {
+ X509_DIGITAL_SIGNATURE = 0x0080,
+ X509_NON_REPUDIATION = 0x0040,
+ X509_KEY_ENCIPHERMENT = 0x0020,
+ X509_DATA_ENCIPHERMENT = 0x0010,
+ X509_KEY_AGREEMENT = 0x0008,
+ X509_KEY_CERT_SIGN = 0x0004,
+ X509_CRL_SIGN = 0x0002,
+ X509_ENCIPHER_ONLY = 0x0001,
+ X509_DECIPHER_ONLY = 0x8000,
+};
+
+/** An X.509 certificate extended key usage */
+struct x509_extended_key_usage {
+ /** Usage bits */
+ unsigned int bits;
+};
+
+/** X.509 certificate extended key usage bits
+ *
+ * Extended key usages are identified by OID; these bits are purely an
+ * internal definition.
+ */
+enum x509_extended_key_usage_bits {
+ X509_CODE_SIGNING = 0x0001,
+ X509_OCSP_SIGNING = 0x0002,
+};
+
+/** X.509 certificate OCSP responder */
+struct x509_ocsp_responder {
+ /** URI */
+ struct asn1_cursor uri;
+ /** OCSP status is good */
+ int good;
+};
+
+/** X.509 certificate authority information access */
+struct x509_authority_info_access {
+ /** OCSP responder */
+ struct x509_ocsp_responder ocsp;
+};
+
+/** X.509 certificate subject alternative name */
+struct x509_subject_alt_name {
+ /** Names */
+ struct asn1_cursor names;
+};
+
+/** X.509 certificate general name types */
+enum x509_general_name_types {
+ X509_GENERAL_NAME_DNS = ASN1_IMPLICIT_TAG ( 2 ),
+ X509_GENERAL_NAME_URI = ASN1_IMPLICIT_TAG ( 6 ),
+ X509_GENERAL_NAME_IP = ASN1_IMPLICIT_TAG ( 7 ),
+};
+
+/** An X.509 certificate extensions set */
+struct x509_extensions {
+ /** Basic constraints */
+ struct x509_basic_constraints basic;
+ /** Key usage */
+ struct x509_key_usage usage;
+ /** Extended key usage */
+ struct x509_extended_key_usage ext_usage;
+ /** Authority information access */
+ struct x509_authority_info_access auth_info;
+ /** Subject alternative name */
+ struct x509_subject_alt_name alt_name;
+};
+
+/** 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;
+
+ /** Link in certificate store */
+ struct x509_link store;
+
+ /** Flags */
+ unsigned int flags;
+ /** Root against which certificate has been validated (if any) */
+ struct x509_root *root;
+ /** Maximum number of subsequent certificates in chain */
+ unsigned int path_remaining;
+
+ /** Raw certificate */
+ struct asn1_cursor raw;
+ /** Version */
+ unsigned int version;
+ /** Serial number */
+ struct x509_serial serial;
+ /** Raw tbsCertificate */
+ struct asn1_cursor tbs;
+ /** Signature algorithm */
+ struct asn1_algorithm *signature_algorithm;
+ /** Issuer */
+ struct x509_issuer issuer;
+ /** Validity */
+ struct x509_validity validity;
+ /** Subject */
+ struct x509_subject subject;
+ /** Signature */
+ struct x509_signature signature;
+ /** Extensions */
+ struct x509_extensions extensions;
+};
+
+/** X.509 certificate flags */
+enum x509_flags {
+ /** Certificate was added at build time */
+ X509_FL_PERMANENT = 0x0001,
+ /** Certificate was added explicitly at run time */
+ X509_FL_EXPLICIT = 0x0002,
+};
+
+/**
+ * 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 );
+}
+
+/**
+ * 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 );
+}
+
+/**
+ * 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 */
+ const char *name;
+ /** Object identifier */
+ struct asn1_cursor oid;
+ /** Parse extension
+ *
+ * @v cert X.509 certificate
+ * @v raw ASN.1 cursor
+ * @ret rc Return status code
+ */
+ int ( * parse ) ( struct x509_certificate *cert,
+ const struct asn1_cursor *raw );
+};
+
+/** An X.509 key purpose */
+struct x509_key_purpose {
+ /** Name */
+ const char *name;
+ /** Object identifier */
+ struct asn1_cursor oid;
+ /** Extended key usage bits */
+ unsigned int bits;
+};
+
+/** An X.509 access method */
+struct x509_access_method {
+ /** Name */
+ const char *name;
+ /** Object identifier */
+ struct asn1_cursor oid;
+ /** Parse access method
+ *
+ * @v cert X.509 certificate
+ * @v raw ASN.1 cursor
+ * @ret rc Return status code
+ */
+ int ( * parse ) ( struct x509_certificate *cert,
+ const struct asn1_cursor *raw );
+};
+
+/** An X.509 root certificate list */
+struct x509_root {
+ /** Reference count */
+ struct refcnt refcnt;
+ /** Fingerprint digest algorithm */
+ struct digest_algorithm *digest;
+ /** Number of certificates */
+ unsigned int count;
+ /** Certificate fingerprints */
+ const void *fingerprints;
+};
+
+/**
+ * Get reference to X.509 root certificate list
+ *
+ * @v root X.509 root certificate list
+ * @ret root X.509 root certificate list
+ */
+static inline __attribute__ (( always_inline )) struct x509_root *
+x509_root_get ( struct x509_root *root ) {
+ ref_get ( &root->refcnt );
+ return root;
+}
+
+/**
+ * Drop reference to X.509 root certificate list
+ *
+ * @v root X.509 root certificate list
+ */
+static inline __attribute__ (( always_inline )) void
+x509_root_put ( struct x509_root *root ) {
+ ref_put ( &root->refcnt );
+}
+
+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_is_valid ( struct x509_certificate *cert,
+ struct x509_root *root );
+extern int x509_validate ( struct x509_certificate *cert,
+ struct x509_certificate *issuer,
+ time_t time, struct x509_root *root );
+extern int x509_check_name ( struct x509_certificate *cert, const char *name );
+
+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_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 );
+extern int image_x509 ( struct image *image, size_t offset,
+ struct x509_certificate **cert );
+
+/* 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_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 ) {
+ x509_root_put ( cert->root );
+ cert->root = NULL;
+ 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 */