attempt to achieve consistent debugging output
[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 {
685 return FALSE;
686 }
687 if (!sigcheck)
688 {
689 return TRUE;
690 }
691 /* TODO: generic OID to scheme mapper? */
692 switch (this->signatureAlgorithm)
693 {
694 case OID_MD5_WITH_RSA:
695 scheme = SIGN_RSA_EMSA_PKCS1_MD5;
696 break;
697 case OID_SHA1_WITH_RSA:
698 scheme = SIGN_RSA_EMSA_PKCS1_SHA1;
699 break;
700 case OID_SHA256_WITH_RSA:
701 scheme = SIGN_RSA_EMSA_PKCS1_SHA256;
702 break;
703 case OID_SHA384_WITH_RSA:
704 scheme = SIGN_RSA_EMSA_PKCS1_SHA384;
705 break;
706 case OID_SHA512_WITH_RSA:
707 scheme = SIGN_RSA_EMSA_PKCS1_SHA512;
708 break;
709 default:
710 return FALSE;
711 }
712 key = issuer->get_public_key(issuer);
713 if (key == NULL)
714 {
715 return FALSE;
716 }
717 valid = key->verify(key, scheme, this->tbsResponseData, this->signature);
718 key->destroy(key);
719 return valid;
720 }
721
722 /**
723 * Implementation of certificate_t.get_public_key
724 */
725 static public_key_t* get_public_key(private_x509_ocsp_response_t *this)
726 {
727 return NULL;
728 }
729
730 /**
731 * Implementation of certificate_t.get_validity.
732 */
733 static bool get_validity(private_x509_ocsp_response_t *this, time_t *when,
734 time_t *not_before, time_t *not_after)
735 {
736 enumerator_t *enumerator;
737 single_response_t *response;
738 time_t thisUpdate = this->producedAt;
739 time_t nextUpdate = 0;
740 time_t t;
741
742 enumerator = this->responses->create_enumerator(this->responses);
743 if (enumerator->enumerate(enumerator, &response))
744 {
745 thisUpdate = response->thisUpdate;
746 nextUpdate = response->nextUpdate;
747 }
748 enumerator->destroy(enumerator);
749
750 if (when == NULL)
751 {
752 t = time(NULL);
753 }
754 else
755 {
756 t = *when;
757 }
758 if (not_before)
759 {
760 *not_before = thisUpdate;
761 }
762 if (not_after)
763 {
764 *not_after = nextUpdate;
765 }
766 return (t < nextUpdate);
767 }
768
769 /**
770 * Implementation of certificate_t.is_newer.
771 */
772 static bool is_newer(certificate_t *this, certificate_t *that)
773 {
774 time_t this_update, that_update, now = time(NULL);
775 bool new;
776
777 this->get_validity(this, &now, &this_update, NULL);
778 that->get_validity(that, &now, &that_update, NULL);
779 new = this_update > that_update;
780 DBG1(" ocsp response from %#T is %s - existing ocsp response from %#T %s",
781 &this_update, FALSE, new ? "newer":"not newer",
782 &that_update, FALSE, new ? "replaced":"retained");
783 return new;
784 }
785
786 /**
787 * Implementation of certificate_t.get_encoding.
788 */
789 static chunk_t get_encoding(private_x509_ocsp_response_t *this)
790 {
791 return chunk_clone(this->data);
792 }
793
794 /**
795 * Implementation of certificate_t.equals.
796 */
797 static bool equals(private_x509_ocsp_response_t *this, certificate_t *other)
798 {
799 if (this == (private_x509_ocsp_response_t*)other)
800 {
801 return TRUE;
802 }
803 if (other->get_type(other) != CERT_X509_OCSP_RESPONSE)
804 {
805 return FALSE;
806 }
807 /* check if we have the same X509 implementation */
808 if (other->equals == (void*)equals)
809 {
810 return chunk_equals(this->data,
811 ((private_x509_ocsp_response_t*)other)->data);
812 }
813 /* TODO: compare against other implementation */
814 return FALSE;
815 }
816
817 /**
818 * Implementation of certificate_t.get_ref
819 */
820 static private_x509_ocsp_response_t* get_ref(private_x509_ocsp_response_t *this)
821 {
822 ref_get(&this->ref);
823 return this;
824 }
825
826 /**
827 * Implements ocsp_t.destroy.
828 */
829 static void destroy(private_x509_ocsp_response_t *this)
830 {
831 if (ref_put(&this->ref))
832 {
833 this->certs->destroy_offset(this->certs, offsetof(certificate_t, destroy));
834 this->responses->destroy_function(this->responses, free);
835 DESTROY_IF(this->responderId);
836 free(this->data.ptr);
837 free(this);
838 }
839 }
840
841 /**
842 * load an OCSP response
843 */
844 static x509_ocsp_response_t *load(chunk_t data)
845 {
846 private_x509_ocsp_response_t *this;
847
848 this = malloc_thing(private_x509_ocsp_response_t);
849
850 this->public.interface.certificate.get_type = (certificate_type_t (*)(certificate_t *this))get_type;
851 this->public.interface.certificate.get_subject = (identification_t* (*)(certificate_t *this))get_issuer;
852 this->public.interface.certificate.get_issuer = (identification_t* (*)(certificate_t *this))get_issuer;
853 this->public.interface.certificate.has_subject = (id_match_t(*)(certificate_t*, identification_t *subject))has_issuer;
854 this->public.interface.certificate.has_issuer = (id_match_t(*)(certificate_t*, identification_t *issuer))has_issuer;
855 this->public.interface.certificate.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer,bool))issued_by;
856 this->public.interface.certificate.get_public_key = (public_key_t* (*)(certificate_t *this))get_public_key;
857 this->public.interface.certificate.get_validity = (bool(*)(certificate_t*, time_t *when, time_t *, time_t*))get_validity;
858 this->public.interface.certificate.is_newer = (bool (*)(certificate_t*,certificate_t*))is_newer;
859 this->public.interface.certificate.get_encoding = (chunk_t(*)(certificate_t*))get_encoding;
860 this->public.interface.certificate.equals = (bool(*)(certificate_t*, certificate_t *other))equals;
861 this->public.interface.certificate.get_ref = (certificate_t* (*)(certificate_t *this))get_ref;
862 this->public.interface.certificate.destroy = (void (*)(certificate_t *this))destroy;
863 this->public.interface.get_status = (cert_validation_t(*)(ocsp_response_t*, x509_t *subject, x509_t *issuer, time_t *revocation_time,crl_reason_t *revocation_reason,time_t *this_update, time_t *next_update))get_status;
864 this->public.interface.create_cert_enumerator = (enumerator_t*(*)(ocsp_response_t*))create_cert_enumerator;
865
866 this->ref = 1;
867 this->data = data;
868 this->tbsResponseData = chunk_empty;
869 this->responderId = NULL;
870 this->producedAt = UNDEFINED_TIME;
871 this->responses = linked_list_create();
872 this->nonce = chunk_empty;
873 this->signatureAlgorithm = OID_UNKNOWN;
874 this->signature = chunk_empty;
875 this->certs = linked_list_create();
876
877 if (!parse_OCSPResponse(this))
878 {
879 destroy(this);
880 return NULL;
881 }
882 return &this->public;
883 }
884
885
886 typedef struct private_builder_t private_builder_t;
887 /**
888 * Builder implementation for certificate loading
889 */
890 struct private_builder_t {
891 /** implements the builder interface */
892 builder_t public;
893 /** loaded response */
894 x509_ocsp_response_t *res;
895 };
896
897 /**
898 * Implementation of builder_t.build
899 */
900 static x509_ocsp_response_t *build(private_builder_t *this)
901 {
902 x509_ocsp_response_t *res = this->res;
903
904 free(this);
905 return res;
906 }
907
908 /**
909 * Implementation of builder_t.add
910 */
911 static void add(private_builder_t *this, builder_part_t part, ...)
912 {
913 va_list args;
914
915 if (this->res)
916 {
917 DBG1("ignoring surplus build part %N", builder_part_names, part);
918 return;
919 }
920
921 switch (part)
922 {
923 case BUILD_BLOB_ASN1_DER:
924 {
925 va_start(args, part);
926 this->res = load(va_arg(args, chunk_t));
927 va_end(args);
928 break;
929 }
930 default:
931 DBG1("ignoring unsupported build part %N", builder_part_names, part);
932 break;
933 }
934 }
935
936 /**
937 * Builder construction function
938 */
939 builder_t *x509_ocsp_response_builder(certificate_type_t type)
940 {
941 private_builder_t *this;
942
943 if (type != CERT_X509_OCSP_RESPONSE)
944 {
945 return NULL;
946 }
947
948 this = malloc_thing(private_builder_t);
949
950 this->res = NULL;
951 this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
952 this->public.build = (void*(*)(builder_t *this))build;
953
954 return &this->public;
955 }
956