iPXE
x509.h
Go to the documentation of this file.
00001 #ifndef _IPXE_X509_H
00002 #define _IPXE_X509_H
00003 
00004 /** @file
00005  *
00006  * X.509 certificates
00007  *
00008  */
00009 
00010 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
00011 
00012 #include <stdint.h>
00013 #include <stddef.h>
00014 #include <time.h>
00015 #include <ipxe/asn1.h>
00016 #include <ipxe/refcnt.h>
00017 #include <ipxe/list.h>
00018 
00019 struct image;
00020 
00021 /** An X.509 serial number */
00022 struct x509_serial {
00023         /** Raw serial number */
00024         struct asn1_cursor raw;
00025 };
00026 
00027 /** An X.509 issuer */
00028 struct x509_issuer {
00029         /** Raw issuer */
00030         struct asn1_cursor raw;
00031 };
00032 
00033 /** An X.509 time */
00034 struct x509_time {
00035         /** Seconds since the Epoch */
00036         time_t time;
00037 };
00038 
00039 /** An X.509 certificate validity period */
00040 struct x509_validity {
00041         /** Not valid before */
00042         struct x509_time not_before;
00043         /** Not valid after */
00044         struct x509_time not_after;
00045 };
00046 
00047 /** An X.509 certificate public key */
00048 struct x509_public_key {
00049         /** Raw public key information */
00050         struct asn1_cursor raw;
00051         /** Public key algorithm */
00052         struct asn1_algorithm *algorithm;
00053         /** Raw public key bit string */
00054         struct asn1_bit_string raw_bits;
00055 };
00056 
00057 /** An X.509 certificate subject */
00058 struct x509_subject {
00059         /** Raw subject */
00060         struct asn1_cursor raw;
00061         /** Common name */
00062         struct asn1_cursor common_name;
00063         /** Public key information */
00064         struct x509_public_key public_key;
00065 };
00066 
00067 /** An X.509 certificate signature */
00068 struct x509_signature {
00069         /** Signature algorithm */
00070         struct asn1_algorithm *algorithm;
00071         /** Signature value */
00072         struct asn1_bit_string value;
00073 };
00074 
00075 /** An X.509 certificate basic constraints set */
00076 struct x509_basic_constraints {
00077         /** Subject is a CA */
00078         int ca;
00079         /** Path length */
00080         unsigned int path_len;
00081 };
00082 
00083 /** Unlimited path length
00084  *
00085  * We use -2U, since this quantity represents one *fewer* than the
00086  * maximum number of remaining certificates in a chain.
00087  */
00088 #define X509_PATH_LEN_UNLIMITED -2U
00089 
00090 /** An X.509 certificate key usage */
00091 struct x509_key_usage {
00092         /** Key usage extension is present */
00093         int present;
00094         /** Usage bits */
00095         unsigned int bits;
00096 };
00097 
00098 /** X.509 certificate key usage bits */
00099 enum x509_key_usage_bits {
00100         X509_DIGITAL_SIGNATURE = 0x0080,
00101         X509_NON_REPUDIATION = 0x0040,
00102         X509_KEY_ENCIPHERMENT = 0x0020,
00103         X509_DATA_ENCIPHERMENT = 0x0010,
00104         X509_KEY_AGREEMENT = 0x0008,
00105         X509_KEY_CERT_SIGN = 0x0004,
00106         X509_CRL_SIGN = 0x0002,
00107         X509_ENCIPHER_ONLY = 0x0001,
00108         X509_DECIPHER_ONLY = 0x8000,
00109 };
00110 
00111 /** An X.509 certificate extended key usage */
00112 struct x509_extended_key_usage {
00113         /** Usage bits */
00114         unsigned int bits;
00115 };
00116 
00117 /** X.509 certificate extended key usage bits
00118  *
00119  * Extended key usages are identified by OID; these bits are purely an
00120  * internal definition.
00121  */
00122 enum x509_extended_key_usage_bits {
00123         X509_CODE_SIGNING = 0x0001,
00124         X509_OCSP_SIGNING = 0x0002,
00125 };
00126 
00127 /** X.509 certificate OCSP responder */
00128 struct x509_ocsp_responder {
00129         /** URI */
00130         struct asn1_cursor uri;
00131         /** OCSP status is good */
00132         int good;
00133 };
00134 
00135 /** X.509 certificate authority information access */
00136 struct x509_authority_info_access {
00137         /** OCSP responder */
00138         struct x509_ocsp_responder ocsp;
00139 };
00140 
00141 /** X.509 certificate subject alternative name */
00142 struct x509_subject_alt_name {
00143         /** Names */
00144         struct asn1_cursor names;
00145 };
00146 
00147 /** X.509 certificate general name types */
00148 enum x509_general_name_types {
00149         X509_GENERAL_NAME_DNS = ASN1_IMPLICIT_TAG ( 2 ),
00150         X509_GENERAL_NAME_URI = ASN1_IMPLICIT_TAG ( 6 ),
00151         X509_GENERAL_NAME_IP = ASN1_IMPLICIT_TAG ( 7 ),
00152 };
00153 
00154 /** An X.509 certificate extensions set */
00155 struct x509_extensions {
00156         /** Basic constraints */
00157         struct x509_basic_constraints basic;
00158         /** Key usage */
00159         struct x509_key_usage usage;
00160         /** Extended key usage */
00161         struct x509_extended_key_usage ext_usage;
00162         /** Authority information access */
00163         struct x509_authority_info_access auth_info;
00164         /** Subject alternative name */
00165         struct x509_subject_alt_name alt_name;
00166 };
00167 
00168 /** A link in an X.509 certificate chain */
00169 struct x509_link {
00170         /** List of links */
00171         struct list_head list;
00172         /** Certificate */
00173         struct x509_certificate *cert;
00174 };
00175 
00176 /** An X.509 certificate chain */
00177 struct x509_chain {
00178         /** Reference count */
00179         struct refcnt refcnt;
00180         /** List of links */
00181         struct list_head links;
00182 };
00183 
00184 /** An X.509 certificate */
00185 struct x509_certificate {
00186         /** Reference count */
00187         struct refcnt refcnt;
00188 
00189         /** Link in certificate store */
00190         struct x509_link store;
00191 
00192         /** Flags */
00193         unsigned int flags;
00194         /** Maximum number of subsequent certificates in chain */
00195         unsigned int path_remaining;
00196 
00197         /** Raw certificate */
00198         struct asn1_cursor raw;
00199         /** Version */
00200         unsigned int version;
00201         /** Serial number */
00202         struct x509_serial serial;
00203         /** Raw tbsCertificate */
00204         struct asn1_cursor tbs;
00205         /** Signature algorithm */
00206         struct asn1_algorithm *signature_algorithm;
00207         /** Issuer */
00208         struct x509_issuer issuer;
00209         /** Validity */
00210         struct x509_validity validity;
00211         /** Subject */
00212         struct x509_subject subject;
00213         /** Signature */
00214         struct x509_signature signature;
00215         /** Extensions */
00216         struct x509_extensions extensions;
00217 };
00218 
00219 /** X.509 certificate flags */
00220 enum x509_flags {
00221         /** Certificate has been validated */
00222         X509_FL_VALIDATED = 0x0001,
00223         /** Certificate was added at build time */
00224         X509_FL_PERMANENT = 0x0002,
00225         /** Certificate was added explicitly at run time */
00226         X509_FL_EXPLICIT = 0x0004,
00227 };
00228 
00229 /**
00230  * Get reference to X.509 certificate
00231  *
00232  * @v cert              X.509 certificate
00233  * @ret cert            X.509 certificate
00234  */
00235 static inline __attribute__ (( always_inline )) struct x509_certificate *
00236 x509_get ( struct x509_certificate *cert ) {
00237         ref_get ( &cert->refcnt );
00238         return cert;
00239 }
00240 
00241 /**
00242  * Drop reference to X.509 certificate
00243  *
00244  * @v cert              X.509 certificate
00245  */
00246 static inline __attribute__ (( always_inline )) void
00247 x509_put ( struct x509_certificate *cert ) {
00248         ref_put ( &cert->refcnt );
00249 }
00250 
00251 /**
00252  * Get reference to X.509 certificate chain
00253  *
00254  * @v chain             X.509 certificate chain
00255  * @ret chain           X.509 certificate chain
00256  */
00257 static inline __attribute__ (( always_inline )) struct x509_chain *
00258 x509_chain_get ( struct x509_chain *chain ) {
00259         ref_get ( &chain->refcnt );
00260         return chain;
00261 }
00262 
00263 /**
00264  * Drop reference to X.509 certificate chain
00265  *
00266  * @v chain             X.509 certificate chain
00267  */
00268 static inline __attribute__ (( always_inline )) void
00269 x509_chain_put ( struct x509_chain *chain ) {
00270         ref_put ( &chain->refcnt );
00271 }
00272 
00273 /**
00274  * Get first certificate in X.509 certificate chain
00275  *
00276  * @v chain             X.509 certificate chain
00277  * @ret cert            X.509 certificate, or NULL
00278  */
00279 static inline __attribute__ (( always_inline )) struct x509_certificate *
00280 x509_first ( struct x509_chain *chain ) {
00281         struct x509_link *link;
00282 
00283         link = list_first_entry ( &chain->links, struct x509_link, list );
00284         return ( link ? link->cert : NULL );
00285 }
00286 
00287 /**
00288  * Get last certificate in X.509 certificate chain
00289  *
00290  * @v chain             X.509 certificate chain
00291  * @ret cert            X.509 certificate, or NULL
00292  */
00293 static inline __attribute__ (( always_inline )) struct x509_certificate *
00294 x509_last ( struct x509_chain *chain ) {
00295         struct x509_link *link;
00296 
00297         link = list_last_entry ( &chain->links, struct x509_link, list );
00298         return ( link ? link->cert : NULL );
00299 }
00300 
00301 /** An X.509 extension */
00302 struct x509_extension {
00303         /** Name */
00304         const char *name;
00305         /** Object identifier */
00306         struct asn1_cursor oid;
00307         /** Parse extension
00308          *
00309          * @v cert              X.509 certificate
00310          * @v raw               ASN.1 cursor
00311          * @ret rc              Return status code
00312          */
00313         int ( * parse ) ( struct x509_certificate *cert,
00314                           const struct asn1_cursor *raw );
00315 };
00316 
00317 /** An X.509 key purpose */
00318 struct x509_key_purpose {
00319         /** Name */
00320         const char *name;
00321         /** Object identifier */
00322         struct asn1_cursor oid;
00323         /** Extended key usage bits */
00324         unsigned int bits;
00325 };
00326 
00327 /** An X.509 access method */
00328 struct x509_access_method {
00329         /** Name */
00330         const char *name;
00331         /** Object identifier */
00332         struct asn1_cursor oid;
00333         /** Parse access method
00334          *
00335          * @v cert              X.509 certificate
00336          * @v raw               ASN.1 cursor
00337          * @ret rc              Return status code
00338          */
00339         int ( * parse ) ( struct x509_certificate *cert,
00340                           const struct asn1_cursor *raw );
00341 };
00342 
00343 /** An X.509 root certificate store */
00344 struct x509_root {
00345         /** Fingerprint digest algorithm */
00346         struct digest_algorithm *digest;
00347         /** Number of certificates */
00348         unsigned int count;
00349         /** Certificate fingerprints */
00350         const void *fingerprints;
00351 };
00352 
00353 extern const char * x509_name ( struct x509_certificate *cert );
00354 extern int x509_parse ( struct x509_certificate *cert,
00355                         const struct asn1_cursor *raw );
00356 extern int x509_certificate ( const void *data, size_t len,
00357                               struct x509_certificate **cert );
00358 extern int x509_validate ( struct x509_certificate *cert,
00359                            struct x509_certificate *issuer,
00360                            time_t time, struct x509_root *root );
00361 extern int x509_check_name ( struct x509_certificate *cert, const char *name );
00362 
00363 extern struct x509_chain * x509_alloc_chain ( void );
00364 extern int x509_append ( struct x509_chain *chain,
00365                          struct x509_certificate *cert );
00366 extern int x509_append_raw ( struct x509_chain *chain, const void *data,
00367                              size_t len );
00368 extern int x509_auto_append ( struct x509_chain *chain,
00369                               struct x509_chain *certs );
00370 extern int x509_validate_chain ( struct x509_chain *chain, time_t time,
00371                                  struct x509_chain *store,
00372                                  struct x509_root *root );
00373 extern int image_x509 ( struct image *image, size_t offset,
00374                         struct x509_certificate **cert );
00375 
00376 /* Functions exposed only for unit testing */
00377 extern int x509_check_issuer ( struct x509_certificate *cert,
00378                                struct x509_certificate *issuer );
00379 extern void x509_fingerprint ( struct x509_certificate *cert,
00380                                struct digest_algorithm *digest,
00381                                void *fingerprint );
00382 extern int x509_check_root ( struct x509_certificate *cert,
00383                              struct x509_root *root );
00384 extern int x509_check_time ( struct x509_certificate *cert, time_t time );
00385 
00386 /**
00387  * Check if X.509 certificate is valid
00388  *
00389  * @v cert              X.509 certificate
00390  */
00391 static inline int x509_is_valid ( struct x509_certificate *cert ) {
00392         return ( cert->flags & X509_FL_VALIDATED );
00393 }
00394 
00395 /**
00396  * Invalidate X.509 certificate
00397  *
00398  * @v cert              X.509 certificate
00399  */
00400 static inline void x509_invalidate ( struct x509_certificate *cert ) {
00401         cert->flags &= ~X509_FL_VALIDATED;
00402         cert->path_remaining = 0;
00403 }
00404 
00405 /**
00406  * Invalidate X.509 certificate chain
00407  *
00408  * @v chain             X.509 certificate chain
00409  */
00410 static inline void x509_invalidate_chain ( struct x509_chain *chain ) {
00411         struct x509_link *link;
00412 
00413         list_for_each_entry ( link, &chain->links, list )
00414                 x509_invalidate ( link->cert );
00415 }
00416 
00417 #endif /* _IPXE_X509_H */