david/ipxe
david
/
ipxe
Archived
1
0
Fork 0
This repository has been archived on 2020-12-06. You can view files and clone it, but cannot push or open issues or pull requests.
ipxe/src/include/ipxe/x509.h

414 lines
9.8 KiB
C

#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 */