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