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