#ifndef _IPXE_OCSP_H #define _IPXE_OCSP_H /** @file * * Online Certificate Status Protocol * */ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include #include #include #include #include #include /* Allow OCSP to be disabled completely */ #ifdef OCSP_CHECK #define OCSP_ENABLED 1 #else #define OCSP_ENABLED 0 #endif /** OCSP algorithm identifier */ #define OCSP_ALGORITHM_IDENTIFIER( ... ) \ ASN1_OID, VA_ARG_COUNT ( __VA_ARGS__ ), __VA_ARGS__, \ ASN1_NULL, 0x00 /* OCSP response statuses */ #define OCSP_STATUS_SUCCESSFUL 0x00 #define OCSP_STATUS_MALFORMED_REQUEST 0x01 #define OCSP_STATUS_INTERNAL_ERROR 0x02 #define OCSP_STATUS_TRY_LATER 0x03 #define OCSP_STATUS_SIG_REQUIRED 0x05 #define OCSP_STATUS_UNAUTHORIZED 0x06 struct ocsp_check; /** An OCSP request */ struct ocsp_request { /** Request builder */ struct asn1_builder builder; /** Certificate ID */ struct asn1_cursor cert_id; }; /** An OCSP responder */ struct ocsp_responder { /** * Check if certificate is the responder's certificate * * @v ocsp OCSP check * @v cert Certificate * @ret difference Difference as returned by memcmp() */ int ( * compare ) ( struct ocsp_check *ocsp, struct x509_certificate *cert ); /** Responder ID */ struct asn1_cursor id; }; /** An OCSP response */ struct ocsp_response { /** Raw response */ void *data; /** Raw tbsResponseData */ struct asn1_cursor tbs; /** Responder */ struct ocsp_responder responder; /** Time at which status is known to be correct */ time_t this_update; /** Time at which newer status information will be available */ time_t next_update; /** Signature algorithm */ struct asn1_algorithm *algorithm; /** Signature value */ struct asn1_bit_string signature; /** Signing certificate */ struct x509_certificate *signer; }; /** An OCSP check */ struct ocsp_check { /** Reference count */ struct refcnt refcnt; /** Certificate being checked */ struct x509_certificate *cert; /** Issuing certificate */ struct x509_certificate *issuer; /** URI string */ char *uri_string; /** Request */ struct ocsp_request request; /** Response */ struct ocsp_response response; }; /** * Get reference to OCSP check * * @v ocsp OCSP check * @ret ocsp OCSP check */ static inline __attribute__ (( always_inline )) struct ocsp_check * ocsp_get ( struct ocsp_check *ocsp ) { ref_get ( &ocsp->refcnt ); return ocsp; } /** * Drop reference to OCSP check * * @v ocsp OCSP check */ static inline __attribute__ (( always_inline )) void ocsp_put ( struct ocsp_check *ocsp ) { ref_put ( &ocsp->refcnt ); } /** * Check if X.509 certificate requires an OCSP check * * @v cert X.509 certificate * @ret ocsp_required An OCSP check is required */ static inline int ocsp_required ( struct x509_certificate *cert ) { /* An OCSP check is never required if OCSP checks are disabled */ if ( ! OCSP_ENABLED ) return 0; /* An OCSP check is required if an OCSP URI exists but the * OCSP status is not (yet) good. */ return ( cert->extensions.auth_info.ocsp.uri.len && ( ! cert->extensions.auth_info.ocsp.good ) ); } extern int ocsp_check ( struct x509_certificate *cert, struct x509_certificate *issuer, struct ocsp_check **ocsp ); extern int ocsp_response ( struct ocsp_check *ocsp, const void *data, size_t len ); extern int ocsp_validate ( struct ocsp_check *check, time_t time ); #endif /* _IPXE_OCSP_H */