support of PKCS#10 certificate request parsing
[strongswan.git] / src / libstrongswan / plugins / x509 / x509_pkcs10.c
1 /*
2 * Copyright (C) 2005 Jan Hutter, Martin Willi
3 * Copyright (C) 2009 Andreas Steffen
4 *
5 * HSR Hochschule fuer Technik Rapperswil
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_pkcs10.h"
19
20 #include <library.h>
21 #include <debug.h>
22 #include <asn1/oid.h>
23 #include <asn1/asn1.h>
24 #include <asn1/asn1_parser.h>
25 #include <credentials/keys/private_key.h>
26 #include <utils/linked_list.h>
27 #include <utils/identification.h>
28
29 typedef struct private_x509_pkcs10_t private_x509_pkcs10_t;
30
31 /**
32 * Private data of a x509_pkcs10_t object.
33 */
34 struct private_x509_pkcs10_t {
35 /**
36 * Public interface for this certificate.
37 */
38 x509_pkcs10_t public;
39
40 /**
41 * PKCS#10 certificate request encoding in ASN.1 DER format
42 */
43 chunk_t encoding;
44
45 /**
46 * PKCS#10 request body over which signature is computed
47 */
48 chunk_t certificationRequestInfo;
49
50 /**
51 * Version of the PKCS#10 certificate request
52 */
53 u_int version;
54
55 /**
56 * ID representing the certificate subject
57 */
58 identification_t *subject;
59
60 /**
61 * List of subjectAltNames as identification_t
62 */
63 linked_list_t *subjectAltNames;
64
65 /**
66 * certificate's embedded public key
67 */
68 public_key_t *public_key;
69
70 /**
71 * challenge password
72 */
73 chunk_t challengePassword;
74
75 /**
76 * Signature algorithm
77 */
78 int algorithm;
79
80 /**
81 * Signature
82 */
83 chunk_t signature;
84
85 /**
86 * Is the certificate request self-signed?
87 */
88 bool self_signed;
89
90 /**
91 * Certificate request parsed from blob/file?
92 */
93 bool parsed;
94
95 /**
96 * reference count
97 */
98 refcount_t ref;
99 };
100
101 /**
102 * Implementation of certificate_t.get_type.
103 */
104 static certificate_type_t get_type(private_x509_pkcs10_t *this)
105 {
106 return CERT_PKCS10_REQUEST;
107 }
108
109 /**
110 * Implementation of certificate_t.get_subject and get_issuer.
111 */
112 static identification_t* get_subject(private_x509_pkcs10_t *this)
113 {
114 return this->subject;
115 }
116
117 /**
118 * Implementation of certificate_t.has_subject and has_issuer.
119 */
120 static id_match_t has_subject(private_x509_pkcs10_t *this, identification_t *subject)
121 {
122 return this->subject->matches(this->subject, subject);
123 }
124
125 /**
126 * Implementation of certificate_t.issued_by.
127 */
128 static bool issued_by(private_x509_pkcs10_t *this, certificate_t *issuer)
129 {
130 public_key_t *key;
131 signature_scheme_t scheme;
132
133 if (&this->public.interface.interface != issuer)
134 {
135 return FALSE;
136 }
137 if (this->self_signed)
138 {
139 return TRUE;
140 }
141
142 /* determine signature scheme */
143 scheme = signature_scheme_from_oid(this->algorithm);
144 if (scheme == SIGN_UNKNOWN)
145 {
146 return FALSE;
147 }
148
149 /* get the public key contained in the certificate request */
150 key = this->public_key;
151 if (!key)
152 {
153 return FALSE;
154 }
155 return key->verify(key, scheme, this->certificationRequestInfo,
156 this->signature);
157 }
158
159 /**
160 * Implementation of certificate_t.get_public_key.
161 */
162 static public_key_t* get_public_key(private_x509_pkcs10_t *this)
163 {
164 this->public_key->get_ref(this->public_key);
165 return this->public_key;
166 }
167
168 /**
169 * Implementation of certificate_t.get_validity.
170 */
171 static bool get_validity(private_x509_pkcs10_t *this, time_t *when,
172 time_t *not_before, time_t *not_after)
173 {
174 if (not_before)
175 {
176 *not_before = 0;
177 }
178 if (not_after)
179 {
180 *not_after = ~0;
181 }
182 return TRUE;
183 }
184
185 /**
186 * Implementation of certificate_t.is_newer.
187 */
188 static bool is_newer(certificate_t *this, certificate_t *that)
189 {
190 return FALSE;
191 }
192
193 /**
194 * Implementation of certificate_t.get_encoding.
195 */
196 static chunk_t get_encoding(private_x509_pkcs10_t *this)
197 {
198 return chunk_clone(this->encoding);
199 }
200
201 /**
202 * Implementation of certificate_t.equals.
203 */
204 static bool equals(private_x509_pkcs10_t *this, certificate_t *other)
205 {
206 chunk_t encoding;
207 bool equal;
208
209 if (this == (private_x509_pkcs10_t*)other)
210 {
211 return TRUE;
212 }
213 if (other->get_type(other) != CERT_PKCS10_REQUEST)
214 {
215 return FALSE;
216 }
217 if (other->equals == (void*)equals)
218 { /* skip allocation if we have the same implementation */
219 return chunk_equals(this->encoding, ((private_x509_pkcs10_t*)other)->encoding);
220 }
221 encoding = other->get_encoding(other);
222 equal = chunk_equals(this->encoding, encoding);
223 free(encoding.ptr);
224 return equal;
225 }
226
227 /**
228 * Implementation of certificate_t.get_ref
229 */
230 static private_x509_pkcs10_t* get_ref(private_x509_pkcs10_t *this)
231 {
232 ref_get(&this->ref);
233 return this;
234 }
235
236 /**
237 * Implementation of certificate_t.get_challengePassword.
238 */
239 static chunk_t get_challengePassword(private_x509_pkcs10_t *this)
240 {
241 return this->challengePassword;
242 }
243
244 /**
245 * Implementation of pkcs10_t.create_subjectAltName_enumerator.
246 */
247 static enumerator_t* create_subjectAltName_enumerator(private_x509_pkcs10_t *this)
248 {
249 return this->subjectAltNames->create_enumerator(this->subjectAltNames);
250 }
251
252 /**
253 * Imported from x509_cert.c
254 */
255 extern void x509_parse_generalNames(chunk_t blob, int level0, bool implicit, linked_list_t *list);
256
257 /**
258 * ASN.1 definition of a PKCS#10 extension request
259 */
260 static const asn1Object_t extensionRequestObjects[] = {
261 { 0, "extensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
262 { 1, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
263 { 2, "extnID", ASN1_OID, ASN1_BODY }, /* 2 */
264 { 2, "critical", ASN1_BOOLEAN, ASN1_DEF|ASN1_BODY }, /* 3 */
265 { 2, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 4 */
266 { 1, "end loop", ASN1_EOC, ASN1_END }, /* 5 */
267 { 0, "exit", ASN1_EOC, ASN1_EXIT }
268 };
269 #define PKCS10_EXTN_ID 2
270 #define PKCS10_EXTN_CRITICAL 3
271 #define PKCS10_EXTN_VALUE 4
272
273 /**
274 * Parses a PKCS#10 extension request
275 */
276 static bool parse_extension_request(private_x509_pkcs10_t *this, chunk_t blob, int level0)
277 {
278 asn1_parser_t *parser;
279 chunk_t object;
280 int objectID;
281 int extn_oid = OID_UNKNOWN;
282 bool success = FALSE;
283 bool critical;
284
285 parser = asn1_parser_create(extensionRequestObjects, blob);
286 parser->set_top_level(parser, level0);
287
288 while (parser->iterate(parser, &objectID, &object))
289 {
290 u_int level = parser->get_level(parser)+1;
291
292 switch (objectID)
293 {
294 case PKCS10_EXTN_ID:
295 extn_oid = asn1_known_oid(object);
296 break;
297 case PKCS10_EXTN_CRITICAL:
298 critical = object.len && *object.ptr;
299 DBG2(" %s", critical ? "TRUE" : "FALSE");
300 break;
301 case PKCS10_EXTN_VALUE:
302 {
303 switch (extn_oid)
304 {
305 case OID_SUBJECT_ALT_NAME:
306 x509_parse_generalNames(object, level, FALSE,
307 this->subjectAltNames);
308 break;
309 default:
310 break;
311 }
312 break;
313 }
314 default:
315 break;
316 }
317 }
318 success = parser->success(parser);
319 parser->destroy(parser);
320 return success;
321 }
322
323 /**
324 * Parses a PKCS#10 challenge password
325 */
326 static bool parse_challengePassword(private_x509_pkcs10_t *this, chunk_t blob, int level)
327 {
328 char tag;
329
330 if (blob.len < 2)
331 {
332 DBG1("L%d - challengePassword: ASN.1 object smaller than 2 octets",
333 level);
334 return FALSE;
335 }
336 tag = *blob.ptr;
337 if (tag < ASN1_UTF8STRING || tag > ASN1_IA5STRING)
338 {
339 DBG1("L%d - challengePassword: ASN.1 object is not a character string",
340 level);
341 return FALSE;
342 }
343 if (asn1_length(&blob) == ASN1_INVALID_LENGTH)
344 {
345 DBG1("L%d - challengePassword: ASN.1 object has an invalid length",
346 level);
347 return FALSE;
348 }
349 DBG2("L%d - challengePassword:", level);
350 DBG4(" '%.*s'", blob.len, blob.ptr);
351 return TRUE;
352 }
353
354 /**
355 * ASN.1 definition of a PKCS#10 certificate request
356 */
357 static const asn1Object_t certificationRequestObjects[] = {
358 { 0, "certificationRequest", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
359 { 1, "certificationRequestInfo", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
360 { 2, "version", ASN1_INTEGER, ASN1_RAW }, /* 2 */
361 { 2, "subject", ASN1_SEQUENCE, ASN1_OBJ }, /* 3 */
362 { 2, "subjectPublicKeyInfo", ASN1_SEQUENCE, ASN1_RAW }, /* 4 */
363 { 2, "attributes", ASN1_CONTEXT_C_0, ASN1_LOOP }, /* 5 */
364 { 3, "attribute", ASN1_SEQUENCE, ASN1_NONE }, /* 6 */
365 { 4, "type", ASN1_OID, ASN1_BODY }, /* 7 */
366 { 4, "values", ASN1_SET, ASN1_LOOP }, /* 8 */
367 { 5, "value", ASN1_EOC, ASN1_RAW }, /* 9 */
368 { 4, "end loop", ASN1_EOC, ASN1_END }, /* 10 */
369 { 2, "end loop", ASN1_EOC, ASN1_END }, /* 11 */
370 { 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 12 */
371 { 1, "signature", ASN1_BIT_STRING, ASN1_BODY }, /* 13 */
372 { 0, "exit", ASN1_EOC, ASN1_EXIT }
373 };
374 #define PKCS10_CERT_REQUEST_INFO 1
375 #define PKCS10_VERSION 2
376 #define PKCS10_SUBJECT 3
377 #define PKCS10_SUBJECT_PUBLIC_KEY_INFO 4
378 #define PKCS10_ATTR_TYPE 7
379 #define PKCS10_ATTR_VALUE 9
380 #define PKCS10_ALGORITHM 12
381 #define PKCS10_SIGNATURE 13
382
383 /**
384 * Parses a PKCS#10 certificate request
385 */
386 static bool parse_certificate_request(private_x509_pkcs10_t *this)
387 {
388 asn1_parser_t *parser;
389 chunk_t object;
390 int objectID;
391 int attr_oid = OID_UNKNOWN;
392 bool success = FALSE;
393
394 parser = asn1_parser_create(certificationRequestObjects, this->encoding);
395
396 while (parser->iterate(parser, &objectID, &object))
397 {
398 u_int level = parser->get_level(parser)+1;
399
400 switch (objectID)
401 {
402 case PKCS10_CERT_REQUEST_INFO:
403 this->certificationRequestInfo = object;
404 break;
405 case PKCS10_VERSION:
406 this->version = (object.len) ? (1+(u_int)*object.ptr) : 1;
407 DBG2(" v%d", this->version);
408 break;
409 break;
410 case PKCS10_SUBJECT:
411 this->subject = identification_create_from_encoding(ID_DER_ASN1_DN, object);
412 DBG2(" '%Y'", this->subject);
413 break;
414 case PKCS10_SUBJECT_PUBLIC_KEY_INFO:
415 this->public_key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY,
416 KEY_ANY, BUILD_BLOB_ASN1_DER, object, BUILD_END);
417 if (this->public_key == NULL)
418 {
419 goto end;
420 }
421 break;
422 case PKCS10_ATTR_TYPE:
423 attr_oid = asn1_known_oid(object);
424 break;
425 case PKCS10_ATTR_VALUE:
426 switch (attr_oid)
427 {
428 case OID_EXTENSION_REQUEST:
429 if (!parse_extension_request(this, object, level))
430 {
431 goto end;
432 }
433 break;
434 case OID_CHALLENGE_PASSWORD:
435 if (!parse_challengePassword(this, object, level))
436 {
437 goto end;
438 }
439 break;
440 default:
441 break;
442 }
443 break;
444 case PKCS10_ALGORITHM:
445 this->algorithm = asn1_parse_algorithmIdentifier(object, level, NULL);
446 break;
447 case PKCS10_SIGNATURE:
448 this->signature = object;
449 break;
450 default:
451 break;
452 }
453 }
454 success = parser->success(parser);
455
456 end:
457 parser->destroy(parser);
458 if (success)
459 {
460 /* check if the certificate request is self-signed */
461 if (issued_by(this, &this->public.interface.interface))
462 {
463 this->self_signed = TRUE;
464 }
465 else
466 {
467 DBG1("certificate request is not self-signed");
468 success = FALSE;
469 }
470 }
471 return success;
472 }
473
474 /**
475 * Implementation of certificate_t.destroy
476 */
477 static void destroy(private_x509_pkcs10_t *this)
478 {
479 if (ref_put(&this->ref))
480 {
481 this->subjectAltNames->destroy_offset(this->subjectAltNames,
482 offsetof(identification_t, destroy));
483 DESTROY_IF(this->subject);
484 DESTROY_IF(this->public_key);
485 chunk_free(&this->encoding);
486 if (!this->parsed)
487 { /* only parsed certificate requests point these fields to "encoded" */
488 chunk_free(&this->certificationRequestInfo);
489 chunk_free(&this->challengePassword);
490 chunk_free(&this->signature);
491 }
492 free(this);
493 }
494 }
495
496 /**
497 * create an empty but initialized PKCS#10 certificate request
498 */
499 static private_x509_pkcs10_t* create_empty(void)
500 {
501 private_x509_pkcs10_t *this = malloc_thing(private_x509_pkcs10_t);
502
503 this->public.interface.interface.get_type = (certificate_type_t (*) (certificate_t*))get_type;
504 this->public.interface.interface.get_subject = (identification_t* (*) (certificate_t*))get_subject;
505 this->public.interface.interface.get_issuer = (identification_t* (*) (certificate_t*))get_subject;
506 this->public.interface.interface.has_subject = (id_match_t (*) (certificate_t*, identification_t*))has_subject;
507 this->public.interface.interface.has_issuer = (id_match_t (*) (certificate_t*, identification_t*))has_subject;
508 this->public.interface.interface.issued_by = (bool (*) (certificate_t*, certificate_t*))issued_by;
509 this->public.interface.interface.get_public_key = (public_key_t* (*) (certificate_t*))get_public_key;
510 this->public.interface.interface.get_validity = (bool (*) (certificate_t*, time_t*, time_t*, time_t*))get_validity;
511 this->public.interface.interface.is_newer = (bool (*) (certificate_t*,certificate_t*))is_newer;
512 this->public.interface.interface.get_encoding = (chunk_t (*) (certificate_t*))get_encoding;
513 this->public.interface.interface.equals = (bool (*)(certificate_t*, certificate_t*))equals;
514 this->public.interface.interface.get_ref = (certificate_t* (*)(certificate_t*))get_ref;
515 this->public.interface.interface.destroy = (void (*)(certificate_t*))destroy;
516 this->public.interface.get_challengePassword = (chunk_t (*)(pkcs10_t*))get_challengePassword;
517 this->public.interface.create_subjectAltName_enumerator = (enumerator_t* (*)(pkcs10_t*))create_subjectAltName_enumerator;
518
519 this->encoding = chunk_empty;
520 this->certificationRequestInfo = chunk_empty;
521 this->subject = NULL;
522 this->public_key = NULL;
523 this->subjectAltNames = linked_list_create();
524 this->challengePassword = chunk_empty;
525 this->signature = chunk_empty;
526 this->ref = 1;
527 this->self_signed = FALSE;
528 this->parsed = FALSE;
529
530 return this;
531 }
532
533 /**
534 * Generate and sign a new certificate
535 */
536 static bool generate(private_x509_pkcs10_t *cert, private_key_t *sign_key,
537 int digest_alg)
538 {
539 /* TODO */
540 return TRUE;
541 }
542
543 /**
544 * See header.
545 */
546 x509_pkcs10_t *x509_pkcs10_load(certificate_type_t type, va_list args)
547 {
548 chunk_t blob = chunk_empty;
549
550 while (TRUE)
551 {
552 switch (va_arg(args, builder_part_t))
553 {
554 case BUILD_BLOB_ASN1_DER:
555 blob = va_arg(args, chunk_t);
556 continue;
557 case BUILD_END:
558 break;
559 default:
560 return NULL;
561 }
562 break;
563 }
564
565 if (blob.ptr)
566 {
567 private_x509_pkcs10_t *cert = create_empty();
568
569 cert->encoding = chunk_clone(blob);
570 cert->parsed = TRUE;
571 if (parse_certificate_request(cert))
572 {
573 return &cert->public;
574 }
575 destroy(cert);
576 }
577 return NULL;
578 }
579
580 /**
581 * See header.
582 */
583 x509_pkcs10_t *x509_pkcs10_gen(certificate_type_t type, va_list args)
584 {
585 private_x509_pkcs10_t *cert;
586 private_key_t *sign_key = NULL;
587 hash_algorithm_t digest_alg = HASH_SHA1;
588
589 cert = create_empty();
590 while (TRUE)
591 {
592 switch (va_arg(args, builder_part_t))
593 {
594 case BUILD_SIGNING_KEY:
595 sign_key = va_arg(args, private_key_t*);
596 continue;
597 case BUILD_PUBLIC_KEY:
598 cert->public_key = va_arg(args, public_key_t*);
599 cert->public_key->get_ref(cert->public_key);
600 continue;
601 case BUILD_SUBJECT:
602 cert->subject = va_arg(args, identification_t*);
603 cert->subject = cert->subject->clone(cert->subject);
604 continue;
605 case BUILD_SUBJECT_ALTNAMES:
606 {
607 enumerator_t *enumerator;
608 identification_t *id;
609 linked_list_t *list;
610
611 list = va_arg(args, linked_list_t*);
612 enumerator = list->create_enumerator(list);
613 while (enumerator->enumerate(enumerator, &id))
614 {
615 cert->subjectAltNames->insert_last(
616 cert->subjectAltNames, id->clone(id));
617 }
618 enumerator->destroy(enumerator);
619 continue;
620 }
621 case BUILD_DIGEST_ALG:
622 digest_alg = va_arg(args, int);
623 continue;
624 case BUILD_END:
625 break;
626 default:
627 destroy(cert);
628 return NULL;
629 }
630 break;
631 }
632
633 if (sign_key && generate(cert, sign_key, digest_alg))
634 {
635 return &cert->public;
636 }
637 destroy(cert);
638 return NULL;
639 }
640