123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413 |
- #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;
- /** 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 has been validated */
- X509_FL_VALIDATED = 0x0001,
- };
-
- /**
- * 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 store */
- struct x509_root {
- /** Fingerprint digest algorithm */
- struct digest_algorithm *digest;
- /** Number of certificates */
- unsigned int count;
- /** Certificate fingerprints */
- const void *fingerprints;
- };
-
- 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,
- 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 );
-
- /**
- * Check if X.509 certificate is valid
- *
- * @v cert X.509 certificate
- */
- static inline int x509_is_valid ( struct x509_certificate *cert ) {
- return ( cert->flags & X509_FL_VALIDATED );
- }
-
- /**
- * Invalidate X.509 certificate
- *
- * @v cert X.509 certificate
- */
- static inline void x509_invalidate ( struct x509_certificate *cert ) {
- cert->flags &= ~X509_FL_VALIDATED;
- 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 */
|