iPXE
ocsp.h
Go to the documentation of this file.
00001 #ifndef _IPXE_OCSP_H
00002 #define _IPXE_OCSP_H
00003 
00004 /** @file
00005  *
00006  * Online Certificate Status Protocol
00007  *
00008  */
00009 
00010 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
00011 
00012 #include <stdarg.h>
00013 #include <time.h>
00014 #include <ipxe/asn1.h>
00015 #include <ipxe/x509.h>
00016 #include <ipxe/refcnt.h>
00017 #include <config/crypto.h>
00018 
00019 /* Allow OCSP to be disabled completely */
00020 #ifdef OCSP_CHECK
00021 #define OCSP_ENABLED 1
00022 #else
00023 #define OCSP_ENABLED 0
00024 #endif
00025 
00026 /** OCSP algorithm identifier */
00027 #define OCSP_ALGORITHM_IDENTIFIER( ... )                                \
00028         ASN1_OID, VA_ARG_COUNT ( __VA_ARGS__ ), __VA_ARGS__,            \
00029         ASN1_NULL, 0x00
00030 
00031 /* OCSP response statuses */
00032 #define OCSP_STATUS_SUCCESSFUL          0x00
00033 #define OCSP_STATUS_MALFORMED_REQUEST   0x01
00034 #define OCSP_STATUS_INTERNAL_ERROR      0x02
00035 #define OCSP_STATUS_TRY_LATER           0x03
00036 #define OCSP_STATUS_SIG_REQUIRED        0x05
00037 #define OCSP_STATUS_UNAUTHORIZED        0x06
00038 
00039 struct ocsp_check;
00040 
00041 /** An OCSP request */
00042 struct ocsp_request {
00043         /** Request builder */
00044         struct asn1_builder builder;
00045         /** Certificate ID */
00046         struct asn1_cursor cert_id;
00047 };
00048 
00049 /** An OCSP responder */
00050 struct ocsp_responder {
00051         /**
00052          * Check if certificate is the responder's certificate
00053          *
00054          * @v ocsp              OCSP check
00055          * @v cert              Certificate
00056          * @ret difference      Difference as returned by memcmp()
00057          */
00058         int ( * compare ) ( struct ocsp_check *ocsp,
00059                             struct x509_certificate *cert );
00060         /** Responder ID */
00061         struct asn1_cursor id;
00062 };
00063 
00064 /** An OCSP response */
00065 struct ocsp_response {
00066         /** Raw response */
00067         void *data;
00068         /** Raw tbsResponseData */
00069         struct asn1_cursor tbs;
00070         /** Responder */
00071         struct ocsp_responder responder;
00072         /** Time at which status is known to be correct */
00073         time_t this_update;
00074         /** Time at which newer status information will be available */
00075         time_t next_update;
00076         /** Signature algorithm */
00077         struct asn1_algorithm *algorithm;
00078         /** Signature value */
00079         struct asn1_bit_string signature;
00080         /** Signing certificate */
00081         struct x509_certificate *signer;
00082 };
00083 
00084 /** An OCSP check */
00085 struct ocsp_check {
00086         /** Reference count */
00087         struct refcnt refcnt;
00088         /** Certificate being checked */
00089         struct x509_certificate *cert;
00090         /** Issuing certificate */
00091         struct x509_certificate *issuer;
00092         /** URI string */
00093         char *uri_string;
00094         /** Request */
00095         struct ocsp_request request;
00096         /** Response */
00097         struct ocsp_response response;
00098 };
00099 
00100 /**
00101  * Get reference to OCSP check
00102  *
00103  * @v ocsp              OCSP check
00104  * @ret ocsp            OCSP check
00105  */
00106 static inline __attribute__ (( always_inline )) struct ocsp_check *
00107 ocsp_get ( struct ocsp_check *ocsp ) {
00108         ref_get ( &ocsp->refcnt );
00109         return ocsp;
00110 }
00111 
00112 /**
00113  * Drop reference to OCSP check
00114  *
00115  * @v ocsp              OCSP check
00116  */
00117 static inline __attribute__ (( always_inline )) void
00118 ocsp_put ( struct ocsp_check *ocsp ) {
00119         ref_put ( &ocsp->refcnt );
00120 }
00121 
00122 /**
00123  * Check if X.509 certificate requires an OCSP check
00124  *
00125  * @v cert              X.509 certificate
00126  * @ret ocsp_required   An OCSP check is required
00127  */
00128 static inline int ocsp_required ( struct x509_certificate *cert ) {
00129 
00130         /* An OCSP check is never required if OCSP checks are disabled */
00131         if ( ! OCSP_ENABLED )
00132                 return 0;
00133 
00134         /* An OCSP check is required if an OCSP URI exists but the
00135          * OCSP status is not (yet) good.
00136          */
00137         return ( cert->extensions.auth_info.ocsp.uri.len &&
00138                  ( ! cert->extensions.auth_info.ocsp.good ) );
00139 }
00140 
00141 extern int ocsp_check ( struct x509_certificate *cert,
00142                         struct x509_certificate *issuer,
00143                         struct ocsp_check **ocsp );
00144 extern int ocsp_response ( struct ocsp_check *ocsp, const void *data,
00145                            size_t len );
00146 extern int ocsp_validate ( struct ocsp_check *check, time_t time );
00147 
00148 #endif /* _IPXE_OCSP_H */