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