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