caching of ocsp responses (experimental), no crl caching yet
[strongswan.git] / src / libstrongswan / plugins / x509 / x509_ocsp_response.c
1 /**
2 * Copyright (C) 2008 Martin Willi
3 * Copyright (C) 2007 Andreas Steffen
4 * Hochschule für Technik Rapperswil
5 * Copyright (C) 2003 Christoph Gysin, Simon Zwahlen
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * for more details.
16 *
17 * $Id$
18 */
19
20 #include "x509_ocsp_response.h"
21
22 #include <time.h>
23
24 #include <asn1/oid.h>
25 #include <asn1/asn1.h>
26 #include <utils/identification.h>
27 #include <utils/linked_list.h>
28 #include <debug.h>
29
30 #include <library.h>
31 #include <credentials/certificates/x509.h>
32 #include <credentials/certificates/crl.h>
33
34 /**
35 * how long do we use an OCSP response without a nextUpdate
36 */
37 #define OCSP_DEFAULT_LIFETIME 30
38
39 typedef struct private_x509_ocsp_response_t private_x509_ocsp_response_t;
40
41 /**
42 * Private data of a ocsp_t object.
43 */
44 struct private_x509_ocsp_response_t {
45 /**
46 * Public interface for this ocsp object.
47 */
48 x509_ocsp_response_t public;
49
50 /**
51 * complete encoded OCSP response
52 */
53 chunk_t data;
54
55 /**
56 * data for signature verficiation
57 */
58 chunk_t tbsResponseData;
59
60 /**
61 * signature algorithm (OID)
62 */
63 int signatureAlgorithm;
64
65 /**
66 * signature
67 */
68 chunk_t signature;
69
70 /**
71 * name or keyid of the responder
72 */
73 identification_t *responderId;
74
75 /**
76 * time of response production
77 */
78 time_t producedAt;
79
80 /**
81 * latest nextUpdate in this OCSP response
82 */
83 time_t usableUntil;
84
85 /**
86 * list of included certificates
87 */
88 linked_list_t *certs;
89
90 /**
91 * Linked list of OCSP responses, single_response_t
92 */
93 linked_list_t *responses;
94
95 /**
96 * Nonce required for ocsp request and response
97 */
98 chunk_t nonce;
99
100 /**
101 * reference counter
102 */
103 refcount_t ref;
104 };
105
106 /**
107 * single response contained in OCSP response
108 */
109 typedef struct {
110 /** hash algorithm OID to for the two hashes */
111 int hashAlgorithm;
112 /** hash of issuer DN */
113 chunk_t issuerNameHash;
114 /** issuerKeyID */
115 chunk_t issuerKeyHash;
116 /** serial number of certificate */
117 chunk_t serialNumber;
118 /** OCSP certificate status */
119 cert_validation_t status;
120 /** time of revocation, if revoked */
121 time_t revocationTime;
122 /** revocation reason, if revoked */
123 crl_reason_t revocationReason;
124 /** creation of associated CRL */
125 time_t thisUpdate;
126 /** creation of next CRL */
127 time_t nextUpdate;
128 } single_response_t;
129
130 /* our OCSP response version implementation */
131 #define OCSP_BASIC_RESPONSE_VERSION 1
132
133 /* some OCSP specific prefabricated ASN.1 constants */
134 static u_char ASN1_nonce_oid_str[] = {
135 0x06, 0x09,
136 0x2B, 0x06,
137 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x02
138 };
139
140 static u_char ASN1_response_oid_str[] = {
141 0x06, 0x09,
142 0x2B, 0x06,
143 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x04
144 };
145
146 static u_char ASN1_response_content_str[] = {
147 0x04, 0x0D,
148 0x30, 0x0B,
149 0x06, 0x09,
150 0x2B, 0x06,
151 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x01
152 };
153
154 static const chunk_t ASN1_nonce_oid = chunk_from_buf(ASN1_nonce_oid_str);
155 static const chunk_t ASN1_response_oid = chunk_from_buf(ASN1_response_oid_str);
156 static const chunk_t ASN1_response_content = chunk_from_buf(ASN1_response_content_str);
157
158 /* asn.1 definitions for parsing */
159
160 static const asn1Object_t ocspResponseObjects[] = {
161 { 0, "OCSPResponse", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
162 { 1, "responseStatus", ASN1_ENUMERATED, ASN1_BODY }, /* 1 */
163 { 1, "responseBytesContext", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 2 */
164 { 2, "responseBytes", ASN1_SEQUENCE, ASN1_NONE }, /* 3 */
165 { 3, "responseType", ASN1_OID, ASN1_BODY }, /* 4 */
166 { 3, "response", ASN1_OCTET_STRING, ASN1_BODY }, /* 5 */
167 { 1, "end opt", ASN1_EOC, ASN1_END } /* 6 */
168 };
169
170 #define OCSP_RESPONSE_STATUS 1
171 #define OCSP_RESPONSE_TYPE 4
172 #define OCSP_RESPONSE 5
173 #define OCSP_RESPONSE_ROOF 7
174
175 static const asn1Object_t basicResponseObjects[] = {
176 { 0, "BasicOCSPResponse", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
177 { 1, "tbsResponseData", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
178 { 2, "versionContext", ASN1_CONTEXT_C_0, ASN1_NONE |
179 ASN1_DEF }, /* 2 */
180 { 3, "version", ASN1_INTEGER, ASN1_BODY }, /* 3 */
181 { 2, "responderIdContext", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 4 */
182 { 3, "responderIdByName", ASN1_SEQUENCE, ASN1_OBJ }, /* 5 */
183 { 2, "end choice", ASN1_EOC, ASN1_END }, /* 6 */
184 { 2, "responderIdContext", ASN1_CONTEXT_C_2, ASN1_OPT }, /* 7 */
185 { 3, "responderIdByKey", ASN1_OCTET_STRING, ASN1_BODY }, /* 8 */
186 { 2, "end choice", ASN1_EOC, ASN1_END }, /* 9 */
187 { 2, "producedAt", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 10 */
188 { 2, "responses", ASN1_SEQUENCE, ASN1_OBJ }, /* 11 */
189 { 2, "responseExtensionsContext", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 12 */
190 { 3, "responseExtensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 13 */
191 { 4, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 14 */
192 { 5, "extnID", ASN1_OID, ASN1_BODY }, /* 15 */
193 { 5, "critical", ASN1_BOOLEAN, ASN1_BODY |
194 ASN1_DEF }, /* 16 */
195 { 5, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 17 */
196 { 4, "end loop", ASN1_EOC, ASN1_END }, /* 18 */
197 { 2, "end opt", ASN1_EOC, ASN1_END }, /* 19 */
198 { 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 20 */
199 { 1, "signature", ASN1_BIT_STRING, ASN1_BODY }, /* 21 */
200 { 1, "certsContext", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 22 */
201 { 2, "certs", ASN1_SEQUENCE, ASN1_LOOP }, /* 23 */
202 { 3, "certificate", ASN1_SEQUENCE, ASN1_RAW }, /* 24 */
203 { 2, "end loop", ASN1_EOC, ASN1_END }, /* 25 */
204 { 1, "end opt", ASN1_EOC, ASN1_END } /* 26 */
205 };
206
207 #define BASIC_RESPONSE_TBS_DATA 1
208 #define BASIC_RESPONSE_VERSION 3
209 #define BASIC_RESPONSE_ID_BY_NAME 5
210 #define BASIC_RESPONSE_ID_BY_KEY 8
211 #define BASIC_RESPONSE_PRODUCED_AT 10
212 #define BASIC_RESPONSE_RESPONSES 11
213 #define BASIC_RESPONSE_EXT_ID 15
214 #define BASIC_RESPONSE_CRITICAL 16
215 #define BASIC_RESPONSE_EXT_VALUE 17
216 #define BASIC_RESPONSE_ALGORITHM 20
217 #define BASIC_RESPONSE_SIGNATURE 21
218 #define BASIC_RESPONSE_CERTIFICATE 24
219 #define BASIC_RESPONSE_ROOF 27
220
221 static const asn1Object_t responsesObjects[] = {
222 { 0, "responses", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
223 { 1, "singleResponse", ASN1_EOC, ASN1_RAW }, /* 1 */
224 { 0, "end loop", ASN1_EOC, ASN1_END } /* 2 */
225 };
226
227 #define RESPONSES_SINGLE_RESPONSE 1
228 #define RESPONSES_ROOF 3
229
230 static const asn1Object_t singleResponseObjects[] = {
231 { 0, "singleResponse", ASN1_SEQUENCE, ASN1_BODY }, /* 0 */
232 { 1, "certID", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
233 { 2, "algorithm", ASN1_EOC, ASN1_RAW }, /* 2 */
234 { 2, "issuerNameHash", ASN1_OCTET_STRING, ASN1_BODY }, /* 3 */
235 { 2, "issuerKeyHash", ASN1_OCTET_STRING, ASN1_BODY }, /* 4 */
236 { 2, "serialNumber", ASN1_INTEGER, ASN1_BODY }, /* 5 */
237 { 1, "certStatusGood", ASN1_CONTEXT_S_0, ASN1_OPT }, /* 6 */
238 { 1, "end opt", ASN1_EOC, ASN1_END }, /* 7 */
239 { 1, "certStatusRevoked", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 8 */
240 { 2, "revocationTime", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 9 */
241 { 2, "revocationReason", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 10 */
242 { 3, "crlReason", ASN1_ENUMERATED, ASN1_BODY }, /* 11 */
243 { 2, "end opt", ASN1_EOC, ASN1_END }, /* 12 */
244 { 1, "end opt", ASN1_EOC, ASN1_END }, /* 13 */
245 { 1, "certStatusUnknown", ASN1_CONTEXT_S_2, ASN1_OPT }, /* 14 */
246 { 1, "end opt", ASN1_EOC, ASN1_END }, /* 15 */
247 { 1, "thisUpdate", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 16 */
248 { 1, "nextUpdateContext", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 17 */
249 { 2, "nextUpdate", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 18 */
250 { 1, "end opt", ASN1_EOC, ASN1_END }, /* 19 */
251 { 1, "singleExtensionsContext", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 20 */
252 { 2, "singleExtensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 21 */
253 { 3, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 22 */
254 { 4, "extnID", ASN1_OID, ASN1_BODY }, /* 23 */
255 { 4, "critical", ASN1_BOOLEAN, ASN1_BODY |
256 ASN1_DEF }, /* 24 */
257 { 4, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 25 */
258 { 2, "end loop", ASN1_EOC, ASN1_END }, /* 26 */
259 { 1, "end opt", ASN1_EOC, ASN1_END } /* 27 */
260 };
261
262 #define SINGLE_RESPONSE_ALGORITHM 2
263 #define SINGLE_RESPONSE_ISSUER_NAME_HASH 3
264 #define SINGLE_RESPONSE_ISSUER_KEY_HASH 4
265 #define SINGLE_RESPONSE_SERIAL_NUMBER 5
266 #define SINGLE_RESPONSE_CERT_STATUS_GOOD 6
267 #define SINGLE_RESPONSE_CERT_STATUS_REVOKED 8
268 #define SINGLE_RESPONSE_CERT_STATUS_REVOCATION_TIME 9
269 #define SINGLE_RESPONSE_CERT_STATUS_CRL_REASON 11
270 #define SINGLE_RESPONSE_CERT_STATUS_UNKNOWN 14
271 #define SINGLE_RESPONSE_THIS_UPDATE 16
272 #define SINGLE_RESPONSE_NEXT_UPDATE 18
273 #define SINGLE_RESPONSE_EXT_ID 23
274 #define SINGLE_RESPONSE_CRITICAL 24
275 #define SINGLE_RESPONSE_EXT_VALUE 25
276 #define SINGLE_RESPONSE_ROOF 28
277
278 /**
279 * Implementaiton of ocsp_response_t.get_status
280 */
281 static cert_validation_t get_status(private_x509_ocsp_response_t *this,
282 x509_t *subject, x509_t *issuer,
283 time_t *revocation_time,
284 crl_reason_t *revocation_reason,
285 time_t *this_update, time_t *next_update)
286 {
287 enumerator_t *enumerator;
288 single_response_t *response;
289 cert_validation_t status = VALIDATION_FAILED;
290 certificate_t *issuercert = &issuer->interface;
291
292 enumerator = this->responses->create_enumerator(this->responses);
293 while (enumerator->enumerate(enumerator, &response))
294 {
295 hasher_t *hasher;
296 identification_t *id;
297 chunk_t hash;
298
299 /* check serial first, is cheaper */
300 if (!chunk_equals(subject->get_serial(subject), response->serialNumber))
301 {
302 continue;
303 }
304 /* check issuerKeyHash if available */
305 if (response->issuerKeyHash.ptr)
306 {
307 public_key_t *public;
308
309 public = issuercert->get_public_key(issuercert);
310 if (!public)
311 {
312 continue;
313 }
314 switch (response->hashAlgorithm)
315 { /* TODO: generic mapper function */
316 case OID_SHA1:
317 id = public->get_id(public, ID_PUBKEY_SHA1);
318 break;
319 default:
320 public->destroy(public);
321 continue;
322 }
323 if (!chunk_equals(response->issuerKeyHash, id->get_encoding(id)))
324 {
325 public->destroy(public);
326 continue;
327 }
328 public->destroy(public);
329 }
330 /* check issuerNameHash, if available */
331 else if (response->issuerNameHash.ptr)
332 {
333 hasher = lib->crypto->create_hasher(lib->crypto,
334 hasher_algorithm_from_oid(response->hashAlgorithm));
335 if (!hasher)
336 {
337 continue;
338 }
339 id = issuercert->get_subject(issuercert);
340 hasher->allocate_hash(hasher, id->get_encoding(id), &hash);
341 hasher->destroy(hasher);
342 if (!chunk_equals(hash, response->issuerNameHash))
343 {
344 continue;
345 }
346 }
347 else
348 {
349 continue;
350 }
351 /* got a match */
352 status = response->status;
353 *revocation_time = response->revocationTime;
354 *revocation_reason = response->revocationReason;
355 *this_update = response->thisUpdate;
356 *next_update = response->nextUpdate;
357
358 break;
359 }
360 enumerator->destroy(enumerator);
361 return status;
362 }
363
364 /**
365 * Implementation of ocsp_response_t.create_cert_enumerator.
366 */
367 static enumerator_t* create_cert_enumerator(private_x509_ocsp_response_t *this)
368 {
369 return this->certs->create_enumerator(this->certs);
370 }
371
372 /**
373 * parse a single OCSP response
374 */
375 static bool parse_singleResponse(private_x509_ocsp_response_t *this,
376 chunk_t blob, int level0)
377 {
378 u_int level;
379 asn1_ctx_t ctx;
380 chunk_t object;
381 int objectID = 0;
382 single_response_t *response;
383
384 response = malloc_thing(single_response_t);
385 response->hashAlgorithm = OID_UNKNOWN;
386 response->issuerNameHash = chunk_empty;
387 response->issuerKeyHash = chunk_empty;
388 response->serialNumber = chunk_empty;
389 response->status = VALIDATION_FAILED;
390 response->revocationTime = 0;
391 response->revocationReason = CRL_UNSPECIFIED;
392 response->thisUpdate = UNDEFINED_TIME;
393 /* if nextUpdate is missing, we give it a short lifetime */
394 response->nextUpdate = this->producedAt + OCSP_DEFAULT_LIFETIME;
395
396 asn1_init(&ctx, blob, level0, FALSE, FALSE);
397 while (objectID < SINGLE_RESPONSE_ROOF)
398 {
399 if (!extract_object(singleResponseObjects, &objectID, &object, &level, &ctx))
400 {
401 free(response);
402 return FALSE;
403 }
404 switch (objectID)
405 {
406 case SINGLE_RESPONSE_ALGORITHM:
407 response->hashAlgorithm = parse_algorithmIdentifier(object, level+1, NULL);
408 break;
409 case SINGLE_RESPONSE_ISSUER_NAME_HASH:
410 response->issuerNameHash = object;
411 break;
412 case SINGLE_RESPONSE_ISSUER_KEY_HASH:
413 response->issuerKeyHash = object;
414 break;
415 case SINGLE_RESPONSE_SERIAL_NUMBER:
416 response->serialNumber = object;
417 break;
418 case SINGLE_RESPONSE_CERT_STATUS_GOOD:
419 response->status = VALIDATION_GOOD;
420 break;
421 case SINGLE_RESPONSE_CERT_STATUS_REVOKED:
422 response->status = VALIDATION_REVOKED;
423 break;
424 case SINGLE_RESPONSE_CERT_STATUS_REVOCATION_TIME:
425 response->revocationTime = asn1totime(&object, ASN1_GENERALIZEDTIME);
426 break;
427 case SINGLE_RESPONSE_CERT_STATUS_CRL_REASON:
428 if (object.len == 1)
429 {
430 response->revocationReason = *object.ptr;
431 }
432 break;
433 case SINGLE_RESPONSE_CERT_STATUS_UNKNOWN:
434 response->status = VALIDATION_FAILED;
435 break;
436 case SINGLE_RESPONSE_THIS_UPDATE:
437 response->thisUpdate = asn1totime(&object, ASN1_GENERALIZEDTIME);
438 break;
439 case SINGLE_RESPONSE_NEXT_UPDATE:
440 response->nextUpdate = asn1totime(&object, ASN1_GENERALIZEDTIME);
441 if (response->nextUpdate > this->usableUntil)
442 {
443 this->usableUntil = response->nextUpdate;
444 }
445 break;
446 }
447 objectID++;
448 }
449 if (this->usableUntil == UNDEFINED_TIME)
450 {
451 this->usableUntil = this->producedAt + OCSP_DEFAULT_LIFETIME;
452 }
453 this->responses->insert_last(this->responses, response);
454 return TRUE;
455 }
456
457 /**
458 * parse all contained responses
459 */
460 static bool parse_responses(private_x509_ocsp_response_t *this,
461 chunk_t blob, int level0)
462 {
463 u_int level;
464 asn1_ctx_t ctx;
465 chunk_t object;
466 int objectID = 0;
467
468 asn1_init(&ctx, blob, level0, FALSE, FALSE);
469 while (objectID < RESPONSES_ROOF)
470 {
471 if (!extract_object(responsesObjects, &objectID, &object, &level, &ctx))
472 {
473 return FALSE;
474 }
475 switch (objectID)
476 {
477 case RESPONSES_SINGLE_RESPONSE:
478 if (!parse_singleResponse(this, object, level+1))
479 {
480 return FALSE;
481 }
482 break;
483 default:
484 break;
485 }
486 objectID++;
487 }
488 return TRUE;
489 }
490
491 /**
492 * parse a basicOCSPResponse
493 */
494 static bool parse_basicOCSPResponse(private_x509_ocsp_response_t *this,
495 chunk_t blob, int level0)
496 {
497 u_int level, version;
498 asn1_ctx_t ctx;
499 bool critical;
500 chunk_t object, responses = chunk_empty;
501 int objectID = 0;
502 int extn_oid = OID_UNKNOWN;
503 certificate_t *cert;
504
505 asn1_init(&ctx, blob, level0, FALSE, FALSE);
506 while (objectID < BASIC_RESPONSE_ROOF)
507 {
508 if (!extract_object(basicResponseObjects, &objectID, &object, &level, &ctx))
509 {
510 return FALSE;
511 }
512 switch (objectID)
513 {
514 case BASIC_RESPONSE_TBS_DATA:
515 this->tbsResponseData = object;
516 break;
517 case BASIC_RESPONSE_VERSION:
518 version = (object.len)? (1 + (u_int)*object.ptr) : 1;
519 if (version != OCSP_BASIC_RESPONSE_VERSION)
520 {
521 DBG1(" ocsp ResponseData version %d not supported", version);
522 return FALSE;
523 }
524 break;
525 case BASIC_RESPONSE_ID_BY_NAME:
526 this->responderId = identification_create_from_encoding(
527 ID_DER_ASN1_DN, object);
528 DBG2(" '%D'", this->responderId);
529 break;
530 case BASIC_RESPONSE_ID_BY_KEY:
531 this->responderId = identification_create_from_encoding(
532 ID_PUBKEY_INFO_SHA1, object);
533 DBG2(" '%D'", this->responderId);
534 break;
535 case BASIC_RESPONSE_PRODUCED_AT:
536 this->producedAt = asn1totime(&object, ASN1_GENERALIZEDTIME);
537 break;
538 case BASIC_RESPONSE_RESPONSES:
539 responses = object;
540 break;
541 case BASIC_RESPONSE_EXT_ID:
542 extn_oid = known_oid(object);
543 break;
544 case BASIC_RESPONSE_CRITICAL:
545 critical = object.len && *object.ptr;
546 DBG2(" %s", critical ? "TRUE" : "FALSE");
547 break;
548 case BASIC_RESPONSE_EXT_VALUE:
549 if (extn_oid == OID_NONCE)
550 {
551 this->nonce = object;
552 }
553 break;
554 case BASIC_RESPONSE_ALGORITHM:
555 this->signatureAlgorithm = parse_algorithmIdentifier(
556 object, level+1, NULL);
557 break;
558 case BASIC_RESPONSE_SIGNATURE:
559 this->signature = object;
560 break;
561 case BASIC_RESPONSE_CERTIFICATE:
562 {
563 cert = lib->creds->create(lib->creds, CRED_CERTIFICATE,CERT_X509,
564 BUILD_BLOB_ASN1_DER, chunk_clone(object),
565 BUILD_END);
566 if (cert)
567 {
568 this->certs->insert_last(this->certs, cert);
569 }
570 break;
571 }
572 }
573 objectID++;
574 }
575 if (!this->responderId)
576 {
577 this->responderId = identification_create_from_encoding(ID_ANY, chunk_empty);
578 }
579 return parse_responses(this, responses, level + 1);
580 }
581
582 /**
583 * Parse OCSPResponse object
584 */
585 static bool parse_OCSPResponse(private_x509_ocsp_response_t *this)
586 {
587 asn1_ctx_t ctx;
588 chunk_t object;
589 u_int level;
590 int objectID = 0;
591 int responseType = OID_UNKNOWN;
592 ocsp_status_t status;
593
594 asn1_init(&ctx, this->data, 0, FALSE, FALSE);
595 while (objectID < OCSP_RESPONSE_ROOF)
596 {
597 if (!extract_object(ocspResponseObjects, &objectID, &object, &level, &ctx))
598 {
599 return FALSE;
600 }
601 switch (objectID)
602 {
603 case OCSP_RESPONSE_STATUS:
604 status = (ocsp_status_t)*object.ptr;
605 switch (status)
606 {
607 case OCSP_SUCCESSFUL:
608 break;
609 default:
610 DBG1(" ocsp response status: %N",
611 ocsp_status_names, status);
612 return FALSE;
613 }
614 break;
615 case OCSP_RESPONSE_TYPE:
616 responseType = known_oid(object);
617 break;
618 case OCSP_RESPONSE:
619 switch (responseType)
620 {
621 case OID_BASIC:
622 return parse_basicOCSPResponse(this, object, level+1);
623 default:
624 DBG1(" ocsp response type %#B not supported", &object);
625 return FALSE;
626 }
627 break;
628 }
629 objectID++;
630 }
631 return FALSE;
632 }
633
634 /**
635 * Implementation of certificate_t.get_type
636 */
637 static certificate_type_t get_type(private_x509_ocsp_response_t *this)
638 {
639 return CERT_X509_OCSP_RESPONSE;
640 }
641
642 /**
643 * Implementation of certificate_t.get_issuer
644 */
645 static identification_t* get_issuer(private_x509_ocsp_response_t *this)
646 {
647 return this->responderId;
648 }
649
650 /**
651 * Implementation of certificate_t.has_subject.
652 */
653 static id_match_t has_issuer(private_x509_ocsp_response_t *this,
654 identification_t *issuer)
655 {
656 return this->responderId->matches(this->responderId, issuer);
657 }
658
659 /**
660 * Implementation of certificate_t.issued_by
661 */
662 static bool issued_by(private_x509_ocsp_response_t *this, certificate_t *issuer)
663 {
664 public_key_t *key;
665 signature_scheme_t scheme;
666 bool valid;
667 x509_t *x509 = (x509_t*)issuer;
668
669 if (issuer->get_type(issuer) != CERT_X509)
670 {
671 return FALSE;
672 }
673 if (this->responderId->get_type(this->responderId) == ID_DER_ASN1_DN)
674 {
675 if (!this->responderId->equals(this->responderId,
676 issuer->get_subject(issuer)))
677 {
678 return FALSE;
679 }
680 }
681 else
682 {
683 bool equal;
684 public_key_t *public = issuer->get_public_key(issuer);
685
686 if (public == NULL)
687 {
688 return FALSE;
689 }
690 equal = this->responderId->equals(this->responderId,
691 public->get_id(public, ID_PUBKEY_SHA1));
692 public->destroy(public);
693 if (!equal)
694 {
695 return FALSE;
696 }
697 }
698 if (!(x509->get_flags(x509) & X509_OCSP_SIGNER) &&
699 !(x509->get_flags(x509) & X509_CA))
700 {
701 return FALSE;
702 }
703 /* TODO: generic OID to scheme mapper? */
704 switch (this->signatureAlgorithm)
705 {
706 case OID_MD5_WITH_RSA:
707 scheme = SIGN_RSA_EMSA_PKCS1_MD5;
708 break;
709 case OID_SHA1_WITH_RSA:
710 scheme = SIGN_RSA_EMSA_PKCS1_SHA1;
711 break;
712 case OID_SHA256_WITH_RSA:
713 scheme = SIGN_RSA_EMSA_PKCS1_SHA256;
714 break;
715 case OID_SHA384_WITH_RSA:
716 scheme = SIGN_RSA_EMSA_PKCS1_SHA384;
717 break;
718 case OID_SHA512_WITH_RSA:
719 scheme = SIGN_RSA_EMSA_PKCS1_SHA512;
720 break;
721 default:
722 return FALSE;
723 }
724 key = issuer->get_public_key(issuer);
725 if (key == NULL)
726 {
727 return FALSE;
728 }
729 valid = key->verify(key, scheme, this->tbsResponseData, this->signature);
730 key->destroy(key);
731 return valid;
732 }
733
734 /**
735 * Implementation of certificate_t.get_public_key
736 */
737 static public_key_t* get_public_key(private_x509_ocsp_response_t *this)
738 {
739 return NULL;
740 }
741
742 /**
743 * Implementation of certificate_t.get_validity.
744 */
745 static bool get_validity(private_x509_ocsp_response_t *this, time_t *when,
746 time_t *not_before, time_t *not_after)
747 {
748 time_t t;
749
750 if (when == NULL)
751 {
752 t = time(NULL);
753 }
754 else
755 {
756 t = *when;
757 }
758 if (not_before)
759 {
760 *not_before = this->producedAt;
761 }
762 if (not_after)
763 {
764 *not_after = this->usableUntil;
765 }
766 return (t < this->usableUntil);
767 }
768
769 /**
770 * Implementation of certificate_t.is_newer.
771 */
772 static bool is_newer(certificate_t *this, certificate_t *that)
773 {
774 time_t this_update, that_update, now = time(NULL);
775 bool new;
776
777 this->get_validity(this, &now, &this_update, NULL);
778 that->get_validity(that, &now, &that_update, NULL);
779 new = this_update > that_update;
780 DBG1(" ocsp response from %#T is %s - existing ocsp response from %#T %s",
781 &this_update, FALSE, new ? "newer":"not newer",
782 &that_update, FALSE, new ? "replaced":"retained");
783 return new;
784 }
785
786 /**
787 * Implementation of certificate_t.get_encoding.
788 */
789 static chunk_t get_encoding(private_x509_ocsp_response_t *this)
790 {
791 return chunk_clone(this->data);
792 }
793
794 /**
795 * Implementation of certificate_t.equals.
796 */
797 static bool equals(private_x509_ocsp_response_t *this, certificate_t *other)
798 {
799 if (this == (private_x509_ocsp_response_t*)other)
800 {
801 return TRUE;
802 }
803 if (other->get_type(other) != CERT_X509_OCSP_RESPONSE)
804 {
805 return FALSE;
806 }
807 /* check if we have the same X509 implementation */
808 if (other->equals == (void*)equals)
809 {
810 return chunk_equals(this->data,
811 ((private_x509_ocsp_response_t*)other)->data);
812 }
813 /* TODO: compare against other implementation */
814 return FALSE;
815 }
816
817 /**
818 * Implementation of certificate_t.get_ref
819 */
820 static private_x509_ocsp_response_t* get_ref(private_x509_ocsp_response_t *this)
821 {
822 ref_get(&this->ref);
823 return this;
824 }
825
826 /**
827 * Implements ocsp_t.destroy.
828 */
829 static void destroy(private_x509_ocsp_response_t *this)
830 {
831 if (ref_put(&this->ref))
832 {
833 this->certs->destroy_offset(this->certs, offsetof(certificate_t, destroy));
834 this->responses->destroy_function(this->responses, free);
835 DESTROY_IF(this->responderId);
836 free(this->data.ptr);
837 free(this);
838 }
839 }
840
841 /**
842 * load an OCSP response
843 */
844 static x509_ocsp_response_t *load(chunk_t data)
845 {
846 private_x509_ocsp_response_t *this;
847
848 this = malloc_thing(private_x509_ocsp_response_t);
849
850 this->public.interface.certificate.get_type = (certificate_type_t (*)(certificate_t *this))get_type;
851 this->public.interface.certificate.get_subject = (identification_t* (*)(certificate_t *this))get_issuer;
852 this->public.interface.certificate.get_issuer = (identification_t* (*)(certificate_t *this))get_issuer;
853 this->public.interface.certificate.has_subject = (id_match_t(*)(certificate_t*, identification_t *subject))has_issuer;
854 this->public.interface.certificate.has_issuer = (id_match_t(*)(certificate_t*, identification_t *issuer))has_issuer;
855 this->public.interface.certificate.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer))issued_by;
856 this->public.interface.certificate.get_public_key = (public_key_t* (*)(certificate_t *this))get_public_key;
857 this->public.interface.certificate.get_validity = (bool(*)(certificate_t*, time_t *when, time_t *, time_t*))get_validity;
858 this->public.interface.certificate.is_newer = (bool (*)(certificate_t*,certificate_t*))is_newer;
859 this->public.interface.certificate.get_encoding = (chunk_t(*)(certificate_t*))get_encoding;
860 this->public.interface.certificate.equals = (bool(*)(certificate_t*, certificate_t *other))equals;
861 this->public.interface.certificate.get_ref = (certificate_t* (*)(certificate_t *this))get_ref;
862 this->public.interface.certificate.destroy = (void (*)(certificate_t *this))destroy;
863 this->public.interface.get_status = (cert_validation_t(*)(ocsp_response_t*, x509_t *subject, x509_t *issuer, time_t *revocation_time,crl_reason_t *revocation_reason,time_t *this_update, time_t *next_update))get_status;
864 this->public.interface.create_cert_enumerator = (enumerator_t*(*)(ocsp_response_t*))create_cert_enumerator;
865
866 this->ref = 1;
867 this->data = data;
868 this->tbsResponseData = chunk_empty;
869 this->responderId = NULL;
870 this->producedAt = UNDEFINED_TIME;
871 this->usableUntil = UNDEFINED_TIME;
872 this->responses = linked_list_create();
873 this->nonce = chunk_empty;
874 this->signatureAlgorithm = OID_UNKNOWN;
875 this->signature = chunk_empty;
876 this->certs = linked_list_create();
877
878 if (!parse_OCSPResponse(this))
879 {
880 destroy(this);
881 return NULL;
882 }
883 return &this->public;
884 }
885
886
887 typedef struct private_builder_t private_builder_t;
888 /**
889 * Builder implementation for certificate loading
890 */
891 struct private_builder_t {
892 /** implements the builder interface */
893 builder_t public;
894 /** loaded response */
895 x509_ocsp_response_t *res;
896 };
897
898 /**
899 * Implementation of builder_t.build
900 */
901 static x509_ocsp_response_t *build(private_builder_t *this)
902 {
903 x509_ocsp_response_t *res = this->res;
904
905 free(this);
906 return res;
907 }
908
909 /**
910 * Implementation of builder_t.add
911 */
912 static void add(private_builder_t *this, builder_part_t part, ...)
913 {
914 va_list args;
915
916 if (this->res)
917 {
918 DBG1("ignoring surplus build part %N", builder_part_names, part);
919 return;
920 }
921
922 switch (part)
923 {
924 case BUILD_BLOB_ASN1_DER:
925 {
926 va_start(args, part);
927 this->res = load(va_arg(args, chunk_t));
928 va_end(args);
929 break;
930 }
931 default:
932 DBG1("ignoring unsupported build part %N", builder_part_names, part);
933 break;
934 }
935 }
936
937 /**
938 * Builder construction function
939 */
940 builder_t *x509_ocsp_response_builder(certificate_type_t type)
941 {
942 private_builder_t *this;
943
944 if (type != CERT_X509_OCSP_RESPONSE)
945 {
946 return NULL;
947 }
948
949 this = malloc_thing(private_builder_t);
950
951 this->res = NULL;
952 this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
953 this->public.build = (void*(*)(builder_t *this))build;
954
955 return &this->public;
956 }
957