check if PKCS#10 version is 1
[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_BODY }, /* 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 if (object.len > 0 && *object.ptr != 0)
407 {
408 DBG1("PKCS#10 certificate request format is not version 1");
409 goto end;
410 }
411 break;
412 case PKCS10_SUBJECT:
413 this->subject = identification_create_from_encoding(ID_DER_ASN1_DN, object);
414 DBG2(" '%Y'", this->subject);
415 break;
416 case PKCS10_SUBJECT_PUBLIC_KEY_INFO:
417 this->public_key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY,
418 KEY_ANY, BUILD_BLOB_ASN1_DER, object, BUILD_END);
419 if (this->public_key == NULL)
420 {
421 goto end;
422 }
423 break;
424 case PKCS10_ATTR_TYPE:
425 attr_oid = asn1_known_oid(object);
426 break;
427 case PKCS10_ATTR_VALUE:
428 switch (attr_oid)
429 {
430 case OID_EXTENSION_REQUEST:
431 if (!parse_extension_request(this, object, level))
432 {
433 goto end;
434 }
435 break;
436 case OID_CHALLENGE_PASSWORD:
437 if (!parse_challengePassword(this, object, level))
438 {
439 goto end;
440 }
441 break;
442 default:
443 break;
444 }
445 break;
446 case PKCS10_ALGORITHM:
447 this->algorithm = asn1_parse_algorithmIdentifier(object, level, NULL);
448 break;
449 case PKCS10_SIGNATURE:
450 this->signature = object;
451 break;
452 default:
453 break;
454 }
455 }
456 success = parser->success(parser);
457
458 end:
459 parser->destroy(parser);
460 if (success)
461 {
462 /* check if the certificate request is self-signed */
463 if (issued_by(this, &this->public.interface.interface))
464 {
465 this->self_signed = TRUE;
466 }
467 else
468 {
469 DBG1("certificate request is not self-signed");
470 success = FALSE;
471 }
472 }
473 return success;
474 }
475
476 /**
477 * Implementation of certificate_t.destroy
478 */
479 static void destroy(private_x509_pkcs10_t *this)
480 {
481 if (ref_put(&this->ref))
482 {
483 this->subjectAltNames->destroy_offset(this->subjectAltNames,
484 offsetof(identification_t, destroy));
485 DESTROY_IF(this->subject);
486 DESTROY_IF(this->public_key);
487 chunk_free(&this->encoding);
488 if (!this->parsed)
489 { /* only parsed certificate requests point these fields to "encoded" */
490 chunk_free(&this->certificationRequestInfo);
491 chunk_free(&this->challengePassword);
492 chunk_free(&this->signature);
493 }
494 free(this);
495 }
496 }
497
498 /**
499 * create an empty but initialized PKCS#10 certificate request
500 */
501 static private_x509_pkcs10_t* create_empty(void)
502 {
503 private_x509_pkcs10_t *this = malloc_thing(private_x509_pkcs10_t);
504
505 this->public.interface.interface.get_type = (certificate_type_t (*) (certificate_t*))get_type;
506 this->public.interface.interface.get_subject = (identification_t* (*) (certificate_t*))get_subject;
507 this->public.interface.interface.get_issuer = (identification_t* (*) (certificate_t*))get_subject;
508 this->public.interface.interface.has_subject = (id_match_t (*) (certificate_t*, identification_t*))has_subject;
509 this->public.interface.interface.has_issuer = (id_match_t (*) (certificate_t*, identification_t*))has_subject;
510 this->public.interface.interface.issued_by = (bool (*) (certificate_t*, certificate_t*))issued_by;
511 this->public.interface.interface.get_public_key = (public_key_t* (*) (certificate_t*))get_public_key;
512 this->public.interface.interface.get_validity = (bool (*) (certificate_t*, time_t*, time_t*, time_t*))get_validity;
513 this->public.interface.interface.is_newer = (bool (*) (certificate_t*,certificate_t*))is_newer;
514 this->public.interface.interface.get_encoding = (chunk_t (*) (certificate_t*))get_encoding;
515 this->public.interface.interface.equals = (bool (*)(certificate_t*, certificate_t*))equals;
516 this->public.interface.interface.get_ref = (certificate_t* (*)(certificate_t*))get_ref;
517 this->public.interface.interface.destroy = (void (*)(certificate_t*))destroy;
518 this->public.interface.get_challengePassword = (chunk_t (*)(pkcs10_t*))get_challengePassword;
519 this->public.interface.create_subjectAltName_enumerator = (enumerator_t* (*)(pkcs10_t*))create_subjectAltName_enumerator;
520
521 this->encoding = chunk_empty;
522 this->certificationRequestInfo = chunk_empty;
523 this->subject = NULL;
524 this->public_key = NULL;
525 this->subjectAltNames = linked_list_create();
526 this->challengePassword = chunk_empty;
527 this->signature = chunk_empty;
528 this->ref = 1;
529 this->self_signed = FALSE;
530 this->parsed = FALSE;
531
532 return this;
533 }
534
535 /**
536 * Generate and sign a new certificate request
537 */
538 static bool generate(private_x509_pkcs10_t *cert, private_key_t *sign_key,
539 int digest_alg)
540 {
541 chunk_t attributes = chunk_empty;
542 chunk_t key_info;
543 signature_scheme_t scheme;
544 identification_t *subject;
545
546 subject = cert->subject;
547 cert->public_key = sign_key->get_public_key(sign_key);
548
549 /* select signature scheme */
550 cert->algorithm = hasher_signature_algorithm_to_oid(digest_alg,
551 sign_key->get_type(sign_key));
552 if (cert->algorithm == OID_UNKNOWN)
553 {
554 return FALSE;
555 }
556 scheme = signature_scheme_from_oid(cert->algorithm);
557
558 if (!cert->public_key->get_encoding(cert->public_key,
559 KEY_PUB_SPKI_ASN1_DER, &key_info))
560 {
561 return FALSE;
562 }
563
564 cert->certificationRequestInfo = asn1_wrap(ASN1_SEQUENCE, "ccmm",
565 ASN1_INTEGER_0,
566 subject->get_encoding(subject),
567 key_info,
568 asn1_wrap(ASN1_CONTEXT_C_0, "m", attributes));
569
570 if (!sign_key->sign(sign_key, scheme, cert->certificationRequestInfo,
571 &cert->signature))
572 {
573 return FALSE;
574 }
575
576 cert->encoding = asn1_wrap(ASN1_SEQUENCE, "cmm",
577 cert->certificationRequestInfo,
578 asn1_algorithmIdentifier(cert->algorithm),
579 asn1_bitstring("c", cert->signature));
580 return TRUE;
581 }
582
583 /**
584 * See header.
585 */
586 x509_pkcs10_t *x509_pkcs10_load(certificate_type_t type, va_list args)
587 {
588 chunk_t blob = chunk_empty;
589
590 while (TRUE)
591 {
592 switch (va_arg(args, builder_part_t))
593 {
594 case BUILD_BLOB_ASN1_DER:
595 blob = va_arg(args, chunk_t);
596 continue;
597 case BUILD_END:
598 break;
599 default:
600 return NULL;
601 }
602 break;
603 }
604
605 if (blob.ptr)
606 {
607 private_x509_pkcs10_t *cert = create_empty();
608
609 cert->encoding = chunk_clone(blob);
610 cert->parsed = TRUE;
611 if (parse_certificate_request(cert))
612 {
613 return &cert->public;
614 }
615 destroy(cert);
616 }
617 return NULL;
618 }
619
620 /**
621 * See header.
622 */
623 x509_pkcs10_t *x509_pkcs10_gen(certificate_type_t type, va_list args)
624 {
625 private_x509_pkcs10_t *cert;
626 private_key_t *sign_key = NULL;
627 hash_algorithm_t digest_alg = HASH_SHA1;
628
629 cert = create_empty();
630 while (TRUE)
631 {
632 switch (va_arg(args, builder_part_t))
633 {
634 case BUILD_SIGNING_KEY:
635 sign_key = va_arg(args, private_key_t*);
636 continue;
637 case BUILD_SUBJECT:
638 cert->subject = va_arg(args, identification_t*);
639 cert->subject = cert->subject->clone(cert->subject);
640 continue;
641 case BUILD_SUBJECT_ALTNAMES:
642 {
643 enumerator_t *enumerator;
644 identification_t *id;
645 linked_list_t *list;
646
647 list = va_arg(args, linked_list_t*);
648 enumerator = list->create_enumerator(list);
649 while (enumerator->enumerate(enumerator, &id))
650 {
651 cert->subjectAltNames->insert_last(
652 cert->subjectAltNames, id->clone(id));
653 }
654 enumerator->destroy(enumerator);
655 continue;
656 }
657 case BUILD_DIGEST_ALG:
658 digest_alg = va_arg(args, int);
659 continue;
660 case BUILD_END:
661 break;
662 default:
663 destroy(cert);
664 return NULL;
665 }
666 break;
667 }
668
669 if (sign_key && generate(cert, sign_key, digest_alg))
670 {
671 return &cert->public;
672 }
673 destroy(cert);
674 return NULL;
675 }
676