ECB mode added to the DES plugin
[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 <asn1/asn1_parser.h>
27 #include <utils/identification.h>
28 #include <utils/linked_list.h>
29 #include <debug.h>
30
31 #include <library.h>
32 #include <credentials/certificates/x509.h>
33 #include <credentials/certificates/crl.h>
34
35 /**
36 * how long do we use an OCSP response without a nextUpdate
37 */
38 #define OCSP_DEFAULT_LIFETIME 30
39
40 typedef struct private_x509_ocsp_response_t private_x509_ocsp_response_t;
41
42 /**
43 * Private data of a ocsp_t object.
44 */
45 struct private_x509_ocsp_response_t {
46 /**
47 * Public interface for this ocsp object.
48 */
49 x509_ocsp_response_t public;
50
51 /**
52 * complete encoded OCSP response
53 */
54 chunk_t encoding;
55
56 /**
57 * data for signature verficiation
58 */
59 chunk_t tbsResponseData;
60
61 /**
62 * signature algorithm (OID)
63 */
64 int signatureAlgorithm;
65
66 /**
67 * signature
68 */
69 chunk_t signature;
70
71 /**
72 * name or keyid of the responder
73 */
74 identification_t *responderId;
75
76 /**
77 * time of response production
78 */
79 time_t producedAt;
80
81 /**
82 * latest nextUpdate in this OCSP response
83 */
84 time_t usableUntil;
85
86 /**
87 * list of included certificates
88 */
89 linked_list_t *certs;
90
91 /**
92 * Linked list of OCSP responses, single_response_t
93 */
94 linked_list_t *responses;
95
96 /**
97 * Nonce required for ocsp request and response
98 */
99 chunk_t nonce;
100
101 /**
102 * reference counter
103 */
104 refcount_t ref;
105 };
106
107 /**
108 * single response contained in OCSP response
109 */
110 typedef struct {
111 /** hash algorithm OID to for the two hashes */
112 int hashAlgorithm;
113 /** hash of issuer DN */
114 chunk_t issuerNameHash;
115 /** issuerKeyID */
116 chunk_t issuerKeyHash;
117 /** serial number of certificate */
118 chunk_t serialNumber;
119 /** OCSP certificate status */
120 cert_validation_t status;
121 /** time of revocation, if revoked */
122 time_t revocationTime;
123 /** revocation reason, if revoked */
124 crl_reason_t revocationReason;
125 /** creation of associated CRL */
126 time_t thisUpdate;
127 /** creation of next CRL */
128 time_t nextUpdate;
129 } single_response_t;
130
131 /* our OCSP response version implementation */
132 #define OCSP_BASIC_RESPONSE_VERSION 1
133
134 /* some OCSP specific prefabricated ASN.1 constants */
135 static u_char ASN1_nonce_oid_str[] = {
136 0x06, 0x09,
137 0x2B, 0x06,
138 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x02
139 };
140
141 static u_char ASN1_response_oid_str[] = {
142 0x06, 0x09,
143 0x2B, 0x06,
144 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x04
145 };
146
147 static u_char ASN1_response_content_str[] = {
148 0x04, 0x0D,
149 0x30, 0x0B,
150 0x06, 0x09,
151 0x2B, 0x06,
152 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x01
153 };
154
155 static const chunk_t ASN1_nonce_oid = chunk_from_buf(ASN1_nonce_oid_str);
156 static const chunk_t ASN1_response_oid = chunk_from_buf(ASN1_response_oid_str);
157 static const chunk_t ASN1_response_content = chunk_from_buf(ASN1_response_content_str);
158
159 /**
160 * Implementaiton of ocsp_response_t.get_status
161 */
162 static cert_validation_t get_status(private_x509_ocsp_response_t *this,
163 x509_t *subject, x509_t *issuer,
164 time_t *revocation_time,
165 crl_reason_t *revocation_reason,
166 time_t *this_update, time_t *next_update)
167 {
168 enumerator_t *enumerator;
169 single_response_t *response;
170 cert_validation_t status = VALIDATION_FAILED;
171 certificate_t *issuercert = &issuer->interface;
172
173 enumerator = this->responses->create_enumerator(this->responses);
174 while (enumerator->enumerate(enumerator, &response))
175 {
176 hasher_t *hasher;
177 identification_t *id;
178 chunk_t hash;
179
180 /* check serial first, is cheaper */
181 if (!chunk_equals(subject->get_serial(subject), response->serialNumber))
182 {
183 continue;
184 }
185 /* check issuerKeyHash if available */
186 if (response->issuerKeyHash.ptr)
187 {
188 public_key_t *public;
189
190 public = issuercert->get_public_key(issuercert);
191 if (!public)
192 {
193 continue;
194 }
195 switch (response->hashAlgorithm)
196 { /* TODO: generic mapper function */
197 case OID_SHA1:
198 id = public->get_id(public, ID_PUBKEY_SHA1);
199 break;
200 default:
201 public->destroy(public);
202 continue;
203 }
204 if (!chunk_equals(response->issuerKeyHash, id->get_encoding(id)))
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_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(" '%D'", this->responderId);
527 break;
528 case BASIC_RESPONSE_ID_BY_KEY:
529 this->responderId = identification_create_from_encoding(
530 ID_PUBKEY_INFO_SHA1, object);
531 DBG2(" '%D'", 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_DER_ASN1_DN)
700 {
701 if (!this->responderId->equals(this->responderId,
702 issuer->get_subject(issuer)))
703 {
704 return FALSE;
705 }
706 }
707 else
708 {
709 bool equal;
710 public_key_t *public = issuer->get_public_key(issuer);
711
712 if (public == NULL)
713 {
714 return FALSE;
715 }
716 equal = this->responderId->equals(this->responderId,
717 public->get_id(public, ID_PUBKEY_SHA1));
718 public->destroy(public);
719 if (!equal)
720 {
721 return FALSE;
722 }
723 }
724 if (!(x509->get_flags(x509) & X509_OCSP_SIGNER) &&
725 !(x509->get_flags(x509) & X509_CA))
726 {
727 return FALSE;
728 }
729 /* TODO: generic OID to scheme mapper? */
730 switch (this->signatureAlgorithm)
731 {
732 case OID_MD5_WITH_RSA:
733 scheme = SIGN_RSA_EMSA_PKCS1_MD5;
734 break;
735 case OID_SHA1_WITH_RSA:
736 scheme = SIGN_RSA_EMSA_PKCS1_SHA1;
737 break;
738 case OID_SHA256_WITH_RSA:
739 scheme = SIGN_RSA_EMSA_PKCS1_SHA256;
740 break;
741 case OID_SHA384_WITH_RSA:
742 scheme = SIGN_RSA_EMSA_PKCS1_SHA384;
743 break;
744 case OID_SHA512_WITH_RSA:
745 scheme = SIGN_RSA_EMSA_PKCS1_SHA512;
746 break;
747 case OID_ECDSA_WITH_SHA1:
748 scheme = SIGN_ECDSA_WITH_SHA1;
749 break;
750 default:
751 return FALSE;
752 }
753 key = issuer->get_public_key(issuer);
754 if (key == NULL)
755 {
756 return FALSE;
757 }
758 valid = key->verify(key, scheme, this->tbsResponseData, this->signature);
759 key->destroy(key);
760 return valid;
761 }
762
763 /**
764 * Implementation of certificate_t.get_public_key
765 */
766 static public_key_t* get_public_key(private_x509_ocsp_response_t *this)
767 {
768 return NULL;
769 }
770
771 /**
772 * Implementation of certificate_t.get_validity.
773 */
774 static bool get_validity(private_x509_ocsp_response_t *this, time_t *when,
775 time_t *not_before, time_t *not_after)
776 {
777 time_t t;
778
779 if (when == NULL)
780 {
781 t = time(NULL);
782 }
783 else
784 {
785 t = *when;
786 }
787 if (not_before)
788 {
789 *not_before = this->producedAt;
790 }
791 if (not_after)
792 {
793 *not_after = this->usableUntil;
794 }
795 return (t < this->usableUntil);
796 }
797
798 /**
799 * Implementation of certificate_t.is_newer.
800 */
801 static bool is_newer(certificate_t *this, certificate_t *that)
802 {
803 time_t this_update, that_update, now = time(NULL);
804 bool new;
805
806 this->get_validity(this, &now, &this_update, NULL);
807 that->get_validity(that, &now, &that_update, NULL);
808 new = this_update > that_update;
809 DBG1(" ocsp response from %#T is %s - existing ocsp response from %#T %s",
810 &this_update, FALSE, new ? "newer":"not newer",
811 &that_update, FALSE, new ? "replaced":"retained");
812 return new;
813 }
814
815 /**
816 * Implementation of certificate_t.get_encoding.
817 */
818 static chunk_t get_encoding(private_x509_ocsp_response_t *this)
819 {
820 return chunk_clone(this->encoding);
821 }
822
823 /**
824 * Implementation of certificate_t.equals.
825 */
826 static bool equals(private_x509_ocsp_response_t *this, certificate_t *other)
827 {
828 chunk_t encoding;
829 bool equal;
830
831 if (this == (private_x509_ocsp_response_t*)other)
832 {
833 return TRUE;
834 }
835 if (other->get_type(other) != CERT_X509_OCSP_RESPONSE)
836 {
837 return FALSE;
838 }
839 if (other->equals == (void*)equals)
840 { /* skip allocation if we have the same implementation */
841 return chunk_equals(this->encoding, ((private_x509_ocsp_response_t*)other)->encoding);
842 }
843 encoding = other->get_encoding(other);
844 equal = chunk_equals(this->encoding, encoding);
845 free(encoding.ptr);
846 return equal;
847 }
848
849 /**
850 * Implementation of certificate_t.get_ref
851 */
852 static private_x509_ocsp_response_t* get_ref(private_x509_ocsp_response_t *this)
853 {
854 ref_get(&this->ref);
855 return this;
856 }
857
858 /**
859 * Implements ocsp_t.destroy.
860 */
861 static void destroy(private_x509_ocsp_response_t *this)
862 {
863 if (ref_put(&this->ref))
864 {
865 this->certs->destroy_offset(this->certs, offsetof(certificate_t, destroy));
866 this->responses->destroy_function(this->responses, free);
867 DESTROY_IF(this->responderId);
868 free(this->encoding.ptr);
869 free(this);
870 }
871 }
872
873 /**
874 * load an OCSP response
875 */
876 static x509_ocsp_response_t *load(chunk_t data)
877 {
878 private_x509_ocsp_response_t *this;
879
880 this = malloc_thing(private_x509_ocsp_response_t);
881
882 this->public.interface.certificate.get_type = (certificate_type_t (*)(certificate_t *this))get_type;
883 this->public.interface.certificate.get_subject = (identification_t* (*)(certificate_t *this))get_issuer;
884 this->public.interface.certificate.get_issuer = (identification_t* (*)(certificate_t *this))get_issuer;
885 this->public.interface.certificate.has_subject = (id_match_t(*)(certificate_t*, identification_t *subject))has_issuer;
886 this->public.interface.certificate.has_issuer = (id_match_t(*)(certificate_t*, identification_t *issuer))has_issuer;
887 this->public.interface.certificate.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer))issued_by;
888 this->public.interface.certificate.get_public_key = (public_key_t* (*)(certificate_t *this))get_public_key;
889 this->public.interface.certificate.get_validity = (bool(*)(certificate_t*, time_t *when, time_t *, time_t*))get_validity;
890 this->public.interface.certificate.is_newer = (bool (*)(certificate_t*,certificate_t*))is_newer;
891 this->public.interface.certificate.get_encoding = (chunk_t(*)(certificate_t*))get_encoding;
892 this->public.interface.certificate.equals = (bool(*)(certificate_t*, certificate_t *other))equals;
893 this->public.interface.certificate.get_ref = (certificate_t* (*)(certificate_t *this))get_ref;
894 this->public.interface.certificate.destroy = (void (*)(certificate_t *this))destroy;
895 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;
896 this->public.interface.create_cert_enumerator = (enumerator_t*(*)(ocsp_response_t*))create_cert_enumerator;
897
898 this->ref = 1;
899 this->encoding = data;
900 this->tbsResponseData = chunk_empty;
901 this->responderId = NULL;
902 this->producedAt = UNDEFINED_TIME;
903 this->usableUntil = UNDEFINED_TIME;
904 this->responses = linked_list_create();
905 this->nonce = chunk_empty;
906 this->signatureAlgorithm = OID_UNKNOWN;
907 this->signature = chunk_empty;
908 this->certs = linked_list_create();
909
910 if (!parse_OCSPResponse(this))
911 {
912 destroy(this);
913 return NULL;
914 }
915 return &this->public;
916 }
917
918
919 typedef struct private_builder_t private_builder_t;
920 /**
921 * Builder implementation for certificate loading
922 */
923 struct private_builder_t {
924 /** implements the builder interface */
925 builder_t public;
926 /** loaded response */
927 x509_ocsp_response_t *res;
928 };
929
930 /**
931 * Implementation of builder_t.build
932 */
933 static x509_ocsp_response_t *build(private_builder_t *this)
934 {
935 x509_ocsp_response_t *res = this->res;
936
937 free(this);
938 return res;
939 }
940
941 /**
942 * Implementation of builder_t.add
943 */
944 static void add(private_builder_t *this, builder_part_t part, ...)
945 {
946 if (!this->res)
947 {
948 va_list args;
949 chunk_t chunk;
950
951 switch (part)
952 {
953 case BUILD_BLOB_ASN1_DER:
954 {
955 va_start(args, part);
956 chunk = va_arg(args, chunk_t);
957 this->res = load(chunk_clone(chunk));
958 va_end(args);
959 return;
960 }
961 default:
962 break;
963 }
964 }
965 if (this->res)
966 {
967 destroy((private_x509_ocsp_response_t*)this->res);
968 }
969 builder_cancel(&this->public);
970 }
971
972 /**
973 * Builder construction function
974 */
975 builder_t *x509_ocsp_response_builder(certificate_type_t type)
976 {
977 private_builder_t *this;
978
979 if (type != CERT_X509_OCSP_RESPONSE)
980 {
981 return NULL;
982 }
983
984 this = malloc_thing(private_builder_t);
985
986 this->res = NULL;
987 this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
988 this->public.build = (void*(*)(builder_t *this))build;
989
990 return &this->public;
991 }
992