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