3a4ea3b5831195e90dcc25d2e2ec476cedf5235f
[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 <stdio.h>
27 #include <string.h>
28 #include <time.h>
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <fcntl.h>
32
33 #include <asn1/oid.h>
34 #include <asn1/asn1.h>
35 #include <utils/identification.h>
36 #include <utils/randomizer.h>
37 #include <utils/fetcher.h>
38 #include <debug.h>
39
40 #include "hashers/hasher.h"
41 #include "rsa/rsa_public_key.h"
42 #include "certinfo.h"
43 #include "x509.h"
44 #include "ocsp.h"
45
46 #define NONCE_LENGTH 16
47
48 typedef struct private_ocsp_t private_ocsp_t;
49
50 /**
51 * Private data of a ocsp_t object.
52 */
53 struct private_ocsp_t {
54 /**
55 * Public interface for this ocsp object.
56 */
57 ocsp_t public;
58
59 /**
60 * CA certificate.
61 */
62 x509_t *cacert;
63
64 /**
65 * Requestor certificate
66 */
67 x509_t *requestor_cert;
68
69 /**
70 * Linked list of ocsp uris
71 */
72 linked_list_t *uris;
73
74 /**
75 * Linked list of certinfos to be requested
76 */
77 linked_list_t *certinfos;
78
79 /**
80 * Nonce required for ocsp request and response
81 */
82 chunk_t nonce;
83
84 /**
85 * SHA-1 hash over issuer distinguished name
86 */
87 chunk_t authNameID;
88 };
89
90 ENUM(response_status_names, STATUS_SUCCESSFUL, STATUS_UNAUTHORIZED,
91 "successful",
92 "malformed request",
93 "internal error",
94 "try later",
95 "signature required",
96 "unauthorized"
97 );
98
99 /* response container */
100 typedef struct response_t response_t;
101
102 struct response_t {
103 chunk_t tbs;
104 identification_t *responder_id_name;
105 chunk_t responder_id_key;
106 time_t produced_at;
107 chunk_t responses;
108 chunk_t nonce;
109 int algorithm;
110 chunk_t signature;
111 x509_t *responder_cert;
112
113 /**
114 * @brief Destroys the response_t object
115 *
116 * @param this response_t to destroy
117 */
118 void (*destroy) (response_t *this);
119 };
120
121 /**
122 * Implements response_t.destroy.
123 */
124 static void response_destroy(response_t *this)
125 {
126 DESTROY_IF(this->responder_id_name);
127 DESTROY_IF(this->responder_cert);
128 }
129
130 /**
131 * Creates a response_t object
132 */
133 static response_t* response_create(void)
134 {
135 response_t *this = malloc_thing(response_t);
136
137 this->tbs = chunk_empty;
138 this->responder_id_name = NULL;
139 this->responder_id_key = chunk_empty;
140 this->produced_at = UNDEFINED_TIME;
141 this->responses = chunk_empty;
142 this->nonce = chunk_empty;
143 this->algorithm = OID_UNKNOWN;
144 this->signature = chunk_empty;
145 this->responder_cert = NULL;
146
147 this->destroy = (void (*) (response_t*))response_destroy;
148
149 return this;
150 }
151
152
153
154 /* single response container */
155 typedef struct single_response single_response_t;
156
157 struct single_response {
158 single_response_t *next;
159 int hash_algorithm;
160 chunk_t issuer_name_hash;
161 chunk_t issuer_key_hash;
162 chunk_t serialNumber;
163 cert_status_t status;
164 time_t revocationTime;
165 crl_reason_t revocationReason;
166 time_t thisUpdate;
167 time_t nextUpdate;
168 };
169
170 const single_response_t empty_single_response = {
171 NULL , /* *next */
172 OID_UNKNOWN , /* hash_algorithm */
173 { NULL, 0 } , /* issuer_name_hash */
174 { NULL, 0 } , /* issuer_key_hash */
175 { NULL, 0 } , /* serial_number */
176 CERT_UNDEFINED , /* status */
177 UNDEFINED_TIME , /* revocationTime */
178 REASON_UNSPECIFIED, /* revocationReason */
179 UNDEFINED_TIME , /* this_update */
180 UNDEFINED_TIME /* next_update */
181 };
182
183 /* some OCSP specific prefabricated ASN.1 constants */
184
185 static u_char ASN1_nonce_oid_str[] = {
186 0x06, 0x09,
187 0x2B, 0x06,
188 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x02
189 };
190
191 static u_char ASN1_response_oid_str[] = {
192 0x06, 0x09,
193 0x2B, 0x06,
194 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x04
195 };
196
197 static u_char ASN1_response_content_str[] = {
198 0x04, 0x0D,
199 0x30, 0x0B,
200 0x06, 0x09,
201 0x2B, 0x06,
202 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x01
203 };
204
205 static const chunk_t ASN1_nonce_oid = chunk_from_buf(ASN1_nonce_oid_str);
206 static const chunk_t ASN1_response_oid = chunk_from_buf(ASN1_response_oid_str);
207 static const chunk_t ASN1_response_content = chunk_from_buf(ASN1_response_content_str);
208
209 /* asn.1 definitions for parsing */
210
211 static const asn1Object_t ocspResponseObjects[] = {
212 { 0, "OCSPResponse", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
213 { 1, "responseStatus", ASN1_ENUMERATED, ASN1_BODY }, /* 1 */
214 { 1, "responseBytesContext", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 2 */
215 { 2, "responseBytes", ASN1_SEQUENCE, ASN1_NONE }, /* 3 */
216 { 3, "responseType", ASN1_OID, ASN1_BODY }, /* 4 */
217 { 3, "response", ASN1_OCTET_STRING, ASN1_BODY }, /* 5 */
218 { 1, "end opt", ASN1_EOC, ASN1_END } /* 6 */
219 };
220
221 #define OCSP_RESPONSE_STATUS 1
222 #define OCSP_RESPONSE_TYPE 4
223 #define OCSP_RESPONSE 5
224 #define OCSP_RESPONSE_ROOF 7
225
226 static const asn1Object_t basicResponseObjects[] = {
227 { 0, "BasicOCSPResponse", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
228 { 1, "tbsResponseData", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
229 { 2, "versionContext", ASN1_CONTEXT_C_0, ASN1_NONE |
230 ASN1_DEF }, /* 2 */
231 { 3, "version", ASN1_INTEGER, ASN1_BODY }, /* 3 */
232 { 2, "responderIdContext", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 4 */
233 { 3, "responderIdByName", ASN1_SEQUENCE, ASN1_OBJ }, /* 5 */
234 { 2, "end choice", ASN1_EOC, ASN1_END }, /* 6 */
235 { 2, "responderIdContext", ASN1_CONTEXT_C_2, ASN1_OPT }, /* 7 */
236 { 3, "responderIdByKey", ASN1_OCTET_STRING, ASN1_BODY }, /* 8 */
237 { 2, "end choice", ASN1_EOC, ASN1_END }, /* 9 */
238 { 2, "producedAt", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 10 */
239 { 2, "responses", ASN1_SEQUENCE, ASN1_OBJ }, /* 11 */
240 { 2, "responseExtensionsContext", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 12 */
241 { 3, "responseExtensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 13 */
242 { 4, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 14 */
243 { 5, "extnID", ASN1_OID, ASN1_BODY }, /* 15 */
244 { 5, "critical", ASN1_BOOLEAN, ASN1_BODY |
245 ASN1_DEF }, /* 16 */
246 { 5, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 17 */
247 { 4, "end loop", ASN1_EOC, ASN1_END }, /* 18 */
248 { 2, "end opt", ASN1_EOC, ASN1_END }, /* 19 */
249 { 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 20 */
250 { 1, "signature", ASN1_BIT_STRING, ASN1_BODY }, /* 21 */
251 { 1, "certsContext", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 22 */
252 { 2, "certs", ASN1_SEQUENCE, ASN1_LOOP }, /* 23 */
253 { 3, "certificate", ASN1_SEQUENCE, ASN1_RAW }, /* 24 */
254 { 2, "end loop", ASN1_EOC, ASN1_END }, /* 25 */
255 { 1, "end opt", ASN1_EOC, ASN1_END } /* 26 */
256 };
257
258 #define BASIC_RESPONSE_TBS_DATA 1
259 #define BASIC_RESPONSE_VERSION 3
260 #define BASIC_RESPONSE_ID_BY_NAME 5
261 #define BASIC_RESPONSE_ID_BY_KEY 8
262 #define BASIC_RESPONSE_PRODUCED_AT 10
263 #define BASIC_RESPONSE_RESPONSES 11
264 #define BASIC_RESPONSE_EXT_ID 15
265 #define BASIC_RESPONSE_CRITICAL 16
266 #define BASIC_RESPONSE_EXT_VALUE 17
267 #define BASIC_RESPONSE_ALGORITHM 20
268 #define BASIC_RESPONSE_SIGNATURE 21
269 #define BASIC_RESPONSE_CERTIFICATE 24
270 #define BASIC_RESPONSE_ROOF 27
271
272 static const asn1Object_t responsesObjects[] = {
273 { 0, "responses", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
274 { 1, "singleResponse", ASN1_EOC, ASN1_RAW }, /* 1 */
275 { 0, "end loop", ASN1_EOC, ASN1_END } /* 2 */
276 };
277
278 #define RESPONSES_SINGLE_RESPONSE 1
279 #define RESPONSES_ROOF 3
280
281 static const asn1Object_t singleResponseObjects[] = {
282 { 0, "singleResponse", ASN1_SEQUENCE, ASN1_BODY }, /* 0 */
283 { 1, "certID", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
284 { 2, "algorithm", ASN1_EOC, ASN1_RAW }, /* 2 */
285 { 2, "issuerNameHash", ASN1_OCTET_STRING, ASN1_BODY }, /* 3 */
286 { 2, "issuerKeyHash", ASN1_OCTET_STRING, ASN1_BODY }, /* 4 */
287 { 2, "serialNumber", ASN1_INTEGER, ASN1_BODY }, /* 5 */
288 { 1, "certStatusGood", ASN1_CONTEXT_S_0, ASN1_OPT }, /* 6 */
289 { 1, "end opt", ASN1_EOC, ASN1_END }, /* 7 */
290 { 1, "certStatusRevoked", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 8 */
291 { 2, "revocationTime", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 9 */
292 { 2, "revocationReason", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 10 */
293 { 3, "crlReason", ASN1_ENUMERATED, ASN1_BODY }, /* 11 */
294 { 2, "end opt", ASN1_EOC, ASN1_END }, /* 12 */
295 { 1, "end opt", ASN1_EOC, ASN1_END }, /* 13 */
296 { 1, "certStatusUnknown", ASN1_CONTEXT_S_2, ASN1_OPT }, /* 14 */
297 { 1, "end opt", ASN1_EOC, ASN1_END }, /* 15 */
298 { 1, "thisUpdate", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 16 */
299 { 1, "nextUpdateContext", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 17 */
300 { 2, "nextUpdate", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 18 */
301 { 1, "end opt", ASN1_EOC, ASN1_END }, /* 19 */
302 { 1, "singleExtensionsContext", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 20 */
303 { 2, "singleExtensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 21 */
304 { 3, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 22 */
305 { 4, "extnID", ASN1_OID, ASN1_BODY }, /* 23 */
306 { 4, "critical", ASN1_BOOLEAN, ASN1_BODY |
307 ASN1_DEF }, /* 24 */
308 { 4, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 25 */
309 { 2, "end loop", ASN1_EOC, ASN1_END }, /* 26 */
310 { 1, "end opt", ASN1_EOC, ASN1_END } /* 27 */
311 };
312
313 #define SINGLE_RESPONSE_ALGORITHM 2
314 #define SINGLE_RESPONSE_ISSUER_NAME_HASH 3
315 #define SINGLE_RESPONSE_ISSUER_KEY_HASH 4
316 #define SINGLE_RESPONSE_SERIAL_NUMBER 5
317 #define SINGLE_RESPONSE_CERT_STATUS_GOOD 6
318 #define SINGLE_RESPONSE_CERT_STATUS_REVOKED 8
319 #define SINGLE_RESPONSE_CERT_STATUS_REVOCATION_TIME 9
320 #define SINGLE_RESPONSE_CERT_STATUS_CRL_REASON 11
321 #define SINGLE_RESPONSE_CERT_STATUS_UNKNOWN 14
322 #define SINGLE_RESPONSE_THIS_UPDATE 16
323 #define SINGLE_RESPONSE_NEXT_UPDATE 18
324 #define SINGLE_RESPONSE_EXT_ID 23
325 #define SINGLE_RESPONSE_CRITICAL 24
326 #define SINGLE_RESPONSE_EXT_VALUE 25
327 #define SINGLE_RESPONSE_ROOF 28
328
329 /**
330 * build requestorName (into TBSRequest)
331 */
332 static chunk_t build_requestor_name(private_ocsp_t *this)
333 {
334 identification_t *requestor_name = this->requestor_cert->get_subject(this->requestor_cert);
335
336 return asn1_wrap(ASN1_CONTEXT_C_1, "m",
337 asn1_simple_object(ASN1_CONTEXT_C_4,
338 requestor_name->get_encoding(requestor_name)));
339 }
340
341 /**
342 * build request (into requestList)
343 * no singleRequestExtensions used
344 */
345 static chunk_t build_request(private_ocsp_t *this, certinfo_t *certinfo)
346 {
347 chunk_t authKeyID = this->cacert->get_subjectKeyID(this->cacert);
348 chunk_t serialNumber = certinfo->get_serialNumber(certinfo);
349
350 chunk_t reqCert = asn1_wrap(ASN1_SEQUENCE, "cmmm",
351 ASN1_sha1_id,
352 asn1_simple_object(ASN1_OCTET_STRING, this->authNameID),
353 asn1_simple_object(ASN1_OCTET_STRING, authKeyID),
354 asn1_simple_object(ASN1_INTEGER, serialNumber));
355
356 return asn1_wrap(ASN1_SEQUENCE, "m", reqCert);
357 }
358
359 /**
360 * build requestList (into TBSRequest)
361 */
362 static chunk_t build_request_list(private_ocsp_t *this)
363 {
364 chunk_t requestList;
365 size_t datalen = 0;
366 linked_list_t *request_list = linked_list_create();
367
368 {
369 iterator_t *iterator = this->certinfos->create_iterator(this->certinfos, TRUE);
370 certinfo_t *certinfo;
371
372 while (iterator->iterate(iterator, (void**)&certinfo))
373 {
374 chunk_t *request = malloc_thing(chunk_t);
375
376 *request = build_request(this, certinfo);
377 request_list->insert_last(request_list, (void*)request);
378 datalen += request->len;
379 }
380 iterator->destroy(iterator);
381 }
382 {
383 iterator_t *iterator = request_list->create_iterator(request_list, TRUE);
384 chunk_t *request;
385
386 u_char *pos = build_asn1_object(&requestList, ASN1_SEQUENCE, datalen);
387
388 while (iterator->iterate(iterator, (void**)&request))
389 {
390 memcpy(pos, request->ptr, request->len);
391 pos += request->len;
392 free(request->ptr);
393 free(request);
394 }
395 iterator->destroy(iterator);
396 request_list->destroy(request_list);
397 }
398 return requestList;
399 }
400
401 /**
402 * build nonce extension (into requestExtensions)
403 */
404 static chunk_t build_nonce_extension(private_ocsp_t *this)
405 {
406 randomizer_t *randomizer = randomizer_create();
407
408 /* generate a random nonce */
409 randomizer->allocate_pseudo_random_bytes(randomizer, NONCE_LENGTH, &this->nonce);
410 randomizer->destroy(randomizer);
411
412 return asn1_wrap(ASN1_SEQUENCE, "cm",
413 ASN1_nonce_oid,
414 asn1_simple_object(ASN1_OCTET_STRING, this->nonce));
415 }
416
417 /**
418 * build requestExtensions (into TBSRequest)
419 */
420 static chunk_t build_request_ext(private_ocsp_t *this)
421 {
422 return asn1_wrap(ASN1_CONTEXT_C_2, "m",
423 asn1_wrap(ASN1_SEQUENCE, "mm",
424 build_nonce_extension(this),
425 asn1_wrap(ASN1_SEQUENCE, "cc",
426 ASN1_response_oid,
427 ASN1_response_content
428 )
429 )
430 );
431 }
432
433 /**
434 * build TBSRequest (into OCSPRequest)
435 */
436 static chunk_t build_tbs_request(private_ocsp_t *this, bool has_requestor_cert)
437 {
438 /* version is skipped since the default is ok */
439 return asn1_wrap(ASN1_SEQUENCE, "mmm",
440 (has_requestor_cert)? build_requestor_name(this): chunk_empty,
441 build_request_list(this),
442 build_request_ext(this));
443 }
444
445 /**
446 * build signature into ocsp request
447 * gets built only if a request cert with a corresponding private key is found
448 */
449 static chunk_t build_signature(private_ocsp_t *this, chunk_t tbsRequest)
450 {
451 /* TODO */
452 return chunk_empty;
453 }
454
455 /**
456 * assembles an ocsp request and sets the nonce field in private_ocsp_t to the sent nonce
457 */
458 static chunk_t ocsp_build_request(private_ocsp_t *this)
459 {
460 bool has_requestor_cert;
461 chunk_t keyid = this->cacert->get_keyid(this->cacert);
462 chunk_t tbsRequest, signature;
463
464 DBG2("assembling ocsp request");
465 DBG2("issuer: '%D'", this->cacert->get_subject(this->cacert));
466 DBG2("keyid: %#B", &keyid);
467
468 /* looks for requestor cert and matching private key */
469 has_requestor_cert = FALSE;
470
471 /* TODO has_requestor_cert = get_ocsp_requestor_cert(location); */
472
473 /* build content */
474 tbsRequest = build_tbs_request(this, has_requestor_cert);
475
476 /* sign tbsReuqest */
477 signature = (has_requestor_cert)? build_signature(this, tbsRequest): chunk_empty;
478
479 return asn1_wrap(ASN1_SEQUENCE, "mm",
480 tbsRequest,
481 signature);
482
483 return signature;
484 }
485
486 /**
487 * parse a basic OCSP response
488 */
489 static bool ocsp_parse_basic_response(chunk_t blob, int level0, response_t *res)
490 {
491 u_int level, version;
492 u_int extn_oid = OID_UNKNOWN;
493 u_char buf[BUF_LEN];
494 asn1_ctx_t ctx;
495 bool critical;
496 chunk_t object;
497 int objectID = 0;
498
499 asn1_init(&ctx, blob, level0, FALSE, FALSE);
500
501 while (objectID < BASIC_RESPONSE_ROOF)
502 {
503 if (!extract_object(basicResponseObjects, &objectID, &object, &level, &ctx))
504 {
505 return FALSE;
506 }
507
508 switch (objectID)
509 {
510 case BASIC_RESPONSE_TBS_DATA:
511 res->tbs = object;
512 break;
513 case BASIC_RESPONSE_VERSION:
514 version = (object.len)? (1 + (u_int)*object.ptr) : 1;
515 if (version != OCSP_BASIC_RESPONSE_VERSION)
516 {
517 DBG1("wrong ocsp basic response version (version= %i)", version);
518 return FALSE;
519 }
520 break;
521 case BASIC_RESPONSE_ID_BY_NAME:
522 res->responder_id_name = identification_create_from_encoding(ID_DER_ASN1_DN, object);
523 DBG2(" '%D'", res->responder_id_name);
524 break;
525 case BASIC_RESPONSE_ID_BY_KEY:
526 res->responder_id_key = object;
527 break;
528 case BASIC_RESPONSE_PRODUCED_AT:
529 res->produced_at = asn1totime(&object, ASN1_GENERALIZEDTIME);
530 break;
531 case BASIC_RESPONSE_RESPONSES:
532 res->responses = object;
533 break;
534 case BASIC_RESPONSE_EXT_ID:
535 extn_oid = known_oid(object);
536 break;
537 case BASIC_RESPONSE_CRITICAL:
538 critical = object.len && *object.ptr;
539 DBG2(" %s", critical? "TRUE" : "FALSE");
540 break;
541 case BASIC_RESPONSE_EXT_VALUE:
542 if (extn_oid == OID_NONCE)
543 res->nonce = object;
544 break;
545 case BASIC_RESPONSE_ALGORITHM:
546 res->algorithm = parse_algorithmIdentifier(object, level+1, NULL);
547 break;
548 case BASIC_RESPONSE_SIGNATURE:
549 res->signature = object;
550 break;
551 case BASIC_RESPONSE_CERTIFICATE:
552 {
553 chunk_t blob = chunk_clone(object);
554
555 res->responder_cert = x509_create_from_chunk(blob, level+1);
556 }
557 break;
558 }
559 objectID++;
560 }
561 return TRUE;
562 }
563
564 /**
565 * parse an ocsp response and return the result as a response_t struct
566 */
567 static response_status ocsp_parse_response(chunk_t blob, response_t *res)
568 {
569 asn1_ctx_t ctx;
570 chunk_t object;
571 u_int level;
572 int objectID = 0;
573
574 response_status rStatus = STATUS_INTERNALERROR;
575 u_int ocspResponseType = OID_UNKNOWN;
576
577 asn1_init(&ctx, blob, 0, FALSE, FALSE);
578
579 while (objectID < OCSP_RESPONSE_ROOF)
580 {
581 if (!extract_object(ocspResponseObjects, &objectID, &object, &level, &ctx))
582 {
583 return STATUS_INTERNALERROR;
584 }
585
586 switch (objectID)
587 {
588 case OCSP_RESPONSE_STATUS:
589 rStatus = (response_status) *object.ptr;
590 DBG2(" '%N'", response_status_names, rStatus);
591
592 switch (rStatus)
593 {
594 case STATUS_SUCCESSFUL:
595 break;
596 case STATUS_MALFORMEDREQUEST:
597 case STATUS_INTERNALERROR:
598 case STATUS_TRYLATER:
599 case STATUS_SIGREQUIRED:
600 case STATUS_UNAUTHORIZED:
601 DBG1("unsuccessful ocsp response: server said '%N'",
602 response_status_names, rStatus);
603 return rStatus;
604 default:
605 return STATUS_INTERNALERROR;
606 }
607 break;
608 case OCSP_RESPONSE_TYPE:
609 ocspResponseType = known_oid(object);
610 break;
611 case OCSP_RESPONSE:
612 {
613 switch (ocspResponseType)
614 {
615 case OID_BASIC:
616 if (!ocsp_parse_basic_response(object, level+1, res))
617 {
618 return STATUS_INTERNALERROR;
619 }
620 break;
621 default:
622 DBG1("ocsp response is not of type BASIC");
623 DBG1("ocsp response OID: %#B", &object);
624 return STATUS_INTERNALERROR;
625 }
626 }
627 break;
628 }
629 objectID++;
630 }
631 return rStatus;
632 }
633
634 /**
635 * Check if the OCSP response has a valid signature
636 */
637 static bool ocsp_valid_response(response_t *res, x509_t *ocsp_cert)
638 {
639 rsa_public_key_t *public_key;
640 time_t until = UNDEFINED_TIME;
641 err_t ugh;
642
643 DBG2("verifying ocsp response signature:");
644 DBG2("signer: '%D'", ocsp_cert->get_subject(ocsp_cert));
645 DBG2("issuer: '%D'", ocsp_cert->get_issuer(ocsp_cert));
646
647 ugh = ocsp_cert->is_valid(ocsp_cert, &until);
648 if (ugh != NULL)
649 {
650 DBG1("ocsp signer certificate %s", ugh);
651 return FALSE;
652 }
653 DBG2("ocsp signer certificate is valid");
654
655 public_key = ocsp_cert->get_public_key(ocsp_cert);
656
657 return public_key->verify_emsa_pkcs1_signature(public_key, res->tbs, res->signature) == SUCCESS;
658 }
659
660 /**
661 * parse a single OCSP response
662 */
663 static bool ocsp_parse_single_response(chunk_t blob, int level0, single_response_t *sres)
664 {
665 u_int level, extn_oid;
666 asn1_ctx_t ctx;
667 bool critical;
668 chunk_t object;
669 int objectID = 0;
670
671 asn1_init(&ctx, blob, level0, FALSE, FALSE);
672
673 while (objectID < SINGLE_RESPONSE_ROOF)
674 {
675 if (!extract_object(singleResponseObjects, &objectID, &object, &level, &ctx))
676 {
677 return FALSE;
678 }
679
680 switch (objectID)
681 {
682 case SINGLE_RESPONSE_ALGORITHM:
683 sres->hash_algorithm = parse_algorithmIdentifier(object, level+1, NULL);
684 break;
685 case SINGLE_RESPONSE_ISSUER_NAME_HASH:
686 sres->issuer_name_hash = object;
687 break;
688 case SINGLE_RESPONSE_ISSUER_KEY_HASH:
689 sres->issuer_key_hash = object;
690 break;
691 case SINGLE_RESPONSE_SERIAL_NUMBER:
692 sres->serialNumber = object;
693 break;
694 case SINGLE_RESPONSE_CERT_STATUS_GOOD:
695 sres->status = CERT_GOOD;
696 break;
697 case SINGLE_RESPONSE_CERT_STATUS_REVOKED:
698 sres->status = CERT_REVOKED;
699 break;
700 case SINGLE_RESPONSE_CERT_STATUS_REVOCATION_TIME:
701 sres->revocationTime = asn1totime(&object, ASN1_GENERALIZEDTIME);
702 break;
703 case SINGLE_RESPONSE_CERT_STATUS_CRL_REASON:
704 sres->revocationReason = (object.len == 1)
705 ? *object.ptr : REASON_UNSPECIFIED;
706 break;
707 case SINGLE_RESPONSE_CERT_STATUS_UNKNOWN:
708 sres->status = CERT_UNKNOWN;
709 break;
710 case SINGLE_RESPONSE_THIS_UPDATE:
711 sres->thisUpdate = asn1totime(&object, ASN1_GENERALIZEDTIME);
712 break;
713 case SINGLE_RESPONSE_NEXT_UPDATE:
714 sres->nextUpdate = asn1totime(&object, ASN1_GENERALIZEDTIME);
715 break;
716 case SINGLE_RESPONSE_EXT_ID:
717 extn_oid = known_oid(object);
718 break;
719 case SINGLE_RESPONSE_CRITICAL:
720 critical = object.len && *object.ptr;
721 DBG2(" %s", critical ? "TRUE" : "FALSE");
722 case SINGLE_RESPONSE_EXT_VALUE:
723 break;
724 }
725 objectID++;
726 }
727 return TRUE;
728 }
729
730 /**
731 * process received ocsp single response and add it to ocsp cache
732 */
733 static void process_single_response(private_ocsp_t *this, single_response_t *sres)
734 {
735 /* TODO */
736 }
737
738 /**
739 * verify and process ocsp response and update the ocsp cache
740 */
741 void ocsp_process_response(private_ocsp_t *this, chunk_t blob, credential_store_t *credentials)
742 {
743 x509_t *ocsp_cert = NULL;
744 response_t *res = response_create();
745
746 /* parse the ocsp response without looking at the single responses yet */
747 response_status status = ocsp_parse_response(blob, res);
748
749 if (status != STATUS_SUCCESSFUL)
750 {
751 DBG1("error in ocsp response");
752 goto err;
753 }
754
755 /* check if there was a nonce in the request */
756 if (this->nonce.ptr != NULL && res->nonce.ptr == NULL)
757 {
758 DBG1("ocsp response contains no nonce, replay attack possible");
759 }
760
761 /* check if the nonces are identical */
762 if (res->nonce.ptr != NULL && !chunk_equals(res->nonce, this->nonce))
763 {
764 DBG1("invalid nonce in ocsp response");
765 goto err;
766 }
767
768 /* check if we received a trusted responder certificate */
769 if (res->responder_cert)
770 {
771 if (res->responder_cert->is_ocsp_signer(res->responder_cert))
772 {
773 DBG2("received certificate is ocsp signer");
774 if (credentials->is_trusted(credentials, res->responder_cert))
775 {
776 DBG2("received ocsp signer certificate is trusted");
777 ocsp_cert = credentials->add_auth_certificate(credentials,
778 res->responder_cert, AUTH_OCSP);
779 res->responder_cert = NULL;
780 }
781 else
782 {
783 DBG1("received ocsp signer certificate is not trusted - rejected");
784 }
785 }
786 else
787 {
788 DBG1("received certificate is no ocsp signer - rejected");
789 }
790 }
791
792 /* if we didn't receive a trusted responder cert, search the credential store */
793 if (ocsp_cert == NULL)
794 {
795 ocsp_cert = credentials->get_auth_certificate(credentials,
796 AUTH_OCSP|AUTH_CA, res->responder_id_name);
797 if (ocsp_cert == NULL)
798 {
799 DBG1("no ocsp signer certificate found");
800 goto err;
801 }
802 }
803
804 /* check the response signature */
805 if (!ocsp_valid_response(res, ocsp_cert))
806 {
807 DBG1("ocsp response signature is invalid");
808 goto err;
809 }
810 DBG2("ocsp response signature is valid");
811
812 /* now parse the single responses one at a time */
813 {
814 u_int level;
815 asn1_ctx_t ctx;
816 chunk_t object;
817 int objectID = 0;
818
819 asn1_init(&ctx, res->responses, 0, FALSE, FALSE);
820
821 while (objectID < RESPONSES_ROOF)
822 {
823 if (!extract_object(responsesObjects, &objectID, &object, &level, &ctx))
824 {
825 goto err;
826 }
827 if (objectID == RESPONSES_SINGLE_RESPONSE)
828 {
829 single_response_t sres = empty_single_response;
830
831 if (ocsp_parse_single_response(object, level+1, &sres))
832 {
833 process_single_response(this, &sres);
834 }
835 }
836 objectID++;
837 }
838 }
839 err:
840 res->destroy(res);
841 }
842
843 /**
844 * Implements ocsp_t.fetch.
845 */
846 static void fetch(private_ocsp_t *this, certinfo_t *certinfo, credential_store_t *credentials)
847 {
848 chunk_t request;
849 chunk_t response;
850 bool fetched = FALSE;
851
852 if (this->uris->get_count(this->uris) == 0)
853 {
854 return;
855 }
856 this->certinfos->insert_last(this->certinfos, (void*)certinfo);
857
858 request = ocsp_build_request(this);
859 DBG3("ocsp request: %B", &request);
860 {
861 iterator_t *iterator = this->uris->create_iterator(this->uris, TRUE);
862 identification_t *uri;
863
864 while (iterator->iterate(iterator, (void**)&uri))
865 {
866 fetcher_t *fetcher;
867 char uri_string[BUF_LEN];
868 chunk_t uri_chunk = uri->get_encoding(uri);
869
870 snprintf(uri_string, BUF_LEN, "%.*s", uri_chunk.len, uri_chunk.ptr);
871 fetcher = fetcher_create(uri_string);
872
873 response = fetcher->post(fetcher, "application/ocsp-request", request);
874 fetcher->destroy(fetcher);
875 if (response.ptr != NULL)
876 {
877 fetched = TRUE;
878 break;
879 }
880 }
881 iterator->destroy(iterator);
882 }
883 free(request.ptr);
884
885 if (!fetched)
886 {
887 return;
888 }
889 DBG3("ocsp response: %B", &response);
890 ocsp_process_response(this, response, credentials);
891 free(response.ptr);
892 }
893
894 /**
895 * Implements ocsp_t.destroy.
896 */
897 static void destroy(private_ocsp_t *this)
898 {
899 this->certinfos->destroy(this->certinfos);
900 free(this->authNameID.ptr);
901 free(this->nonce.ptr);
902 free(this);
903 }
904
905 /*
906 * Described in header.
907 */
908 ocsp_t *ocsp_create(x509_t *cacert, linked_list_t *uris)
909 {
910 private_ocsp_t *this = malloc_thing(private_ocsp_t);
911
912 /* initialize */
913 this->cacert = cacert;
914 this->uris = uris;
915 this->certinfos = linked_list_create();
916 this->nonce = chunk_empty;
917 {
918 hasher_t *hasher = hasher_create(HASH_SHA1);
919 identification_t *issuer = cacert->get_subject(cacert);
920
921 hasher->allocate_hash(hasher, issuer->get_encoding(issuer),
922 &this->authNameID);
923 hasher->destroy(hasher);
924 }
925
926 /* public functions */
927 this->public.fetch = (void (*) (ocsp_t*,certinfo_t*,credential_store_t*))fetch;
928 this->public.destroy = (void (*) (ocsp_t*))destroy;
929
930 return &this->public;
931 }