The introduced SHA1_NOFINAL hasher was not sufficient for EAP-AKA,
[strongswan.git] / src / libstrongswan / crypto / pkcs7.c
1 /*
2 * Copyright (C) 2005 Jan Hutter, Martin Willi
3 * Copyright (C) 2002-2008 Andreas Steffen
4 *
5 * Hochschule fuer Technik Rapperswil, Switzerland
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 <stdlib.h>
21 #include <string.h>
22
23 #include <library.h>
24 #include "debug.h"
25
26 #include <asn1/asn1.h>
27 #include <asn1/oid.h>
28 #include <crypto/x509.h>
29 #include <crypto/pkcs9.h>
30 #include <crypto/hashers/hasher.h>
31 #include <crypto/crypters/crypter.h>
32 #include <crypto/rsa/rsa_public_key.h>
33 #include <utils/randomizer.h>
34 #include <utils/linked_list.h>
35
36 #include "pkcs7.h"
37
38 typedef struct private_pkcs7_t private_pkcs7_t;
39
40 /**
41 * Private data of a pkcs7_t object.
42 */
43 struct private_pkcs7_t {
44 /**
45 * Public interface for this certificate.
46 */
47 pkcs7_t public;
48
49 /**
50 * contentInfo type
51 */
52 int type;
53
54 /**
55 * ASN.1 encoded content
56 */
57 chunk_t content;
58
59 /**
60 * Has the content already been parsed?
61 */
62 bool parsed;
63
64 /**
65 * ASN.1 parsing start level
66 */
67 u_int level;
68
69 /**
70 * retrieved data
71 */
72 chunk_t data;
73
74 /**
75 * ASN.1 encoded attributes
76 */
77 pkcs9_t *attributes;
78
79 /**
80 * Linked list of X.509 certificates
81 */
82 linked_list_t *certs;
83 };
84
85 /**
86 * ASN.1 definition of the PKCS#7 ContentInfo type
87 */
88 static const asn1Object_t contentInfoObjects[] = {
89 { 0, "contentInfo", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
90 { 1, "contentType", ASN1_OID, ASN1_BODY }, /* 1 */
91 { 1, "content", ASN1_CONTEXT_C_0, ASN1_OPT |
92 ASN1_BODY }, /* 2 */
93 { 1, "end opt", ASN1_EOC, ASN1_END } /* 3 */
94 };
95
96 #define PKCS7_INFO_TYPE 1
97 #define PKCS7_INFO_CONTENT 2
98 #define PKCS7_INFO_ROOF 4
99
100 /**
101 * ASN.1 definition of the PKCS#7 signedData type
102 */
103 static const asn1Object_t signedDataObjects[] = {
104 { 0, "signedData", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
105 { 1, "version", ASN1_INTEGER, ASN1_BODY }, /* 1 */
106 { 1, "digestAlgorithms", ASN1_SET, ASN1_LOOP }, /* 2 */
107 { 2, "algorithm", ASN1_EOC, ASN1_RAW }, /* 3 */
108 { 1, "end loop", ASN1_EOC, ASN1_END }, /* 4 */
109 { 1, "contentInfo", ASN1_EOC, ASN1_RAW }, /* 5 */
110 { 1, "certificates", ASN1_CONTEXT_C_0, ASN1_OPT |
111 ASN1_LOOP }, /* 6 */
112 { 2, "certificate", ASN1_SEQUENCE, ASN1_OBJ }, /* 7 */
113 { 1, "end opt or loop", ASN1_EOC, ASN1_END }, /* 8 */
114 { 1, "crls", ASN1_CONTEXT_C_1, ASN1_OPT |
115 ASN1_LOOP }, /* 9 */
116 { 2, "crl", ASN1_SEQUENCE, ASN1_OBJ }, /* 10 */
117 { 1, "end opt or loop", ASN1_EOC, ASN1_END }, /* 11 */
118 { 1, "signerInfos", ASN1_SET, ASN1_LOOP }, /* 12 */
119 { 2, "signerInfo", ASN1_SEQUENCE, ASN1_NONE }, /* 13 */
120 { 3, "version", ASN1_INTEGER, ASN1_BODY }, /* 14 */
121 { 3, "issuerAndSerialNumber", ASN1_SEQUENCE, ASN1_BODY }, /* 15 */
122 { 4, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 16 */
123 { 4, "serial", ASN1_INTEGER, ASN1_BODY }, /* 17 */
124 { 3, "digestAlgorithm", ASN1_EOC, ASN1_RAW }, /* 18 */
125 { 3, "authenticatedAttributes", ASN1_CONTEXT_C_0, ASN1_OPT |
126 ASN1_OBJ }, /* 19 */
127 { 3, "end opt", ASN1_EOC, ASN1_END }, /* 20 */
128 { 3, "digestEncryptionAlgorithm", ASN1_EOC, ASN1_RAW }, /* 21 */
129 { 3, "encryptedDigest", ASN1_OCTET_STRING, ASN1_BODY }, /* 22 */
130 { 3, "unauthenticatedAttributes", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 23 */
131 { 3, "end opt", ASN1_EOC, ASN1_END }, /* 24 */
132 { 1, "end loop", ASN1_EOC, ASN1_END } /* 25 */
133 };
134
135 #define PKCS7_DIGEST_ALG 3
136 #define PKCS7_SIGNED_CONTENT_INFO 5
137 #define PKCS7_SIGNED_CERT 7
138 #define PKCS7_SIGNER_INFO 13
139 #define PKCS7_SIGNED_ISSUER 16
140 #define PKCS7_SIGNED_SERIAL_NUMBER 17
141 #define PKCS7_DIGEST_ALGORITHM 18
142 #define PKCS7_AUTH_ATTRIBUTES 19
143 #define PKCS7_DIGEST_ENC_ALGORITHM 21
144 #define PKCS7_ENCRYPTED_DIGEST 22
145 #define PKCS7_SIGNED_ROOF 26
146
147 /**
148 * ASN.1 definition of the PKCS#7 envelopedData type
149 */
150 static const asn1Object_t envelopedDataObjects[] = {
151 { 0, "envelopedData", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
152 { 1, "version", ASN1_INTEGER, ASN1_BODY }, /* 1 */
153 { 1, "recipientInfos", ASN1_SET, ASN1_LOOP }, /* 2 */
154 { 2, "recipientInfo", ASN1_SEQUENCE, ASN1_BODY }, /* 3 */
155 { 3, "version", ASN1_INTEGER, ASN1_BODY }, /* 4 */
156 { 3, "issuerAndSerialNumber", ASN1_SEQUENCE, ASN1_BODY }, /* 5 */
157 { 4, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 6 */
158 { 4, "serial", ASN1_INTEGER, ASN1_BODY }, /* 7 */
159 { 3, "encryptionAlgorithm", ASN1_EOC, ASN1_RAW }, /* 8 */
160 { 3, "encryptedKey", ASN1_OCTET_STRING, ASN1_BODY }, /* 9 */
161 { 1, "end loop", ASN1_EOC, ASN1_END }, /* 10 */
162 { 1, "encryptedContentInfo", ASN1_SEQUENCE, ASN1_OBJ }, /* 11 */
163 { 2, "contentType", ASN1_OID, ASN1_BODY }, /* 12 */
164 { 2, "contentEncryptionAlgorithm", ASN1_EOC, ASN1_RAW }, /* 13 */
165 { 2, "encryptedContent", ASN1_CONTEXT_S_0, ASN1_BODY } /* 14 */
166 };
167
168 #define PKCS7_ENVELOPED_VERSION 1
169 #define PKCS7_RECIPIENT_INFO_VERSION 4
170 #define PKCS7_ISSUER 6
171 #define PKCS7_SERIAL_NUMBER 7
172 #define PKCS7_ENCRYPTION_ALG 8
173 #define PKCS7_ENCRYPTED_KEY 9
174 #define PKCS7_CONTENT_TYPE 12
175 #define PKCS7_CONTENT_ENC_ALGORITHM 13
176 #define PKCS7_ENCRYPTED_CONTENT 14
177 #define PKCS7_ENVELOPED_ROOF 15
178
179 /**
180 * PKCS7 contentInfo OIDs
181 */
182 static u_char ASN1_pkcs7_data_oid_str[] = {
183 0x06, 0x09,
184 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01
185 };
186
187 static u_char ASN1_pkcs7_signed_data_oid_str[] = {
188 0x06, 0x09,
189 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x02
190 };
191
192 static u_char ASN1_pkcs7_enveloped_data_oid_str[] = {
193 0x06, 0x09,
194 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x03
195 };
196
197 static u_char ASN1_pkcs7_signed_enveloped_data_oid_str[] = {
198 0x06, 0x09,
199 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x04
200 };
201
202 static u_char ASN1_pkcs7_digested_data_oid_str[] = {
203 0x06, 0x09,
204 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x05
205 };
206
207 static char ASN1_pkcs7_encrypted_data_oid_str[] = {
208 0x06, 0x09,
209 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x06
210 };
211
212 static const chunk_t ASN1_pkcs7_data_oid =
213 chunk_from_buf(ASN1_pkcs7_data_oid_str);
214 static const chunk_t ASN1_pkcs7_signed_data_oid =
215 chunk_from_buf(ASN1_pkcs7_signed_data_oid_str);
216 static const chunk_t ASN1_pkcs7_enveloped_data_oid =
217 chunk_from_buf(ASN1_pkcs7_enveloped_data_oid_str);
218 static const chunk_t ASN1_pkcs7_signed_enveloped_data_oid =
219 chunk_from_buf(ASN1_pkcs7_signed_enveloped_data_oid_str);
220 static const chunk_t ASN1_pkcs7_digested_data_oid =
221 chunk_from_buf(ASN1_pkcs7_digested_data_oid_str);
222 static const chunk_t ASN1_pkcs7_encrypted_data_oid =
223 chunk_from_buf(ASN1_pkcs7_encrypted_data_oid_str);
224
225 /**
226 * 3DES and DES encryption OIDs
227 */
228 static u_char ASN1_3des_ede_cbc_oid_str[] = {
229 0x06, 0x08,
230 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x03, 0x07
231 };
232
233 static u_char ASN1_des_cbc_oid_str[] = {
234 0x06, 0x05,
235 0x2B, 0x0E, 0x03, 0x02, 0x07
236 };
237
238 static const chunk_t ASN1_3des_ede_cbc_oid =
239 chunk_from_buf(ASN1_3des_ede_cbc_oid_str);
240 static const chunk_t ASN1_des_cbc_oid =
241 chunk_from_buf(ASN1_des_cbc_oid_str);
242
243 /**
244 * Implements pkcs7_t.is_data.
245 */
246 static bool is_data(private_pkcs7_t *this)
247 {
248 return this->type == OID_PKCS7_DATA;
249 }
250
251 /**
252 * Implements pkcs7_t.is_signedData.
253 */
254 static bool is_signedData(private_pkcs7_t *this)
255 {
256 return this->type == OID_PKCS7_SIGNED_DATA;
257 }
258
259 /**
260 * Implements pkcs7_t.is_envelopedData.
261 */
262 static bool is_envelopedData(private_pkcs7_t *this)
263 {
264 return this->type == OID_PKCS7_ENVELOPED_DATA;
265 }
266
267 /**
268 * Check whether to abort the requested parsing
269 */
270 static bool abort_parsing(private_pkcs7_t *this, int type)
271 {
272 if (this->type != type)
273 {
274 DBG1("pkcs7 content to be parsed is not of type '%s'",
275 oid_names[type]);
276 return TRUE;
277 }
278 if (this->parsed)
279 {
280 DBG1("pkcs7 content has already been parsed");
281 return TRUE;
282 }
283 this->parsed = TRUE;
284 return FALSE;
285 }
286
287 /**
288 * Implements pkcs7_t.parse_data.
289 */
290 static bool parse_data(private_pkcs7_t *this)
291 {
292 chunk_t data = this->content;
293
294 if (abort_parsing(this, OID_PKCS7_DATA))
295 {
296 return FALSE;
297 }
298 if (data.len == 0)
299 {
300 this->data = chunk_empty;
301 return TRUE;
302 }
303 if (parse_asn1_simple_object(&data, ASN1_OCTET_STRING, this->level, "data"))
304 {
305 this->data = chunk_clone(data);
306 return TRUE;
307 }
308 else
309 {
310 return FALSE;
311 }
312 }
313
314 /**
315 * Implements pkcs7_t.parse_signedData.
316 */
317 static bool parse_signedData(private_pkcs7_t *this, x509_t *cacert)
318 {
319 asn1_ctx_t ctx;
320 chunk_t object;
321 u_int level;
322 int objectID = 0;
323
324 int digest_alg = OID_UNKNOWN;
325 int enc_alg = OID_UNKNOWN;
326 int signerInfos = 0;
327
328 chunk_t encrypted_digest = chunk_empty;
329
330 if (abort_parsing(this, OID_PKCS7_SIGNED_DATA))
331 {
332 return FALSE;
333 }
334
335 asn1_init(&ctx, this->content, this->level, FALSE, FALSE);
336
337 while (objectID < PKCS7_SIGNED_ROOF)
338 {
339 if (!extract_object(signedDataObjects, &objectID, &object, &level, &ctx))
340 {
341 return FALSE;
342 }
343
344 switch (objectID)
345 {
346 case PKCS7_DIGEST_ALG:
347 digest_alg = parse_algorithmIdentifier(object, level, NULL);
348 break;
349 case PKCS7_SIGNED_CONTENT_INFO:
350 {
351 chunk_t pureData;
352 pkcs7_t *data = pkcs7_create_from_chunk(object, level+1);
353
354 if (data == NULL)
355 {
356 return FALSE;
357 }
358 if (!data->parse_data(data))
359 {
360 data->destroy(data);
361 return FALSE;
362 }
363 pureData = data->get_data(data);
364 this->data = (pureData.len)? chunk_clone(pureData) : chunk_empty;
365 data->destroy(data);
366 }
367 break;
368 case PKCS7_SIGNED_CERT:
369 {
370 x509_t *cert = x509_create_from_chunk(chunk_clone(object), level+1);
371
372 if (cert)
373 {
374 this->certs->insert_last(this->certs, (void*)cert);
375 }
376 }
377 break;
378 case PKCS7_SIGNER_INFO:
379 signerInfos++;
380 DBG2(" signer #%d", signerInfos);
381 break;
382 case PKCS7_SIGNED_ISSUER:
383 {
384 identification_t *issuer;
385
386 issuer = identification_create_from_encoding(ID_DER_ASN1_DN, object);
387 DBG2(" '%D'", issuer);
388 issuer->destroy(issuer);
389 }
390 break;
391 case PKCS7_AUTH_ATTRIBUTES:
392 *object.ptr = ASN1_SET;
393 this->attributes = pkcs9_create_from_chunk(object, level+1);
394 *object.ptr = ASN1_CONTEXT_C_0;
395 break;
396 case PKCS7_DIGEST_ALGORITHM:
397 digest_alg = parse_algorithmIdentifier(object, level, NULL);
398 break;
399 case PKCS7_DIGEST_ENC_ALGORITHM:
400 enc_alg = parse_algorithmIdentifier(object, level, NULL);
401 break;
402 case PKCS7_ENCRYPTED_DIGEST:
403 encrypted_digest = object;
404 }
405 objectID++;
406 }
407
408 /* check the signature only if a cacert is available */
409 if (cacert != NULL)
410 {
411 hash_algorithm_t algorithm = hasher_algorithm_from_oid(digest_alg);
412 rsa_public_key_t *signer = cacert->get_public_key(cacert);
413
414 if (signerInfos == 0)
415 {
416 DBG1("no signerInfo object found");
417 return FALSE;
418 }
419 else if (signerInfos > 1)
420 {
421 DBG1("more than one signerInfo object found");
422 return FALSE;
423 }
424 if (this->attributes == NULL)
425 {
426 DBG1("no authenticatedAttributes object found");
427 return FALSE;
428 }
429 if (enc_alg != OID_RSA_ENCRYPTION)
430 {
431 DBG1("only RSA digest encryption supported");
432 return FALSE;
433 }
434 if (signer->verify_emsa_pkcs1_signature(signer, algorithm,
435 this->attributes->get_encoding(this->attributes), encrypted_digest) != SUCCESS)
436 {
437 DBG1("invalid digest signature");
438 return FALSE;
439 }
440 else
441 {
442 DBG2("digest signature is valid");
443 }
444 if (this->data.ptr != NULL)
445 {
446 chunk_t messageDigest = this->attributes->get_messageDigest(this->attributes);
447
448 if (messageDigest.ptr == NULL)
449 {
450 DBG1("messageDigest attribute not found");
451 return FALSE;
452 }
453 else
454 {
455 hasher_t *hasher;
456 chunk_t hash;
457 bool valid;
458
459 hasher = lib->crypto->create_hasher(lib->crypto, algorithm)
460 if (hasher == NULL)
461 {
462 DBG1("hash algorithm %N not supported",
463 hash_algorithm_names, algorithm);
464 free(messageDigest.ptr);
465 return FALSE;
466 }
467 hasher->allocate_hash(hasher, this->data, &hash);
468 hasher->destroy(hasher);
469 DBG3("hash: %B", &hash);
470
471 valid = chunk_equals(messageDigest, hash);
472 free(messageDigest.ptr);
473 free(hash.ptr);
474 if (valid)
475 {
476 DBG2("messageDigest is valid");
477 }
478 else
479 {
480 DBG1("invalid messageDigest");
481 return FALSE;
482 }
483 }
484 }
485 }
486 return TRUE;
487 }
488
489 /**
490 * Parse PKCS#7 envelopedData content
491 */
492 static bool parse_envelopedData(private_pkcs7_t *this, chunk_t serialNumber,
493 rsa_private_key_t *key)
494 {
495 asn1_ctx_t ctx;
496 chunk_t object;
497 u_int level;
498 int objectID = 0;
499
500 chunk_t iv = chunk_empty;
501 chunk_t symmetric_key = chunk_empty;
502 chunk_t encrypted_content = chunk_empty;
503
504 crypter_t *crypter = NULL;
505
506 if (abort_parsing(this, OID_PKCS7_ENVELOPED_DATA))
507 {
508 return FALSE;
509 }
510
511 asn1_init(&ctx, this->content, this->level, FALSE, FALSE);
512
513 while (objectID < PKCS7_ENVELOPED_ROOF)
514 {
515 if (!extract_object(envelopedDataObjects, &objectID, &object, &level, &ctx))
516 {
517 goto failed;
518 }
519
520 switch (objectID)
521 {
522 case PKCS7_ENVELOPED_VERSION:
523 if (*object.ptr != 0)
524 {
525 DBG1("envelopedData version is not 0");
526 goto failed;
527 }
528 break;
529 case PKCS7_RECIPIENT_INFO_VERSION:
530 if (*object.ptr != 0)
531 {
532 DBG1("recipient info version is not 0");
533 goto failed;
534 }
535 break;
536 case PKCS7_ISSUER:
537 {
538 identification_t *issuer;
539
540 issuer = identification_create_from_encoding(ID_DER_ASN1_DN, object);
541 DBG2(" '%D'", issuer);
542 issuer->destroy(issuer);
543 }
544 break;
545 case PKCS7_SERIAL_NUMBER:
546 if (!chunk_equals(serialNumber, object))
547 {
548 DBG1("serial numbers do not match");
549 goto failed;
550 }
551 break;
552 case PKCS7_ENCRYPTION_ALG:
553 {
554 int alg = parse_algorithmIdentifier(object, level, NULL);
555
556 if (alg != OID_RSA_ENCRYPTION)
557 {
558 DBG1("only rsa encryption supported");
559 goto failed;
560 }
561 }
562 break;
563 case PKCS7_ENCRYPTED_KEY:
564 if (key->pkcs1_decrypt(key, object, &symmetric_key) != SUCCESS)
565 {
566 DBG1("symmetric key could not be decrypted with rsa");
567 goto failed;
568 }
569 DBG4("symmetric key : %B", &symmetric_key);
570 break;
571 case PKCS7_CONTENT_TYPE:
572 if (known_oid(object) != OID_PKCS7_DATA)
573 {
574 DBG1("encrypted content not of type pkcs7 data");
575 goto failed;
576 }
577 break;
578 case PKCS7_CONTENT_ENC_ALGORITHM:
579 {
580 int alg = parse_algorithmIdentifier(object, level, &iv);
581
582 switch (alg)
583 {
584 case OID_DES_CBC:
585 crypter = crypter_create(ENCR_DES, 0);
586 break;
587 case OID_3DES_EDE_CBC:
588 crypter = crypter_create(ENCR_3DES, 0);
589 break;
590 default:
591 DBG1("Only DES and 3DES supported for symmetric encryption");
592 goto failed;
593 }
594 if (symmetric_key.len != crypter->get_key_size(crypter))
595 {
596 DBG1("symmetric key has wrong length");
597 goto failed;
598 }
599 if (!parse_asn1_simple_object(&iv, ASN1_OCTET_STRING, level+1, "IV"))
600 {
601 DBG1("IV could not be parsed");
602 goto failed;
603 }
604 if (iv.len != crypter->get_block_size(crypter))
605 {
606 DBG1("IV has wrong length");
607 goto failed;
608 }
609 }
610 break;
611 case PKCS7_ENCRYPTED_CONTENT:
612 encrypted_content = object;
613 break;
614 }
615 objectID++;
616 }
617
618 /* decrypt the content */
619 crypter->set_key(crypter, symmetric_key);
620 crypter->decrypt(crypter, encrypted_content, iv, &this->data);
621 DBG3("decrypted content with padding: %B", &this->data);
622
623 /* remove the padding */
624 {
625 u_char *pos = this->data.ptr + this->data.len - 1;
626 u_char pattern = *pos;
627 size_t padding = pattern;
628
629 if (padding > this->data.len)
630 {
631 DBG1("padding greater than data length");
632 goto failed;
633 }
634 this->data.len -= padding;
635
636 while (padding-- > 0)
637 {
638 if (*pos-- != pattern)
639 {
640 DBG1("wrong padding pattern");
641 goto failed;
642 }
643 }
644 }
645 crypter->destroy(crypter);
646 free(symmetric_key.ptr);
647 return TRUE;
648
649 failed:
650 DESTROY_IF(crypter);
651 free(symmetric_key.ptr);
652 chunk_free(&this->data);
653 return FALSE;
654 }
655
656 /**
657 * Implements pkcs7_t.get_data.
658 */
659 static chunk_t get_data(private_pkcs7_t *this)
660 {
661 return this->data;
662 }
663
664 /**
665 * Implements pkcs7_t.get_contentInfo.
666 */
667 static chunk_t get_contentInfo(private_pkcs7_t *this)
668 {
669 chunk_t content_type;
670
671 /* select DER-encoded OID for pkcs7_contentInfo type */
672 switch(this->type)
673 {
674 case OID_PKCS7_DATA:
675 content_type = ASN1_pkcs7_data_oid;
676 break;
677 case OID_PKCS7_SIGNED_DATA:
678 content_type = ASN1_pkcs7_signed_data_oid;
679 break;
680 case OID_PKCS7_ENVELOPED_DATA:
681 content_type = ASN1_pkcs7_enveloped_data_oid;
682 break;
683 case OID_PKCS7_SIGNED_ENVELOPED_DATA:
684 content_type = ASN1_pkcs7_signed_enveloped_data_oid;
685 break;
686 case OID_PKCS7_DIGESTED_DATA:
687 content_type = ASN1_pkcs7_digested_data_oid;
688 break;
689 case OID_PKCS7_ENCRYPTED_DATA:
690 content_type = ASN1_pkcs7_encrypted_data_oid;
691 break;
692 case OID_UNKNOWN:
693 default:
694 DBG1("invalid pkcs7 contentInfo type");
695 return chunk_empty;
696 }
697
698 return (this->content.ptr == NULL)
699 ? asn1_simple_object(ASN1_SEQUENCE, content_type)
700 : asn1_wrap(ASN1_SEQUENCE, "cm",
701 content_type,
702 asn1_simple_object(ASN1_CONTEXT_C_0, this->content)
703 );
704 }
705
706 /**
707 * Implements pkcs7_t.create_certificate_iterator
708 */
709 static iterator_t *create_certificate_iterator(const private_pkcs7_t *this)
710 {
711 return this->certs->create_iterator(this->certs, TRUE);
712 }
713
714 /**
715 * Implements pkcs7_t.set_certificate
716 */
717 static void set_certificate(private_pkcs7_t *this, x509_t *cert)
718 {
719 if (cert)
720 {
721 /* TODO the certificate is currently not cloned */
722 this->certs->insert_last(this->certs, cert);
723 }
724 }
725
726 /**
727 * Implements pkcs7_t.set_attributes
728 */
729 static void set_attributes(private_pkcs7_t *this, pkcs9_t *attributes)
730 {
731 this->attributes = attributes;
732 }
733
734 /**
735 * build a DER-encoded issuerAndSerialNumber object
736 */
737 chunk_t pkcs7_build_issuerAndSerialNumber(x509_t *cert)
738 {
739 identification_t *issuer = cert->get_issuer(cert);
740
741 return asn1_wrap(ASN1_SEQUENCE, "cm",
742 issuer->get_encoding(issuer),
743 asn1_simple_object(ASN1_INTEGER, cert->get_serialNumber(cert)));
744 }
745
746 /**
747 * Implements pkcs7_t.build_envelopedData.
748 */
749 bool build_envelopedData(private_pkcs7_t *this, x509_t *cert,
750 encryption_algorithm_t alg)
751 {
752 chunk_t iv, symmetricKey, in, out, alg_oid;
753 crypter_t *crypter;
754
755 /* select OID of symmetric encryption algorithm */
756 switch (alg)
757 {
758 case ENCR_DES:
759 alg_oid = ASN1_des_cbc_oid;
760 break;
761 case ENCR_3DES:
762 alg_oid = ASN1_3des_ede_cbc_oid;
763 break;
764 default:
765 DBG1(" encryption algorithm %N not supported",
766 encryption_algorithm_names, alg);
767 return FALSE;
768 }
769
770 crypter = crypter_create(alg, 0);
771 if (crypter == NULL)
772 {
773 DBG1(" could not create crypter for algorithm %N",
774 encryption_algorithm_names, alg);
775 return FALSE;
776 }
777
778 /* generate a true random symmetric encryption key
779 * and a pseudo-random iv
780 */
781 {
782 randomizer_t *randomizer = randomizer_create();
783
784 randomizer->allocate_random_bytes(randomizer,
785 crypter->get_key_size(crypter), &symmetricKey);
786 DBG4(" symmetric encryption key: %B", &symmetricKey);
787
788 randomizer->allocate_pseudo_random_bytes(randomizer,
789 crypter->get_block_size(crypter), &iv);
790 DBG4(" initialization vector: %B", &iv);
791
792 randomizer->destroy(randomizer);
793 }
794
795 /* pad the data so that the total length becomes
796 * a multiple of the block size
797 */
798 {
799 size_t block_size = crypter->get_block_size(crypter);
800 size_t padding = block_size - this->data.len % block_size;
801
802 in.len = this->data.len + padding;
803 in.ptr = malloc(in.len);
804
805 DBG2(" padding %d bytes of data to multiple block size of %d bytes",
806 (int)this->data.len, (int)in.len);
807
808 /* copy data */
809 memcpy(in.ptr, this->data.ptr, this->data.len);
810 /* append padding */
811 memset(in.ptr + this->data.len, padding, padding);
812 }
813 DBG3(" padded unencrypted data: %B", &in);
814
815 /* symmetric encryption of data object */
816 crypter->set_key(crypter, symmetricKey);
817 crypter->encrypt(crypter, in, iv, &out);
818 crypter->destroy(crypter);
819 chunk_free_randomized(&in);
820 DBG3(" encrypted data: %B", &out);
821
822 /* build pkcs7 enveloped data object */
823 {
824 chunk_t contentEncryptionAlgorithm = asn1_wrap(ASN1_SEQUENCE, "cm",
825 alg_oid,
826 asn1_wrap(ASN1_OCTET_STRING, "m", iv));
827
828 chunk_t encryptedContentInfo = asn1_wrap(ASN1_SEQUENCE, "cmm",
829 ASN1_pkcs7_data_oid,
830 contentEncryptionAlgorithm,
831 asn1_wrap(ASN1_CONTEXT_S_0, "m", out));
832
833 chunk_t wrappedKey, encryptedKey, recipientInfo;
834
835 rsa_public_key_t *public_key = cert->get_public_key(cert);
836
837 public_key->pkcs1_encrypt(public_key, symmetricKey, &wrappedKey);
838 chunk_free_randomized(&symmetricKey);
839
840 encryptedKey = asn1_wrap(ASN1_OCTET_STRING, "m", wrappedKey);
841
842 recipientInfo = asn1_wrap(ASN1_SEQUENCE, "cmcm",
843 ASN1_INTEGER_0,
844 pkcs7_build_issuerAndSerialNumber(cert),
845 asn1_algorithmIdentifier(OID_RSA_ENCRYPTION),
846 encryptedKey);
847
848 this->content = asn1_wrap(ASN1_SEQUENCE, "cmm",
849 ASN1_INTEGER_0,
850 asn1_wrap(ASN1_SET, "m", recipientInfo),
851 encryptedContentInfo);
852 this->type = OID_PKCS7_ENVELOPED_DATA;
853 }
854 return TRUE;
855 }
856
857 /**
858 * Implements pkcs7_t.build_signedData.
859 */
860 bool build_signedData(private_pkcs7_t *this, rsa_private_key_t *private_key,
861 hash_algorithm_t alg)
862 {
863 int signature_oid = hasher_signature_algorithm_to_oid(alg);
864 chunk_t authenticatedAttributes = chunk_empty;
865 chunk_t encryptedDigest = chunk_empty;
866 chunk_t signerInfo;
867 x509_t *cert;
868
869 if (this->certs->get_first(this->certs, (void**)&cert) != SUCCESS)
870 {
871 DBG1(" no pkcs7 signer certificate found");
872 return FALSE;
873 }
874
875 if (this->attributes != NULL)
876 {
877 if(this->data.ptr != NULL)
878 {
879 hasher_t *hasher;
880
881 hasher = lib->crypto->create_hasher(lib->crypto, alg);
882 if (hasher == NULL)
883 {
884 DBG1(" hash algorithm %N not support",
885 hash_algorithm_names, alg);
886 return FALSE;
887 }
888
889 /* take the current time as signingTime */
890 time_t now = time(NULL);
891 chunk_t signingTime = timetoasn1(&now, ASN1_UTCTIME);
892
893 chunk_t messageDigest, attributes;
894
895 hasher->allocate_hash(hasher, this->data, &messageDigest);
896 hasher->destroy(hasher);
897 this->attributes->set_attribute(this->attributes,
898 OID_PKCS9_CONTENT_TYPE, ASN1_pkcs7_data_oid);
899 this->attributes->set_messageDigest(this->attributes,
900 messageDigest);
901 this->attributes->set_attribute(this->attributes,
902 OID_PKCS9_SIGNING_TIME, signingTime);
903 attributes = this->attributes->get_encoding(this->attributes);
904
905 free(messageDigest.ptr);
906 free(signingTime.ptr);
907
908 private_key->build_emsa_pkcs1_signature(private_key, alg,
909 attributes, &encryptedDigest);
910 authenticatedAttributes = chunk_clone(attributes);
911 *authenticatedAttributes.ptr = ASN1_CONTEXT_C_0;
912 }
913 }
914 else if (this->data.ptr != NULL)
915 {
916 private_key->build_emsa_pkcs1_signature(private_key, alg,
917 this->data, &encryptedDigest);
918 }
919 if (encryptedDigest.ptr)
920 {
921 encryptedDigest = asn1_wrap(ASN1_OCTET_STRING, "m", encryptedDigest);
922 }
923
924 signerInfo = asn1_wrap(ASN1_SEQUENCE, "cmcmcm",
925 ASN1_INTEGER_1,
926 pkcs7_build_issuerAndSerialNumber(cert),
927 asn1_algorithmIdentifier(signature_oid),
928 authenticatedAttributes,
929 asn1_algorithmIdentifier(OID_RSA_ENCRYPTION),
930 encryptedDigest);
931
932 if (this->data.ptr != NULL)
933 {
934 this->content = asn1_simple_object(ASN1_OCTET_STRING, this->data);
935 chunk_free(&this->data);
936 }
937 this->type = OID_PKCS7_DATA;
938 this->data = get_contentInfo(this);
939 chunk_free(&this->content);
940
941 this->type = OID_PKCS7_SIGNED_DATA;
942
943 this->content = asn1_wrap(ASN1_SEQUENCE, "cmcmm",
944 ASN1_INTEGER_1,
945 asn1_simple_object(ASN1_SET, asn1_algorithmIdentifier(signature_oid)),
946 this->data,
947 asn1_simple_object(ASN1_CONTEXT_C_0, cert->get_certificate(cert)),
948 asn1_wrap(ASN1_SET, "m", signerInfo));
949
950 return TRUE;
951 }
952
953 /**
954 * Implements pkcs7_t.destroy
955 */
956 static void destroy(private_pkcs7_t *this)
957 {
958 DESTROY_IF(this->attributes);
959 this->certs->destroy_offset(this->certs, offsetof(x509_t, destroy));
960 free(this->content.ptr);
961 free(this->data.ptr);
962 free(this);
963 }
964
965 /**
966 * Parse PKCS#7 contentInfo object
967 */
968 static bool parse_contentInfo(chunk_t blob, u_int level0, private_pkcs7_t *cInfo)
969 {
970 asn1_ctx_t ctx;
971 chunk_t object;
972 u_int level;
973 int objectID = 0;
974
975 asn1_init(&ctx, blob, level0, FALSE, FALSE);
976
977 while (objectID < PKCS7_INFO_ROOF)
978 {
979 if (!extract_object(contentInfoObjects, &objectID, &object, &level, &ctx))
980 {
981 return FALSE;
982 }
983
984 if (objectID == PKCS7_INFO_TYPE)
985 {
986 cInfo->type = known_oid(object);
987 if (cInfo->type < OID_PKCS7_DATA
988 || cInfo->type > OID_PKCS7_ENCRYPTED_DATA)
989 {
990 DBG1("unknown pkcs7 content type");
991 return FALSE;
992 }
993 }
994 else if (objectID == PKCS7_INFO_CONTENT && object.len > 0)
995 {
996 cInfo->content = chunk_clone(object);
997 }
998 objectID++;
999 }
1000 return TRUE;
1001 }
1002
1003 /**
1004 * Generic private constructor
1005 */
1006 static private_pkcs7_t *pkcs7_create_empty(void)
1007 {
1008 private_pkcs7_t *this = malloc_thing(private_pkcs7_t);
1009
1010 /* initialize */
1011 this->type = OID_UNKNOWN;
1012 this->content = chunk_empty;
1013 this->parsed = FALSE;
1014 this->level = 0;
1015 this->data = chunk_empty;
1016 this->attributes = NULL;
1017 this->certs = linked_list_create();
1018
1019 /*public functions */
1020 this->public.is_data = (bool (*) (pkcs7_t*))is_data;
1021 this->public.is_signedData = (bool (*) (pkcs7_t*))is_signedData;
1022 this->public.is_envelopedData = (bool (*) (pkcs7_t*))is_envelopedData;
1023 this->public.parse_data = (bool (*) (pkcs7_t*))parse_data;
1024 this->public.parse_signedData = (bool (*) (pkcs7_t*,x509_t*))parse_signedData;
1025 this->public.parse_envelopedData = (bool (*) (pkcs7_t*,chunk_t,rsa_private_key_t*))parse_envelopedData;
1026 this->public.get_data = (chunk_t (*) (pkcs7_t*))get_data;
1027 this->public.get_contentInfo = (chunk_t (*) (pkcs7_t*))get_contentInfo;
1028 this->public.create_certificate_iterator = (iterator_t* (*) (pkcs7_t*))create_certificate_iterator;
1029 this->public.set_certificate = (void (*) (pkcs7_t*,x509_t*))set_certificate;
1030 this->public.set_attributes = (void (*) (pkcs7_t*,pkcs9_t*))set_attributes;
1031 this->public.build_envelopedData = (bool (*) (pkcs7_t*,x509_t*,encryption_algorithm_t))build_envelopedData;
1032 this->public.build_signedData = (bool (*) (pkcs7_t*,rsa_private_key_t*,hash_algorithm_t))build_signedData;
1033 this->public.destroy = (void (*) (pkcs7_t*))destroy;
1034
1035 return this;
1036 }
1037
1038 /*
1039 * Described in header.
1040 */
1041 pkcs7_t *pkcs7_create_from_chunk(chunk_t chunk, u_int level)
1042 {
1043 private_pkcs7_t *this = pkcs7_create_empty();
1044
1045 this->level = level + 2;
1046 if (!parse_contentInfo(chunk, level, this))
1047 {
1048 destroy(this);
1049 return NULL;
1050 }
1051 return &this->public;
1052 }
1053
1054 /*
1055 * Described in header.
1056 */
1057 pkcs7_t *pkcs7_create_from_data(chunk_t data)
1058 {
1059 private_pkcs7_t *this = pkcs7_create_empty();
1060
1061 this->data = chunk_clone(data);
1062 this->parsed = TRUE;
1063
1064 return &this->public;
1065 }
1066
1067 /*
1068 * Described in header.
1069 */
1070 pkcs7_t *pkcs7_create_from_file(const char *filename, const char *label)
1071 {
1072 bool pgp = FALSE;
1073 chunk_t chunk = chunk_empty;
1074 char cert_label[BUF_LEN];
1075 pkcs7_t *pkcs7;
1076
1077 snprintf(cert_label, BUF_LEN, "%s pkcs7", label);
1078
1079 if (!pem_asn1_load_file(filename, NULL, cert_label, &chunk, &pgp))
1080 {
1081 return NULL;
1082 }
1083
1084 pkcs7 = pkcs7_create_from_chunk(chunk, 0);
1085 free(chunk.ptr);
1086 return pkcs7;
1087 }