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