1 #ifndef _IPXE_OCSP_H
2 #define _IPXE_OCSP_H
3 
4 /** @file
5  *
6  * Online Certificate Status Protocol
7  *
8  */
9 
10 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
11 
12 #include <stdarg.h>
13 #include <time.h>
14 #include <ipxe/asn1.h>
15 #include <ipxe/x509.h>
16 #include <ipxe/refcnt.h>
17 #include <config/crypto.h>
18 
19 /* Allow OCSP to be disabled completely */
20 #ifdef OCSP_CHECK
21 #define OCSP_ENABLED 1
22 #else
23 #define OCSP_ENABLED 0
24 #endif
25 
26 /** OCSP algorithm identifier */
27 #define OCSP_ALGORITHM_IDENTIFIER( ... )				\
28 	ASN1_OID, VA_ARG_COUNT ( __VA_ARGS__ ), __VA_ARGS__,		\
29 	ASN1_NULL, 0x00
30 
31 /* OCSP response statuses */
32 #define OCSP_STATUS_SUCCESSFUL		0x00
33 #define OCSP_STATUS_MALFORMED_REQUEST	0x01
34 #define OCSP_STATUS_INTERNAL_ERROR	0x02
35 #define OCSP_STATUS_TRY_LATER		0x03
36 #define OCSP_STATUS_SIG_REQUIRED	0x05
37 #define OCSP_STATUS_UNAUTHORIZED	0x06
38 
39 struct ocsp_check;
40 
41 /** An OCSP request */
42 struct ocsp_request {
43 	/** Request builder */
44 	struct asn1_builder builder;
45 	/** Certificate ID (excluding hashAlgorithm) */
46 	struct asn1_cursor cert_id_tail;
47 };
48 
49 /** An OCSP responder */
50 struct ocsp_responder {
51 	/**
52 	 * Check if certificate is the responder's certificate
53 	 *
54 	 * @v ocsp		OCSP check
55 	 * @v cert		Certificate
56 	 * @ret difference	Difference as returned by memcmp()
57 	 */
58 	int ( * compare ) ( struct ocsp_check *ocsp,
59 			    struct x509_certificate *cert );
60 	/** Responder ID */
61 	struct asn1_cursor id;
62 };
63 
64 /** An OCSP response */
65 struct ocsp_response {
66 	/** Raw response */
67 	void *data;
68 	/** Raw tbsResponseData */
69 	struct asn1_cursor tbs;
70 	/** Responder */
71 	struct ocsp_responder responder;
72 	/** Time at which status is known to be correct */
73 	time_t this_update;
74 	/** Time at which newer status information will be available */
75 	time_t next_update;
76 	/** Signature algorithm */
77 	struct asn1_algorithm *algorithm;
78 	/** Signature value */
79 	struct asn1_bit_string signature;
80 	/** Signing certificate */
81 	struct x509_certificate *signer;
82 };
83 
84 /** An OCSP check */
85 struct ocsp_check {
86 	/** Reference count */
87 	struct refcnt refcnt;
88 	/** Certificate being checked */
89 	struct x509_certificate *cert;
90 	/** Issuing certificate */
91 	struct x509_certificate *issuer;
92 	/** URI string */
93 	char *uri_string;
94 	/** Request */
95 	struct ocsp_request request;
96 	/** Response */
97 	struct ocsp_response response;
98 };
99 
100 /**
101  * Get reference to OCSP check
102  *
103  * @v ocsp		OCSP check
104  * @ret ocsp		OCSP check
105  */
106 static inline __attribute__ (( always_inline )) struct ocsp_check *
ocsp_get(struct ocsp_check * ocsp)107 ocsp_get ( struct ocsp_check *ocsp ) {
108 	ref_get ( &ocsp->refcnt );
109 	return ocsp;
110 }
111 
112 /**
113  * Drop reference to OCSP check
114  *
115  * @v ocsp		OCSP check
116  */
117 static inline __attribute__ (( always_inline )) void
ocsp_put(struct ocsp_check * ocsp)118 ocsp_put ( struct ocsp_check *ocsp ) {
119 	ref_put ( &ocsp->refcnt );
120 }
121 
122 /**
123  * Check if X.509 certificate requires an OCSP check
124  *
125  * @v cert		X.509 certificate
126  * @ret ocsp_required	An OCSP check is required
127  */
ocsp_required(struct x509_certificate * cert)128 static inline int ocsp_required ( struct x509_certificate *cert ) {
129 
130 	/* An OCSP check is never required if OCSP checks are disabled */
131 	if ( ! OCSP_ENABLED )
132 		return 0;
133 
134 	/* An OCSP check is required if an OCSP URI exists but the
135 	 * OCSP status is not (yet) good.
136 	 */
137 	return ( cert->extensions.auth_info.ocsp.uri.len &&
138 		 ( ! cert->extensions.auth_info.ocsp.good ) );
139 }
140 
141 extern int ocsp_check ( struct x509_certificate *cert,
142 			struct x509_certificate *issuer,
143 			struct ocsp_check **ocsp );
144 extern int ocsp_response ( struct ocsp_check *ocsp, const void *data,
145 			   size_t len );
146 extern int ocsp_validate ( struct ocsp_check *check, time_t time );
147 
148 #endif /* _IPXE_OCSP_H */
149