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