fixed typo
[strongswan.git] / src / libstrongswan / crypto / ocsp.c
1 /**
2 * @file ocsp.c
3 *
4 * @brief Implementation of ocsp_t.
5 *
6 */
7
8 /* Support of the Online Certificate Status Protocol (OCSP)
9 * Copyright (C) 2003 Christoph Gysin, Simon Zwahlen
10 * Zuercher Hochschule Winterthur
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * for more details.
21 *
22 */
23
24 #include <unistd.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <time.h>
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <fcntl.h>
31
32 #include <asn1/oid.h>
33 #include <asn1/asn1.h>
34
35 #include "certinfo.h"
36 #include "x509.h"
37 #include "ocsp.h"
38
39 #define NONCE_LENGTH 16
40
41 static const char *const response_status_names[] = {
42 "successful",
43 "malformed request",
44 "internal error",
45 "try later",
46 "signature required",
47 "unauthorized"
48 };
49
50 /* response container */
51 typedef struct response_t response_t;
52
53 struct response_t {
54 chunk_t tbs;
55 chunk_t responder_id_name;
56 chunk_t responder_id_key;
57 time_t produced_at;
58 chunk_t responses;
59 chunk_t nonce;
60 int algorithm;
61 chunk_t signature;
62 };
63
64 const response_t empty_response = {
65 { NULL, 0 } , /* tbs */
66 { NULL, 0 } , /* responder_id_name */
67 { NULL, 0 } , /* responder_id_key */
68 UNDEFINED_TIME, /* produced_at */
69 { NULL, 0 } , /* single_response */
70 { NULL, 0 } , /* nonce */
71 OID_UNKNOWN , /* signature_algorithm */
72 { NULL, 0 } /* signature */
73 };
74
75 /* single response container */
76 typedef struct single_response single_response_t;
77
78 struct single_response {
79 single_response_t *next;
80 int hash_algorithm;
81 chunk_t issuer_name_hash;
82 chunk_t issuer_key_hash;
83 chunk_t serialNumber;
84 cert_status_t status;
85 time_t revocationTime;
86 crl_reason_t revocationReason;
87 time_t thisUpdate;
88 time_t nextUpdate;
89 };
90
91 const single_response_t empty_single_response = {
92 NULL , /* *next */
93 OID_UNKNOWN , /* hash_algorithm */
94 { NULL, 0 } , /* issuer_name_hash */
95 { NULL, 0 } , /* issuer_key_hash */
96 { NULL, 0 } , /* serial_number */
97 CERT_UNDEFINED , /* status */
98 UNDEFINED_TIME , /* revocationTime */
99 REASON_UNSPECIFIED, /* revocationReason */
100 UNDEFINED_TIME , /* this_update */
101 UNDEFINED_TIME /* next_update */
102 };
103
104
105 /* list of single requests */
106 typedef struct request_list request_list_t;
107 struct request_list {
108 chunk_t request;
109 request_list_t *next;
110 };
111
112 /* some OCSP specific prefabricated ASN.1 constants */
113
114 static u_char ASN1_nonce_oid_str[] = {
115 0x06, 0x09,
116 0x2B, 0x06,
117 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x02
118 };
119
120 static u_char ASN1_response_oid_str[] = {
121 0x06, 0x09,
122 0x2B, 0x06,
123 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x04
124 };
125
126 static u_char ASN1_response_content_str[] = {
127 0x04, 0x0D,
128 0x30, 0x0B,
129 0x06, 0x09,
130 0x2B, 0x06,
131 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x01
132 };
133
134 static const chunk_t ASN1_nonce_oid = chunk_from_buf(ASN1_nonce_oid_str);
135 static const chunk_t ASN1_response_oid = chunk_from_buf(ASN1_response_oid_str);
136 static const chunk_t ASN1_response_content = chunk_from_buf(ASN1_response_content_str);
137
138 /* asn.1 definitions for parsing */
139
140 static const asn1Object_t ocspResponseObjects[] = {
141 { 0, "OCSPResponse", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
142 { 1, "responseStatus", ASN1_ENUMERATED, ASN1_BODY }, /* 1 */
143 { 1, "responseBytesContext", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 2 */
144 { 2, "responseBytes", ASN1_SEQUENCE, ASN1_NONE }, /* 3 */
145 { 3, "responseType", ASN1_OID, ASN1_BODY }, /* 4 */
146 { 3, "response", ASN1_OCTET_STRING, ASN1_BODY }, /* 5 */
147 { 1, "end opt", ASN1_EOC, ASN1_END } /* 6 */
148 };
149
150 #define OCSP_RESPONSE_STATUS 1
151 #define OCSP_RESPONSE_TYPE 4
152 #define OCSP_RESPONSE 5
153 #define OCSP_RESPONSE_ROOF 7
154
155 static const asn1Object_t basicResponseObjects[] = {
156 { 0, "BasicOCSPResponse", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
157 { 1, "tbsResponseData", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
158 { 2, "versionContext", ASN1_CONTEXT_C_0, ASN1_NONE |
159 ASN1_DEF }, /* 2 */
160 { 3, "version", ASN1_INTEGER, ASN1_BODY }, /* 3 */
161 { 2, "responderIdContext", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 4 */
162 { 3, "responderIdByName", ASN1_SEQUENCE, ASN1_OBJ }, /* 5 */
163 { 2, "end choice", ASN1_EOC, ASN1_END }, /* 6 */
164 { 2, "responderIdContext", ASN1_CONTEXT_C_2, ASN1_OPT }, /* 7 */
165 { 3, "responderIdByKey", ASN1_OCTET_STRING, ASN1_BODY }, /* 8 */
166 { 2, "end choice", ASN1_EOC, ASN1_END }, /* 9 */
167 { 2, "producedAt", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 10 */
168 { 2, "responses", ASN1_SEQUENCE, ASN1_OBJ }, /* 11 */
169 { 2, "responseExtensionsContext", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 12 */
170 { 3, "responseExtensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 13 */
171 { 4, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 14 */
172 { 5, "extnID", ASN1_OID, ASN1_BODY }, /* 15 */
173 { 5, "critical", ASN1_BOOLEAN, ASN1_BODY |
174 ASN1_DEF }, /* 16 */
175 { 5, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 17 */
176 { 4, "end loop", ASN1_EOC, ASN1_END }, /* 18 */
177 { 2, "end opt", ASN1_EOC, ASN1_END }, /* 19 */
178 { 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 20 */
179 { 1, "signature", ASN1_BIT_STRING, ASN1_BODY }, /* 21 */
180 { 1, "certsContext", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 22 */
181 { 2, "certs", ASN1_SEQUENCE, ASN1_LOOP }, /* 23 */
182 { 3, "certificate", ASN1_SEQUENCE, ASN1_OBJ }, /* 24 */
183 { 2, "end loop", ASN1_EOC, ASN1_END }, /* 25 */
184 { 1, "end opt", ASN1_EOC, ASN1_END } /* 26 */
185 };
186
187 #define BASIC_RESPONSE_TBS_DATA 1
188 #define BASIC_RESPONSE_VERSION 3
189 #define BASIC_RESPONSE_ID_BY_NAME 5
190 #define BASIC_RESPONSE_ID_BY_KEY 8
191 #define BASIC_RESPONSE_PRODUCED_AT 10
192 #define BASIC_RESPONSE_RESPONSES 11
193 #define BASIC_RESPONSE_EXT_ID 15
194 #define BASIC_RESPONSE_CRITICAL 16
195 #define BASIC_RESPONSE_EXT_VALUE 17
196 #define BASIC_RESPONSE_ALGORITHM 20
197 #define BASIC_RESPONSE_SIGNATURE 21
198 #define BASIC_RESPONSE_CERTIFICATE 24
199 #define BASIC_RESPONSE_ROOF 27
200
201 static const asn1Object_t responsesObjects[] = {
202 { 0, "responses", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
203 { 1, "singleResponse", ASN1_EOC, ASN1_RAW }, /* 1 */
204 { 0, "end loop", ASN1_EOC, ASN1_END } /* 2 */
205 };
206
207 #define RESPONSES_SINGLE_RESPONSE 1
208 #define RESPONSES_ROOF 3
209
210 static const asn1Object_t singleResponseObjects[] = {
211 { 0, "singleResponse", ASN1_SEQUENCE, ASN1_BODY }, /* 0 */
212 { 1, "certID", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
213 { 2, "algorithm", ASN1_EOC, ASN1_RAW }, /* 2 */
214 { 2, "issuerNameHash", ASN1_OCTET_STRING, ASN1_BODY }, /* 3 */
215 { 2, "issuerKeyHash", ASN1_OCTET_STRING, ASN1_BODY }, /* 4 */
216 { 2, "serialNumber", ASN1_INTEGER, ASN1_BODY }, /* 5 */
217 { 1, "certStatusGood", ASN1_CONTEXT_S_0, ASN1_OPT }, /* 6 */
218 { 1, "end opt", ASN1_EOC, ASN1_END }, /* 7 */
219 { 1, "certStatusRevoked", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 8 */
220 { 2, "revocationTime", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 9 */
221 { 2, "revocationReason", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 10 */
222 { 3, "crlReason", ASN1_ENUMERATED, ASN1_BODY }, /* 11 */
223 { 2, "end opt", ASN1_EOC, ASN1_END }, /* 12 */
224 { 1, "end opt", ASN1_EOC, ASN1_END }, /* 13 */
225 { 1, "certStatusUnknown", ASN1_CONTEXT_S_2, ASN1_OPT }, /* 14 */
226 { 1, "end opt", ASN1_EOC, ASN1_END }, /* 15 */
227 { 1, "thisUpdate", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 16 */
228 { 1, "nextUpdateContext", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 17 */
229 { 2, "nextUpdate", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 18 */
230 { 1, "end opt", ASN1_EOC, ASN1_END }, /* 19 */
231 { 1, "singleExtensionsContext", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 20 */
232 { 2, "singleExtensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 21 */
233 { 3, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 22 */
234 { 4, "extnID", ASN1_OID, ASN1_BODY }, /* 23 */
235 { 4, "critical", ASN1_BOOLEAN, ASN1_BODY |
236 ASN1_DEF }, /* 24 */
237 { 4, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 25 */
238 { 2, "end loop", ASN1_EOC, ASN1_END }, /* 26 */
239 { 1, "end opt", ASN1_EOC, ASN1_END } /* 27 */
240 };
241
242 #define SINGLE_RESPONSE_ALGORITHM 2
243 #define SINGLE_RESPONSE_ISSUER_NAME_HASH 3
244 #define SINGLE_RESPONSE_ISSUER_KEY_HASH 4
245 #define SINGLE_RESPONSE_SERIAL_NUMBER 5
246 #define SINGLE_RESPONSE_CERT_STATUS_GOOD 6
247 #define SINGLE_RESPONSE_CERT_STATUS_REVOKED 8
248 #define SINGLE_RESPONSE_CERT_STATUS_REVOCATION_TIME 9
249 #define SINGLE_RESPONSE_CERT_STATUS_CRL_REASON 11
250 #define SINGLE_RESPONSE_CERT_STATUS_UNKNOWN 14
251 #define SINGLE_RESPONSE_THIS_UPDATE 16
252 #define SINGLE_RESPONSE_NEXT_UPDATE 18
253 #define SINGLE_RESPONSE_EXT_ID 23
254 #define SINGLE_RESPONSE_CRITICAL 24
255 #define SINGLE_RESPONSE_EXT_VALUE 25
256 #define SINGLE_RESPONSE_ROOF 28
257
258