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