1 /* minip12.c - A minimal pkcs-12 implementation.
2 * Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
6 * GnuPG is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * GnuPG is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
35 #include "../jnlib/logging.h"
36 #include "../jnlib/utf8conv.h"
40 #define DIM(v) (sizeof(v)/sizeof((v)[0]))
62 TAG_OBJECT_DESCRIPTOR
= 7,
66 TAG_EMBEDDED_PDV
= 11,
68 TAG_REALTIVE_OID
= 13,
71 TAG_NUMERIC_STRING
= 18,
72 TAG_PRINTABLE_STRING
= 19,
73 TAG_TELETEX_STRING
= 20,
74 TAG_VIDEOTEX_STRING
= 21,
77 TAG_GENERALIZED_TIME
= 24,
78 TAG_GRAPHIC_STRING
= 25,
79 TAG_VISIBLE_STRING
= 26,
80 TAG_GENERAL_STRING
= 27,
81 TAG_UNIVERSAL_STRING
= 28,
82 TAG_CHARACTER_STRING
= 29,
87 static unsigned char const oid_data
[9] = {
88 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01 };
89 static unsigned char const oid_encryptedData
[9] = {
90 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x06 };
91 static unsigned char const oid_pkcs_12_keyBag
[11] = {
92 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x0A, 0x01, 0x01 };
93 static unsigned char const oid_pkcs_12_pkcs_8ShroudedKeyBag
[11] = {
94 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x0A, 0x01, 0x02 };
95 static unsigned char const oid_pkcs_12_CertBag
[11] = {
96 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x0A, 0x01, 0x03 };
97 static unsigned char const oid_pkcs_12_CrlBag
[11] = {
98 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x0A, 0x01, 0x04 };
100 static unsigned char const oid_pbeWithSHAAnd3_KeyTripleDES_CBC
[10] = {
101 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x03 };
102 static unsigned char const oid_pbeWithSHAAnd40BitRC2_CBC
[10] = {
103 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x06 };
104 static unsigned char const oid_x509Certificate_for_pkcs_12
[10] = {
105 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x16, 0x01 };
108 static unsigned char const oid_rsaEncryption
[9] = {
109 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01 };
112 static unsigned char const data_3desiter2048
[30] = {
113 0x30, 0x1C, 0x06, 0x0A, 0x2A, 0x86, 0x48, 0x86,
114 0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x03, 0x30, 0x0E,
115 0x04, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
116 0xFF, 0xFF, 0x02, 0x02, 0x08, 0x00 };
117 #define DATA_3DESITER2048_SALT_OFF 18
119 static unsigned char const data_rc2iter2048
[30] = {
120 0x30, 0x1C, 0x06, 0x0A, 0x2A, 0x86, 0x48, 0x86,
121 0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x06, 0x30, 0x0E,
122 0x04, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
123 0xFF, 0xFF, 0x02, 0x02, 0x08, 0x00 };
124 #define DATA_RC2ITER2048_SALT_OFF 18
126 static unsigned char const data_mactemplate
[51] = {
127 0x30, 0x31, 0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
128 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04,
129 0x14, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
130 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
131 0xff, 0xff, 0xff, 0xff, 0xff, 0x04, 0x08, 0xff,
132 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02,
134 #define DATA_MACTEMPLATE_MAC_OFF 17
135 #define DATA_MACTEMPLATE_SALT_OFF 39
137 static unsigned char const data_attrtemplate
[106] = {
138 0x31, 0x7c, 0x30, 0x55, 0x06, 0x09, 0x2a, 0x86,
139 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x14, 0x31,
140 0x48, 0x1e, 0x46, 0x00, 0x47, 0x00, 0x6e, 0x00,
141 0x75, 0x00, 0x50, 0x00, 0x47, 0x00, 0x20, 0x00,
142 0x65, 0x00, 0x78, 0x00, 0x70, 0x00, 0x6f, 0x00,
143 0x72, 0x00, 0x74, 0x00, 0x65, 0x00, 0x64, 0x00,
144 0x20, 0x00, 0x63, 0x00, 0x65, 0x00, 0x72, 0x00,
145 0x74, 0x00, 0x69, 0x00, 0x66, 0x00, 0x69, 0x00,
146 0x63, 0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00,
147 0x20, 0x00, 0x66, 0x00, 0x66, 0x00, 0x66, 0x00,
148 0x66, 0x00, 0x66, 0x00, 0x66, 0x00, 0x66, 0x00,
149 0x66, 0x30, 0x23, 0x06, 0x09, 0x2a, 0x86, 0x48,
150 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x15, 0x31, 0x16,
151 0x04, 0x14 }; /* Need to append SHA-1 digest. */
152 #define DATA_ATTRTEMPLATE_KEYID_OFF 73
156 unsigned char *buffer
;
166 unsigned long length
; /* length part of the TLV */
168 int ndef
; /* It is an indefinite length */
172 /* Parse the buffer at the address BUFFER which is of SIZE and return
173 the tag and the length part from the TLV triplet. Update BUFFER
174 and SIZE on success. Checks that the encoded length does not
175 exhaust the length of the provided buffer. */
177 parse_tag (unsigned char const **buffer
, size_t *size
, struct tag_info
*ti
)
181 const unsigned char *buf
= *buffer
;
182 size_t length
= *size
;
190 return -1; /* premature eof */
191 c
= *buf
++; length
--;
194 ti
->class = (c
& 0xc0) >> 6;
195 ti
->is_constructed
= !!(c
& 0x20);
205 return -1; /* premature eof */
206 c
= *buf
++; length
--;
216 return -1; /* prematureeof */
217 c
= *buf
++; length
--;
225 return -1; /* forbidden length value */
228 unsigned long len
= 0;
229 int count
= c
& 0x7f;
231 for (; count
; count
--)
235 return -1; /* premature_eof */
236 c
= *buf
++; length
--;
243 if (ti
->class == UNIVERSAL
&& !ti
->tag
)
246 if (ti
->length
> length
)
247 return -1; /* data larger than buffer. */
255 /* Given an ASN.1 chunk of a structure like:
257 24 NDEF: OCTET STRING -- This is not passed to us
258 04 1: OCTET STRING -- INPUT point s to here
265 : } -- This denotes a Null tag and are the last
266 -- two bytes in INPUT.
268 Create a new buffer with the content of that octet string. INPUT
269 is the orginal buffer with a length as stored at LENGTH. Returns
270 NULL on error or a new malloced buffer with the length of this new
271 buffer stored at LENGTH and the number of bytes parsed from input
272 are added to the value stored at INPUT_CONSUMED. INPUT_CONSUMED is
273 allowed to be passed as NULL if the caller is not interested in
275 static unsigned char *
276 cram_octet_string (const unsigned char *input
, size_t *length
,
277 size_t *input_consumed
)
279 const unsigned char *s
= input
;
281 unsigned char *output
, *d
;
284 /* Allocate output buf. We know that it won't be longer than the
286 d
= output
= gcry_malloc (n
);
292 if (parse_tag (&s
, &n
, &ti
))
294 if (ti
.class == UNIVERSAL
&& ti
.tag
== TAG_OCTET_STRING
295 && !ti
.ndef
&& !ti
.is_constructed
)
297 memcpy (d
, s
, ti
.length
);
302 else if (ti
.class == UNIVERSAL
&& !ti
.tag
&& !ti
.is_constructed
)
309 *length
= d
- output
;
311 *input_consumed
+= s
- input
;
316 *input_consumed
+= s
- input
;
324 string_to_key (int id
, char *salt
, size_t saltlen
, int iter
, const char *pw
,
325 int req_keylen
, unsigned char *keybuf
)
329 gcry_mpi_t num_b1
= NULL
;
331 unsigned char hash
[20], buf_b
[64], buf_i
[128], *p
;
339 log_error ("password too long\n");
345 log_error ("salt too short\n");
349 /* Store salt and password in BUF_I */
351 for(i
=0; i
< 64; i
++)
352 *p
++ = salt
[i
%saltlen
];
353 for(i
=j
=0; i
< 64; i
+= 2)
357 if (++j
> pwlen
) /* Note, that we include the trailing zero */
363 rc
= gcry_md_open (&md
, GCRY_MD_SHA1
, 0);
366 log_error ( "gcry_md_open failed: %s\n", gpg_strerror (rc
));
369 for(i
=0; i
< 64; i
++)
370 gcry_md_putc (md
, id
);
371 gcry_md_write (md
, buf_i
, 128);
372 memcpy (hash
, gcry_md_read (md
, 0), 20);
374 for (i
=1; i
< iter
; i
++)
375 gcry_md_hash_buffer (GCRY_MD_SHA1
, hash
, hash
, 20);
377 for (i
=0; i
< 20 && cur_keylen
< req_keylen
; i
++)
378 keybuf
[cur_keylen
++] = hash
[i
];
379 if (cur_keylen
== req_keylen
)
381 gcry_mpi_release (num_b1
);
382 return 0; /* ready */
385 /* need more bytes. */
386 for(i
=0; i
< 64; i
++)
387 buf_b
[i
] = hash
[i
% 20];
388 rc
= gcry_mpi_scan (&num_b1
, GCRYMPI_FMT_USG
, buf_b
, 64, &n
);
391 log_error ( "gcry_mpi_scan failed: %s\n", gpg_strerror (rc
));
394 gcry_mpi_add_ui (num_b1
, num_b1
, 1);
395 for (i
=0; i
< 128; i
+= 64)
399 rc
= gcry_mpi_scan (&num_ij
, GCRYMPI_FMT_USG
, buf_i
+ i
, 64, &n
);
402 log_error ( "gcry_mpi_scan failed: %s\n",
406 gcry_mpi_add (num_ij
, num_ij
, num_b1
);
407 gcry_mpi_clear_highbit (num_ij
, 64*8);
408 rc
= gcry_mpi_print (GCRYMPI_FMT_USG
, buf_i
+ i
, 64, &n
, num_ij
);
411 log_error ( "gcry_mpi_print failed: %s\n",
415 gcry_mpi_release (num_ij
);
422 set_key_iv (gcry_cipher_hd_t chd
, char *salt
, size_t saltlen
, int iter
,
423 const char *pw
, int keybytes
)
425 unsigned char keybuf
[24];
428 assert (keybytes
== 5 || keybytes
== 24);
429 if (string_to_key (1, salt
, saltlen
, iter
, pw
, keybytes
, keybuf
))
431 rc
= gcry_cipher_setkey (chd
, keybuf
, keybytes
);
434 log_error ( "gcry_cipher_setkey failed: %s\n", gpg_strerror (rc
));
438 if (string_to_key (2, salt
, saltlen
, iter
, pw
, 8, keybuf
))
440 rc
= gcry_cipher_setiv (chd
, keybuf
, 8);
443 log_error ("gcry_cipher_setiv failed: %s\n", gpg_strerror (rc
));
451 crypt_block (unsigned char *buffer
, size_t length
, char *salt
, size_t saltlen
,
452 int iter
, const char *pw
, int cipher_algo
, int encrypt
)
454 gcry_cipher_hd_t chd
;
457 rc
= gcry_cipher_open (&chd
, cipher_algo
, GCRY_CIPHER_MODE_CBC
, 0);
460 log_error ( "gcry_cipher_open failed: %s\n", gpg_strerror(rc
));
461 wipememory (buffer
, length
);
464 if (set_key_iv (chd
, salt
, saltlen
, iter
, pw
,
465 cipher_algo
== GCRY_CIPHER_RFC2268_40
? 5:24))
467 wipememory (buffer
, length
);
471 rc
= encrypt
? gcry_cipher_encrypt (chd
, buffer
, length
, NULL
, 0)
472 : gcry_cipher_decrypt (chd
, buffer
, length
, NULL
, 0);
476 wipememory (buffer
, length
);
477 log_error ( "en/de-crytion failed: %s\n", gpg_strerror (rc
));
482 gcry_cipher_close (chd
);
486 /* Decrypt a block of data and try several encodings of the key.
487 CIPHERTEXT is the encrypted data of size LENGTH bytes; PLAINTEXT is
488 a buffer of the same size to receive the decryption result. SALT,
489 SALTLEN, ITER and PW are the information required for decryption
490 and CIPHER_ALGO is the algorithm id to use. CHECK_FNC is a
491 function called with the plaintext and used to check whether the
492 decryption succeeded; i.e. that a correct passphrase has been
493 given. That function shall return true if the decryption has likely
496 decrypt_block (const void *ciphertext
, unsigned char *plaintext
, size_t length
,
497 char *salt
, size_t saltlen
,
498 int iter
, const char *pw
, int cipher_algo
,
499 int (*check_fnc
) (const void *, size_t))
501 static const char * const charsets
[] = {
502 "", /* No conversion - use the UTF-8 passphrase direct. */
521 char *convertedpw
= NULL
; /* Malloced and converted password or NULL. */
522 size_t convertedpwsize
= 0; /* Allocated length. */
524 for (charsetidx
=0; charsets
[charsetidx
]; charsetidx
++)
526 if (*charsets
[charsetidx
])
531 size_t inbytes
, outbytes
;
535 /* We assume one byte encodings. Thus we can allocate
536 the buffer of the same size as the original
537 passphrase; the result will actually be shorter
539 convertedpwsize
= strlen (pw
) + 1;
540 convertedpw
= gcry_malloc_secure (convertedpwsize
);
543 log_info ("out of secure memory while"
544 " converting passphrase\n");
545 break; /* Give up. */
549 cd
= jnlib_iconv_open (charsets
[charsetidx
], "utf-8");
550 if (cd
== (jnlib_iconv_t
)(-1))
554 inbytes
= strlen (pw
);
555 outptr
= convertedpw
;
556 outbytes
= convertedpwsize
- 1;
557 if ( jnlib_iconv (cd
, (const char **)&inptr
, &inbytes
,
558 &outptr
, &outbytes
) == (size_t)-1)
560 jnlib_iconv_close (cd
);
564 jnlib_iconv_close (cd
);
565 log_info ("decryption failed; trying charset `%s'\n",
566 charsets
[charsetidx
]);
568 memcpy (plaintext
, ciphertext
, length
);
569 crypt_block (plaintext
, length
, salt
, saltlen
, iter
,
570 convertedpw
? convertedpw
:pw
, cipher_algo
, 0);
571 if (check_fnc (plaintext
, length
))
572 break; /* Decryption succeeded. */
574 gcry_free (convertedpw
);
578 /* Return true if the decryption of an bag_encrypted_data object has
581 bag_decrypted_data_p (const void *plaintext
, size_t length
)
584 const unsigned char *p
= plaintext
;
588 /* # warning debug code is enabled */
589 /* FILE *fp = fopen ("tmp-rc2-plain.der", "wb"); */
590 /* if (!fp || fwrite (p, n, 1, fp) != 1) */
595 if (parse_tag (&p
, &n
, &ti
))
597 if (ti
.class || ti
.tag
!= TAG_SEQUENCE
)
599 if (parse_tag (&p
, &n
, &ti
))
605 /* Note: If R_RESULT is passed as NULL, a key object as already be
606 processed and thus we need to skip it here. */
608 parse_bag_encrypted_data (const unsigned char *buffer
, size_t length
,
609 int startoffset
, size_t *r_consumed
, const char *pw
,
610 void (*certcb
)(void*, const unsigned char*, size_t),
611 void *certcbarg
, gcry_mpi_t
**r_result
)
614 const unsigned char *p
= buffer
;
615 const unsigned char *p_start
= buffer
;
621 unsigned char *plain
= NULL
;
623 unsigned char *cram_buffer
= NULL
;
624 size_t consumed
= 0; /* Number of bytes consumed from the orginal buffer. */
626 gcry_mpi_t
*result
= NULL
;
632 if (parse_tag (&p
, &n
, &ti
))
634 if (ti
.class != ASNCONTEXT
|| ti
.tag
)
636 if (parse_tag (&p
, &n
, &ti
))
638 if (ti
.tag
!= TAG_SEQUENCE
)
641 where
= "bag.encryptedData.version";
642 if (parse_tag (&p
, &n
, &ti
))
644 if (ti
.tag
!= TAG_INTEGER
|| ti
.length
!= 1 || *p
!= 0)
647 if (parse_tag (&p
, &n
, &ti
))
649 if (ti
.tag
!= TAG_SEQUENCE
)
652 where
= "bag.encryptedData.data";
653 if (parse_tag (&p
, &n
, &ti
))
655 if (ti
.tag
!= TAG_OBJECT_ID
|| ti
.length
!= DIM(oid_data
)
656 || memcmp (p
, oid_data
, DIM(oid_data
)))
661 where
= "bag.encryptedData.keyinfo";
662 if (parse_tag (&p
, &n
, &ti
))
664 if (ti
.class || ti
.tag
!= TAG_SEQUENCE
)
666 if (parse_tag (&p
, &n
, &ti
))
668 if (!ti
.class && ti
.tag
== TAG_OBJECT_ID
669 && ti
.length
== DIM(oid_pbeWithSHAAnd40BitRC2_CBC
)
670 && !memcmp (p
, oid_pbeWithSHAAnd40BitRC2_CBC
,
671 DIM(oid_pbeWithSHAAnd40BitRC2_CBC
)))
673 p
+= DIM(oid_pbeWithSHAAnd40BitRC2_CBC
);
674 n
-= DIM(oid_pbeWithSHAAnd40BitRC2_CBC
);
676 else if (!ti
.class && ti
.tag
== TAG_OBJECT_ID
677 && ti
.length
== DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC
)
678 && !memcmp (p
, oid_pbeWithSHAAnd3_KeyTripleDES_CBC
,
679 DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC
)))
681 p
+= DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC
);
682 n
-= DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC
);
688 where
= "rc2or3des-params";
689 if (parse_tag (&p
, &n
, &ti
))
691 if (ti
.class || ti
.tag
!= TAG_SEQUENCE
)
693 if (parse_tag (&p
, &n
, &ti
))
695 if (ti
.class || ti
.tag
!= TAG_OCTET_STRING
696 || ti
.length
< 8 || ti
.length
> 20 )
699 memcpy (salt
, p
, saltlen
);
702 if (parse_tag (&p
, &n
, &ti
))
704 if (ti
.class || ti
.tag
!= TAG_INTEGER
|| !ti
.length
)
706 for (iter
=0; ti
.length
; ti
.length
--)
709 iter
|= (*p
++) & 0xff;
713 where
= "rc2or3des-ciphertext";
714 if (parse_tag (&p
, &n
, &ti
))
717 consumed
= p
- p_start
;
718 if (ti
.class == ASNCONTEXT
&& ti
.tag
== 0 && ti
.is_constructed
&& ti
.ndef
)
720 /* Mozilla exported certs now come with single byte chunks of
721 octect strings. (Mozilla Firefox 1.0.4). Arghh. */
722 where
= "cram-rc2or3des-ciphertext";
723 cram_buffer
= cram_octet_string ( p
, &n
, &consumed
);
726 p
= p_start
= cram_buffer
;
728 *r_consumed
= consumed
;
729 r_consumed
= NULL
; /* Ugly hack to not update that value any further. */
732 else if (ti
.class == ASNCONTEXT
&& ti
.tag
== 0 && ti
.length
)
737 log_info ("%lu bytes of %s encrypted text\n",ti
.length
,is_3des
?"3DES":"RC2");
739 plain
= gcry_malloc_secure (ti
.length
);
742 log_error ("error allocating decryption buffer\n");
745 decrypt_block (p
, plain
, ti
.length
, salt
, saltlen
, iter
, pw
,
746 is_3des
? GCRY_CIPHER_3DES
: GCRY_CIPHER_RFC2268_40
,
747 bag_decrypted_data_p
);
752 where
= "outer.outer.seq";
753 if (parse_tag (&p
, &n
, &ti
))
758 if (ti
.class || ti
.tag
!= TAG_SEQUENCE
)
764 if (parse_tag (&p
, &n
, &ti
))
770 /* Loop over all certificates inside the bag. */
776 where
= "certbag.nextcert";
777 if (ti
.class || ti
.tag
!= TAG_SEQUENCE
)
780 where
= "certbag.objectidentifier";
781 if (parse_tag (&p
, &n
, &ti
))
783 if (ti
.class || ti
.tag
!= TAG_OBJECT_ID
)
785 if ( ti
.length
== DIM(oid_pkcs_12_CertBag
)
786 && !memcmp (p
, oid_pkcs_12_CertBag
, DIM(oid_pkcs_12_CertBag
)))
788 p
+= DIM(oid_pkcs_12_CertBag
);
789 n
-= DIM(oid_pkcs_12_CertBag
);
791 else if ( ti
.length
== DIM(oid_pkcs_12_CrlBag
)
792 && !memcmp (p
, oid_pkcs_12_CrlBag
, DIM(oid_pkcs_12_CrlBag
)))
794 p
+= DIM(oid_pkcs_12_CrlBag
);
795 n
-= DIM(oid_pkcs_12_CrlBag
);
798 else if ( ti
.length
== DIM(oid_pkcs_12_keyBag
)
799 && !memcmp (p
, oid_pkcs_12_keyBag
, DIM(oid_pkcs_12_keyBag
)))
801 /* The TrustedMIME plugin for MS Outlook started to create
802 files with just one outer 3DES encrypted container and
803 inside the certificates as well as the key. */
804 p
+= DIM(oid_pkcs_12_keyBag
);
805 n
-= DIM(oid_pkcs_12_keyBag
);
811 where
= "certbag.before.certheader";
812 if (parse_tag (&p
, &n
, &ti
))
814 if (ti
.class != ASNCONTEXT
|| ti
.tag
)
818 log_info ("skipping unsupported crlBag\n");
822 else if (iskeybag
&& (result
|| !r_result
))
824 log_info ("one keyBag already processed; skipping this one\n");
832 log_info ("processing simple keyBag\n");
834 /* Fixme: This code is duplicated from parse_bag_data. */
835 if (parse_tag (&p
, &n
, &ti
) || ti
.class || ti
.tag
!= TAG_SEQUENCE
)
837 if (parse_tag (&p
, &n
, &ti
) || ti
.class || ti
.tag
!= TAG_INTEGER
838 || ti
.length
!= 1 || *p
)
841 if (parse_tag (&p
, &n
, &ti
) || ti
.class || ti
.tag
!= TAG_SEQUENCE
)
844 if (parse_tag (&p
, &n
, &ti
))
849 if (ti
.class || ti
.tag
!= TAG_OBJECT_ID
850 || ti
.length
!= DIM(oid_rsaEncryption
)
851 || memcmp (p
, oid_rsaEncryption
,
852 DIM(oid_rsaEncryption
)))
854 p
+= DIM (oid_rsaEncryption
);
855 n
-= DIM (oid_rsaEncryption
);
863 if ( parse_tag (&p
, &n
, &ti
)
864 || ti
.class || ti
.tag
!= TAG_OCTET_STRING
)
866 if ( parse_tag (&p
, &n
, &ti
)
867 || ti
.class || ti
.tag
!= TAG_SEQUENCE
)
871 result
= gcry_calloc (10, sizeof *result
);
874 log_error ( "error allocating result array\n");
879 where
= "reading.keybag.key-parameters";
880 for (result_count
= 0; len
&& result_count
< 9;)
882 if ( parse_tag (&p
, &n
, &ti
)
883 || ti
.class || ti
.tag
!= TAG_INTEGER
)
891 if (!result_count
&& ti
.length
== 1 && !*p
)
892 ; /* ignore the very first one if it is a 0 */
897 rc
= gcry_mpi_scan (result
+result_count
, GCRYMPI_FMT_USG
, p
,
901 log_error ("error parsing key parameter: %s\n",
915 log_info ("processing certBag\n");
916 if (parse_tag (&p
, &n
, &ti
))
918 if (ti
.class || ti
.tag
!= TAG_SEQUENCE
)
920 if (parse_tag (&p
, &n
, &ti
))
922 if (ti
.class || ti
.tag
!= TAG_OBJECT_ID
923 || ti
.length
!= DIM(oid_x509Certificate_for_pkcs_12
)
924 || memcmp (p
, oid_x509Certificate_for_pkcs_12
,
925 DIM(oid_x509Certificate_for_pkcs_12
)))
927 p
+= DIM(oid_x509Certificate_for_pkcs_12
);
928 n
-= DIM(oid_x509Certificate_for_pkcs_12
);
930 where
= "certbag.before.octetstring";
931 if (parse_tag (&p
, &n
, &ti
))
933 if (ti
.class != ASNCONTEXT
|| ti
.tag
)
935 if (parse_tag (&p
, &n
, &ti
))
937 if (ti
.class || ti
.tag
!= TAG_OCTET_STRING
|| ti
.ndef
)
940 /* Return the certificate. */
942 certcb (certcbarg
, p
, ti
.length
);
948 /* Ugly hack to cope with the padding: Forget about the rest if
949 that is less or equal to the cipher's block length. We can
950 reasonable assume that all valid data will be longer than
955 /* Skip the optional SET with the pkcs12 cert attributes. */
958 where
= "bag.attributes";
959 if (parse_tag (&p
, &n
, &ti
))
961 if (!ti
.class && ti
.tag
== TAG_SEQUENCE
)
962 ; /* No attributes. */
963 else if (!ti
.class && ti
.tag
== TAG_SET
&& !ti
.ndef
)
964 { /* The optional SET. */
969 if (n
&& parse_tag (&p
, &n
, &ti
))
978 *r_consumed
= consumed
;
980 gcry_free (cram_buffer
);
990 for (i
=0; result
[i
]; i
++)
991 gcry_mpi_release (result
[i
]);
995 *r_consumed
= consumed
;
997 gcry_free (cram_buffer
);
998 log_error ("encryptedData error at \"%s\", offset %u\n",
999 where
, (unsigned int)((p
- p_start
)+startoffset
));
1002 /* Note, that the following string might be used by other programs
1003 to check for a bad passphrase; it should therefore not be
1004 translated or changed. */
1005 log_error ("possibly bad passphrase given\n");
1011 /* Return true if the decryption of a bag_data object has likely
1014 bag_data_p (const void *plaintext
, size_t length
)
1017 const unsigned char *p
= plaintext
;
1021 /* # warning debug code is enabled */
1022 /* FILE *fp = fopen ("tmp-3des-plain-key.der", "wb"); */
1023 /* if (!fp || fwrite (p, n, 1, fp) != 1) */
1028 if (parse_tag (&p
, &n
, &ti
) || ti
.class || ti
.tag
!= TAG_SEQUENCE
)
1030 if (parse_tag (&p
, &n
, &ti
) || ti
.class || ti
.tag
!= TAG_INTEGER
1031 || ti
.length
!= 1 || *p
)
1039 parse_bag_data (const unsigned char *buffer
, size_t length
, int startoffset
,
1040 size_t *r_consumed
, const char *pw
)
1044 const unsigned char *p
= buffer
;
1045 const unsigned char *p_start
= buffer
;
1052 unsigned char *plain
= NULL
;
1053 gcry_mpi_t
*result
= NULL
;
1054 int result_count
, i
;
1055 unsigned char *cram_buffer
= NULL
;
1056 size_t consumed
= 0; /* Number of bytes consumed from the orginal buffer. */
1059 if (parse_tag (&p
, &n
, &ti
))
1061 if (ti
.class != ASNCONTEXT
|| ti
.tag
)
1063 if (parse_tag (&p
, &n
, &ti
))
1065 if (ti
.class || ti
.tag
!= TAG_OCTET_STRING
)
1068 consumed
= p
- p_start
;
1069 if (ti
.is_constructed
&& ti
.ndef
)
1071 /* Mozilla exported certs now come with single byte chunks of
1072 octect strings. (Mozilla Firefox 1.0.4). Arghh. */
1073 where
= "cram-data.outersegs";
1074 cram_buffer
= cram_octet_string ( p
, &n
, &consumed
);
1077 p
= p_start
= cram_buffer
;
1079 *r_consumed
= consumed
;
1080 r_consumed
= NULL
; /* Ugly hack to not update that value any further. */
1084 where
= "data.outerseqs";
1085 if (parse_tag (&p
, &n
, &ti
))
1087 if (ti
.class || ti
.tag
!= TAG_SEQUENCE
)
1089 if (parse_tag (&p
, &n
, &ti
))
1091 if (ti
.class || ti
.tag
!= TAG_SEQUENCE
)
1094 where
= "data.objectidentifier";
1095 if (parse_tag (&p
, &n
, &ti
))
1097 if (ti
.class || ti
.tag
!= TAG_OBJECT_ID
1098 || ti
.length
!= DIM(oid_pkcs_12_pkcs_8ShroudedKeyBag
)
1099 || memcmp (p
, oid_pkcs_12_pkcs_8ShroudedKeyBag
,
1100 DIM(oid_pkcs_12_pkcs_8ShroudedKeyBag
)))
1102 p
+= DIM(oid_pkcs_12_pkcs_8ShroudedKeyBag
);
1103 n
-= DIM(oid_pkcs_12_pkcs_8ShroudedKeyBag
);
1105 where
= "shrouded,outerseqs";
1106 if (parse_tag (&p
, &n
, &ti
))
1108 if (ti
.class != ASNCONTEXT
|| ti
.tag
)
1110 if (parse_tag (&p
, &n
, &ti
))
1112 if (ti
.class || ti
.tag
!= TAG_SEQUENCE
)
1114 if (parse_tag (&p
, &n
, &ti
))
1116 if (ti
.class || ti
.tag
!= TAG_SEQUENCE
)
1118 if (parse_tag (&p
, &n
, &ti
))
1120 if (ti
.class || ti
.tag
!= TAG_OBJECT_ID
1121 || ti
.length
!= DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC
)
1122 || memcmp (p
, oid_pbeWithSHAAnd3_KeyTripleDES_CBC
,
1123 DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC
)))
1125 p
+= DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC
);
1126 n
-= DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC
);
1128 where
= "3des-params";
1129 if (parse_tag (&p
, &n
, &ti
))
1131 if (ti
.class || ti
.tag
!= TAG_SEQUENCE
)
1133 if (parse_tag (&p
, &n
, &ti
))
1135 if (ti
.class || ti
.tag
!= TAG_OCTET_STRING
1136 || ti
.length
< 8 || ti
.length
> 20)
1138 saltlen
= ti
.length
;
1139 memcpy (salt
, p
, saltlen
);
1142 if (parse_tag (&p
, &n
, &ti
))
1144 if (ti
.class || ti
.tag
!= TAG_INTEGER
|| !ti
.length
)
1146 for (iter
=0; ti
.length
; ti
.length
--)
1149 iter
|= (*p
++) & 0xff;
1153 where
= "3des-ciphertext";
1154 if (parse_tag (&p
, &n
, &ti
))
1156 if (ti
.class || ti
.tag
!= TAG_OCTET_STRING
|| !ti
.length
)
1159 log_info ("%lu bytes of 3DES encrypted text\n", ti
.length
);
1161 plain
= gcry_malloc_secure (ti
.length
);
1164 log_error ("error allocating decryption buffer\n");
1167 consumed
+= p
- p_start
+ ti
.length
;
1168 decrypt_block (p
, plain
, ti
.length
, salt
, saltlen
, iter
, pw
,
1173 p_start
= p
= plain
;
1175 where
= "decrypted-text";
1176 if (parse_tag (&p
, &n
, &ti
) || ti
.class || ti
.tag
!= TAG_SEQUENCE
)
1178 if (parse_tag (&p
, &n
, &ti
) || ti
.class || ti
.tag
!= TAG_INTEGER
1179 || ti
.length
!= 1 || *p
)
1182 if (parse_tag (&p
, &n
, &ti
) || ti
.class || ti
.tag
!= TAG_SEQUENCE
)
1185 if (parse_tag (&p
, &n
, &ti
))
1190 if (ti
.class || ti
.tag
!= TAG_OBJECT_ID
1191 || ti
.length
!= DIM(oid_rsaEncryption
)
1192 || memcmp (p
, oid_rsaEncryption
,
1193 DIM(oid_rsaEncryption
)))
1195 p
+= DIM (oid_rsaEncryption
);
1196 n
-= DIM (oid_rsaEncryption
);
1197 if (len
< ti
.length
)
1204 if (parse_tag (&p
, &n
, &ti
) || ti
.class || ti
.tag
!= TAG_OCTET_STRING
)
1206 if (parse_tag (&p
, &n
, &ti
) || ti
.class || ti
.tag
!= TAG_SEQUENCE
)
1210 result
= gcry_calloc (10, sizeof *result
);
1213 log_error ( "error allocating result array\n");
1218 where
= "reading.key-parameters";
1219 for (result_count
=0; len
&& result_count
< 9;)
1221 if (parse_tag (&p
, &n
, &ti
) || ti
.class || ti
.tag
!= TAG_INTEGER
)
1226 if (len
< ti
.length
)
1229 if (!result_count
&& ti
.length
== 1 && !*p
)
1230 ; /* ignore the very first one if it is a 0 */
1233 rc
= gcry_mpi_scan (result
+result_count
, GCRYMPI_FMT_USG
, p
,
1237 log_error ("error parsing key parameter: %s\n",
1249 gcry_free (cram_buffer
);
1251 *r_consumed
= consumed
;
1258 for (i
=0; result
[i
]; i
++)
1259 gcry_mpi_release (result
[i
]);
1262 gcry_free (cram_buffer
);
1263 log_error ( "data error at \"%s\", offset %u\n",
1264 where
, (unsigned int)((p
- buffer
) + startoffset
));
1266 *r_consumed
= consumed
;
1271 /* Parse a PKCS12 object and return an array of MPI representing the
1272 secret key parameters. This is a very limited implementation in
1273 that it is only able to look for 3DES encoded encryptedData and
1274 tries to extract the first private key object it finds. In case of
1275 an error NULL is returned. CERTCB and CERRTCBARG are used to pass
1276 X.509 certificates back to the caller. */
1278 p12_parse (const unsigned char *buffer
, size_t length
, const char *pw
,
1279 void (*certcb
)(void*, const unsigned char*, size_t),
1283 const unsigned char *p
= buffer
;
1284 const unsigned char *p_start
= buffer
;
1287 int bagseqlength
, len
;
1288 int bagseqndef
, lenndef
;
1289 gcry_mpi_t
*result
= NULL
;
1290 unsigned char *cram_buffer
= NULL
;
1293 if (parse_tag (&p
, &n
, &ti
))
1295 if (ti
.tag
!= TAG_SEQUENCE
)
1298 where
= "pfxVersion";
1299 if (parse_tag (&p
, &n
, &ti
))
1301 if (ti
.tag
!= TAG_INTEGER
|| ti
.length
!= 1 || *p
!= 3)
1306 if (parse_tag (&p
, &n
, &ti
))
1308 if (ti
.tag
!= TAG_SEQUENCE
)
1310 if (parse_tag (&p
, &n
, &ti
))
1312 if (ti
.tag
!= TAG_OBJECT_ID
|| ti
.length
!= DIM(oid_data
)
1313 || memcmp (p
, oid_data
, DIM(oid_data
)))
1318 if (parse_tag (&p
, &n
, &ti
))
1320 if (ti
.class != ASNCONTEXT
|| ti
.tag
)
1322 if (parse_tag (&p
, &n
, &ti
))
1324 if (ti
.class != UNIVERSAL
|| ti
.tag
!= TAG_OCTET_STRING
)
1327 if (ti
.is_constructed
&& ti
.ndef
)
1329 /* Mozilla exported certs now come with single byte chunks of
1330 octect strings. (Mozilla Firefox 1.0.4). Arghh. */
1331 where
= "cram-bags";
1332 cram_buffer
= cram_octet_string ( p
, &n
, NULL
);
1335 p
= p_start
= cram_buffer
;
1339 if (parse_tag (&p
, &n
, &ti
))
1341 if (ti
.class != UNIVERSAL
|| ti
.tag
!= TAG_SEQUENCE
)
1343 bagseqndef
= ti
.ndef
;
1344 bagseqlength
= ti
.length
;
1345 while (bagseqlength
|| bagseqndef
)
1347 /* log_debug ( "at offset %u\n", (p - p_start)); */
1348 where
= "bag-sequence";
1349 if (parse_tag (&p
, &n
, &ti
))
1351 if (bagseqndef
&& ti
.class == UNIVERSAL
&& !ti
.tag
&& !ti
.is_constructed
)
1353 if (ti
.class != UNIVERSAL
|| ti
.tag
!= TAG_SEQUENCE
)
1358 if (bagseqlength
< ti
.nhdr
)
1360 bagseqlength
-= ti
.nhdr
;
1361 if (bagseqlength
< ti
.length
)
1363 bagseqlength
-= ti
.length
;
1368 if (parse_tag (&p
, &n
, &ti
))
1375 if (ti
.tag
== TAG_OBJECT_ID
&& ti
.length
== DIM(oid_encryptedData
)
1376 && !memcmp (p
, oid_encryptedData
, DIM(oid_encryptedData
)))
1378 size_t consumed
= 0;
1380 p
+= DIM(oid_encryptedData
);
1381 n
-= DIM(oid_encryptedData
);
1383 len
-= DIM(oid_encryptedData
);
1384 where
= "bag.encryptedData";
1385 if (parse_bag_encrypted_data (p
, n
, (p
- p_start
), &consumed
, pw
,
1387 result
? NULL
: &result
))
1392 else if (ti
.tag
== TAG_OBJECT_ID
&& ti
.length
== DIM(oid_data
)
1393 && !memcmp (p
, oid_data
, DIM(oid_data
)))
1397 log_info ("already got an key object, skipping this one\n");
1403 size_t consumed
= 0;
1408 len
-= DIM(oid_data
);
1409 result
= parse_bag_data (p
, n
, (p
- p_start
), &consumed
, pw
);
1418 log_info ("unknown bag type - skipped\n");
1423 if (len
< 0 || len
> n
)
1429 /* Need to skip the Null Tag. */
1430 if (parse_tag (&p
, &n
, &ti
))
1432 if (!(ti
.class == UNIVERSAL
&& !ti
.tag
&& !ti
.is_constructed
))
1437 gcry_free (cram_buffer
);
1440 log_error ("error at \"%s\", offset %u\n",
1441 where
, (unsigned int)(p
- p_start
));
1446 for (i
=0; result
[i
]; i
++)
1447 gcry_mpi_release (result
[i
]);
1450 gcry_free (cram_buffer
);
1457 compute_tag_length (size_t n
)
1462 needed
+= 2; /* tag and one length byte */
1464 needed
+= 3; /* tag, number of length bytes, 1 length byte */
1466 needed
+= 4; /* tag, number of length bytes, 2 length bytes */
1469 log_error ("object too larger to encode\n");
1475 static unsigned char *
1476 store_tag_length (unsigned char *p
, int tag
, size_t n
)
1478 if (tag
== TAG_SEQUENCE
)
1479 tag
|= 0x20; /* constructed */
1500 /* Create the final PKCS-12 object from the sequences contained in
1501 SEQLIST. PW is the password. That array is terminated with an NULL
1503 static unsigned char *
1504 create_final (struct buffer_s
*sequences
, const char *pw
, size_t *r_length
)
1509 unsigned char *macstart
;
1511 unsigned char *result
, *p
;
1514 unsigned char keybuf
[20];
1520 /* 9 steps to create the pkcs#12 Krampf. */
1523 /* We add this at step 0. */
1525 /* 7. All the buffers. */
1526 for (i
=0; sequences
[i
].buffer
; i
++)
1527 needed
+= sequences
[i
].length
;
1529 /* 6. This goes into a sequences. */
1531 n
= compute_tag_length (needed
);
1534 /* 5. Encapsulate all in an octet string. */
1536 n
= compute_tag_length (needed
);
1539 /* 4. And tag it with [0]. */
1541 n
= compute_tag_length (needed
);
1544 /* 3. Prepend an data OID. */
1545 needed
+= 2 + DIM (oid_data
);
1547 /* 2. Put all into a sequences. */
1549 n
= compute_tag_length (needed
);
1552 /* 1. Prepend the version integer 3. */
1555 /* 0. And the final outer sequence. */
1557 needed
+= DIM (data_mactemplate
);
1559 n
= compute_tag_length (needed
);
1562 /* Allocate a buffer. */
1563 result
= gcry_malloc (needed
);
1566 log_error ("error allocating buffer\n");
1571 /* 0. Store the very outer sequence. */
1572 p
= store_tag_length (p
, TAG_SEQUENCE
, len
[0]);
1574 /* 1. Store the version integer 3. */
1579 /* 2. Store another sequence. */
1580 p
= store_tag_length (p
, TAG_SEQUENCE
, len
[2]);
1582 /* 3. Store the data OID. */
1583 p
= store_tag_length (p
, TAG_OBJECT_ID
, DIM (oid_data
));
1584 memcpy (p
, oid_data
, DIM (oid_data
));
1585 p
+= DIM (oid_data
);
1587 /* 4. Next comes a context tag. */
1588 p
= store_tag_length (p
, 0xa0, len
[4]);
1590 /* 5. And an octet string. */
1591 p
= store_tag_length (p
, TAG_OCTET_STRING
, len
[5]);
1593 /* 6. And the inner sequence. */
1595 p
= store_tag_length (p
, TAG_SEQUENCE
, len
[6]);
1597 /* 7. Append all the buffers. */
1598 for (i
=0; sequences
[i
].buffer
; i
++)
1600 memcpy (p
, sequences
[i
].buffer
, sequences
[i
].length
);
1601 p
+= sequences
[i
].length
;
1606 /* Intermezzo to compute the MAC. */
1607 maclen
= p
- macstart
;
1608 gcry_randomize (salt
, 8, GCRY_STRONG_RANDOM
);
1609 if (string_to_key (3, salt
, 8, 2048, pw
, 20, keybuf
))
1614 rc
= gcry_md_open (&md
, GCRY_MD_SHA1
, GCRY_MD_FLAG_HMAC
);
1617 log_error ("gcry_md_open failed: %s\n", gpg_strerror (rc
));
1621 rc
= gcry_md_setkey (md
, keybuf
, 20);
1624 log_error ("gcry_md_setkey failed: %s\n", gpg_strerror (rc
));
1629 gcry_md_write (md
, macstart
, maclen
);
1631 /* 8. Append the MAC template and fix it up. */
1632 memcpy (p
, data_mactemplate
, DIM (data_mactemplate
));
1633 memcpy (p
+ DATA_MACTEMPLATE_SALT_OFF
, salt
, 8);
1634 memcpy (p
+ DATA_MACTEMPLATE_MAC_OFF
, gcry_md_read (md
, 0), 20);
1635 p
+= DIM (data_mactemplate
);
1640 resultlen
= p
- result
;
1641 if (needed
!= resultlen
)
1642 log_debug ("length mismatch: %lu, %lu\n",
1643 (unsigned long)needed
, (unsigned long)resultlen
);
1645 *r_length
= resultlen
;
1650 /* Build a DER encoded SEQUENCE with the key:
1655 OBJECT IDENTIFIER rsaEncryption (1 2 840 113549 1 1 1)
1658 OCTET STRING, encapsulates {
1674 static unsigned char *
1675 build_key_sequence (gcry_mpi_t
*kparms
, size_t *r_length
)
1679 unsigned char *plain
, *p
;
1681 size_t outseqlen
, oidseqlen
, octstrlen
, inseqlen
;
1683 needed
= 3; /* The version(?) integer of value 0. */
1684 for (i
=0; kparms
[i
]; i
++)
1687 rc
= gcry_mpi_print (GCRYMPI_FMT_STD
, NULL
, 0, &n
, kparms
[i
]);
1690 log_error ("error formatting parameter: %s\n", gpg_strerror (rc
));
1694 n
= compute_tag_length (n
);
1701 log_error ("invalid paramters for p12_build\n");
1704 /* Now this all goes into a sequence. */
1706 n
= compute_tag_length (needed
);
1710 /* Encapsulate all into an octet string. */
1712 n
= compute_tag_length (needed
);
1716 /* Prepend the object identifier sequence. */
1717 oidseqlen
= 2 + DIM (oid_rsaEncryption
) + 2;
1718 needed
+= 2 + oidseqlen
;
1719 /* The version number. */
1721 /* And finally put the whole thing into a sequence. */
1723 n
= compute_tag_length (needed
);
1728 /* allocate 8 extra bytes for padding */
1729 plain
= gcry_malloc_secure (needed
+8);
1732 log_error ("error allocating encryption buffer\n");
1736 /* And now fill the plaintext buffer. */
1738 p
= store_tag_length (p
, TAG_SEQUENCE
, outseqlen
);
1739 /* Store version. */
1743 /* Store object identifier sequence. */
1744 p
= store_tag_length (p
, TAG_SEQUENCE
, oidseqlen
);
1745 p
= store_tag_length (p
, TAG_OBJECT_ID
, DIM (oid_rsaEncryption
));
1746 memcpy (p
, oid_rsaEncryption
, DIM (oid_rsaEncryption
));
1747 p
+= DIM (oid_rsaEncryption
);
1750 /* Start with the octet string. */
1751 p
= store_tag_length (p
, TAG_OCTET_STRING
, octstrlen
);
1752 p
= store_tag_length (p
, TAG_SEQUENCE
, inseqlen
);
1753 /* Store the key parameters. */
1757 for (i
=0; kparms
[i
]; i
++)
1760 rc
= gcry_mpi_print (GCRYMPI_FMT_STD
, NULL
, 0, &n
, kparms
[i
]);
1763 log_error ("oops: error formatting parameter: %s\n",
1768 p
= store_tag_length (p
, TAG_INTEGER
, n
);
1770 n
= plain
+ needed
- p
;
1771 rc
= gcry_mpi_print (GCRYMPI_FMT_STD
, p
, n
, &n
, kparms
[i
]);
1774 log_error ("oops: error storing parameter: %s\n",
1782 plainlen
= p
- plain
;
1783 assert (needed
== plainlen
);
1784 /* Append some pad characters; we already allocated extra space. */
1785 n
= 8 - plainlen
% 8;
1786 for (i
=0; i
< n
; i
++, plainlen
++)
1789 *r_length
= plainlen
;
1795 static unsigned char *
1796 build_key_bag (unsigned char *buffer
, size_t buflen
, char *salt
,
1797 const unsigned char *sha1hash
, const char *keyidstr
,
1800 size_t len
[11], needed
;
1801 unsigned char *p
, *keybag
;
1804 /* Walk 11 steps down to collect the info: */
1806 /* 10. The data goes into an octet string. */
1807 needed
= compute_tag_length (buflen
);
1810 /* 9. Prepend the algorithm identifier. */
1811 needed
+= DIM (data_3desiter2048
);
1813 /* 8. Put a sequence around. */
1815 needed
+= compute_tag_length (needed
);
1817 /* 7. Prepend a [0] tag. */
1819 needed
+= compute_tag_length (needed
);
1821 /* 6b. The attributes which are appended at the end. */
1823 needed
+= DIM (data_attrtemplate
) + 20;
1825 /* 6. Prepend the shroudedKeyBag OID. */
1826 needed
+= 2 + DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag
);
1828 /* 5+4. Put all into two sequences. */
1830 needed
+= compute_tag_length ( needed
);
1832 needed
+= compute_tag_length (needed
);
1834 /* 3. This all goes into an octet string. */
1836 needed
+= compute_tag_length (needed
);
1838 /* 2. Prepend another [0] tag. */
1840 needed
+= compute_tag_length (needed
);
1842 /* 1. Prepend the data OID. */
1843 needed
+= 2 + DIM (oid_data
);
1845 /* 0. Prepend another sequence. */
1847 needed
+= compute_tag_length (needed
);
1849 /* Now that we have all length information, allocate a buffer. */
1850 p
= keybag
= gcry_malloc (needed
);
1853 log_error ("error allocating buffer\n");
1857 /* Walk 11 steps up to store the data. */
1859 /* 0. Store the first sequence. */
1860 p
= store_tag_length (p
, TAG_SEQUENCE
, len
[0]);
1862 /* 1. Store the data OID. */
1863 p
= store_tag_length (p
, TAG_OBJECT_ID
, DIM (oid_data
));
1864 memcpy (p
, oid_data
, DIM (oid_data
));
1865 p
+= DIM (oid_data
);
1867 /* 2. Store a [0] tag. */
1868 p
= store_tag_length (p
, 0xa0, len
[2]);
1870 /* 3. And an octet string. */
1871 p
= store_tag_length (p
, TAG_OCTET_STRING
, len
[3]);
1873 /* 4+5. Two sequences. */
1874 p
= store_tag_length (p
, TAG_SEQUENCE
, len
[4]);
1875 p
= store_tag_length (p
, TAG_SEQUENCE
, len
[5]);
1877 /* 6. Store the shroudedKeyBag OID. */
1878 p
= store_tag_length (p
, TAG_OBJECT_ID
,
1879 DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag
));
1880 memcpy (p
, oid_pkcs_12_pkcs_8ShroudedKeyBag
,
1881 DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag
));
1882 p
+= DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag
);
1884 /* 7. Store a [0] tag. */
1885 p
= store_tag_length (p
, 0xa0, len
[7]);
1887 /* 8. Store a sequence. */
1888 p
= store_tag_length (p
, TAG_SEQUENCE
, len
[8]);
1890 /* 9. Now for the pre-encoded algorithm identifier and the salt. */
1891 memcpy (p
, data_3desiter2048
, DIM (data_3desiter2048
));
1892 memcpy (p
+ DATA_3DESITER2048_SALT_OFF
, salt
, 8);
1893 p
+= DIM (data_3desiter2048
);
1895 /* 10. And the octet string with the encrypted data. */
1896 p
= store_tag_length (p
, TAG_OCTET_STRING
, buflen
);
1897 memcpy (p
, buffer
, buflen
);
1900 /* Append the attributes whose length we calculated at step 2b. */
1905 memcpy (p
, data_attrtemplate
, DIM (data_attrtemplate
));
1906 for (i
=0; i
< 8; i
++)
1907 p
[DATA_ATTRTEMPLATE_KEYID_OFF
+2*i
+1] = keyidstr
[i
];
1908 p
+= DIM (data_attrtemplate
);
1909 memcpy (p
, sha1hash
, 20);
1914 keybaglen
= p
- keybag
;
1915 if (needed
!= keybaglen
)
1916 log_debug ("length mismatch: %lu, %lu\n",
1917 (unsigned long)needed
, (unsigned long)keybaglen
);
1919 *r_length
= keybaglen
;
1924 static unsigned char *
1925 build_cert_bag (unsigned char *buffer
, size_t buflen
, char *salt
,
1928 size_t len
[9], needed
;
1929 unsigned char *p
, *certbag
;
1932 /* Walk 9 steps down to collect the info: */
1934 /* 8. The data goes into an octet string. */
1935 needed
= compute_tag_length (buflen
);
1938 /* 7. The algorithm identifier. */
1939 needed
+= DIM (data_rc2iter2048
);
1941 /* 6. The data OID. */
1942 needed
+= 2 + DIM (oid_data
);
1944 /* 5. A sequence. */
1946 needed
+= compute_tag_length ( needed
);
1948 /* 4. An integer. */
1951 /* 3. A sequence. */
1953 needed
+= compute_tag_length (needed
);
1957 needed
+= compute_tag_length (needed
);
1959 /* 1. The encryptedData OID. */
1960 needed
+= 2 + DIM (oid_encryptedData
);
1962 /* 0. The first sequence. */
1964 needed
+= compute_tag_length (needed
);
1966 /* Now that we have all length information, allocate a buffer. */
1967 p
= certbag
= gcry_malloc (needed
);
1970 log_error ("error allocating buffer\n");
1974 /* Walk 9 steps up to store the data. */
1976 /* 0. Store the first sequence. */
1977 p
= store_tag_length (p
, TAG_SEQUENCE
, len
[0]);
1979 /* 1. Store the encryptedData OID. */
1980 p
= store_tag_length (p
, TAG_OBJECT_ID
, DIM (oid_encryptedData
));
1981 memcpy (p
, oid_encryptedData
, DIM (oid_encryptedData
));
1982 p
+= DIM (oid_encryptedData
);
1984 /* 2. Store a [0] tag. */
1985 p
= store_tag_length (p
, 0xa0, len
[2]);
1987 /* 3. Store a sequence. */
1988 p
= store_tag_length (p
, TAG_SEQUENCE
, len
[3]);
1990 /* 4. Store the integer 0. */
1995 /* 5. Store a sequence. */
1996 p
= store_tag_length (p
, TAG_SEQUENCE
, len
[5]);
1998 /* 6. Store the data OID. */
1999 p
= store_tag_length (p
, TAG_OBJECT_ID
, DIM (oid_data
));
2000 memcpy (p
, oid_data
, DIM (oid_data
));
2001 p
+= DIM (oid_data
);
2003 /* 7. Now for the pre-encoded algorithm identifier and the salt. */
2004 memcpy (p
, data_rc2iter2048
, DIM (data_rc2iter2048
));
2005 memcpy (p
+ DATA_RC2ITER2048_SALT_OFF
, salt
, 8);
2006 p
+= DIM (data_rc2iter2048
);
2008 /* 8. And finally the [0] tag with the encrypted data. */
2009 p
= store_tag_length (p
, 0x80, buflen
);
2010 memcpy (p
, buffer
, buflen
);
2012 certbaglen
= p
- certbag
;
2014 if (needed
!= certbaglen
)
2015 log_debug ("length mismatch: %lu, %lu\n",
2016 (unsigned long)needed
, (unsigned long)certbaglen
);
2018 *r_length
= certbaglen
;
2023 static unsigned char *
2024 build_cert_sequence (unsigned char *buffer
, size_t buflen
,
2025 const unsigned char *sha1hash
, const char *keyidstr
,
2028 size_t len
[8], needed
, n
;
2029 unsigned char *p
, *certseq
;
2033 assert (strlen (keyidstr
) == 8);
2035 /* Walk 8 steps down to collect the info: */
2037 /* 7. The data goes into an octet string. */
2038 needed
= compute_tag_length (buflen
);
2043 needed
+= compute_tag_length (needed
);
2046 needed
+= 2 + DIM (oid_x509Certificate_for_pkcs_12
);
2048 /* 4. A sequence. */
2050 needed
+= compute_tag_length (needed
);
2054 needed
+= compute_tag_length (needed
);
2056 /* 2b. The attributes which are appended at the end. */
2058 needed
+= DIM (data_attrtemplate
) + 20;
2061 needed
+= 2 + DIM (oid_pkcs_12_CertBag
);
2063 /* 1. A sequence. */
2065 needed
+= compute_tag_length (needed
);
2067 /* 0. The first sequence. */
2069 needed
+= compute_tag_length (needed
);
2071 /* Now that we have all length information, allocate a buffer. */
2072 p
= certseq
= gcry_malloc (needed
+ 8 /*(for padding)*/);
2075 log_error ("error allocating buffer\n");
2079 /* Walk 8 steps up to store the data. */
2081 /* 0. Store the first sequence. */
2082 p
= store_tag_length (p
, TAG_SEQUENCE
, len
[0]);
2084 /* 1. Store the second sequence. */
2085 p
= store_tag_length (p
, TAG_SEQUENCE
, len
[1]);
2087 /* 2. Store the pkcs12-cert-bag OID. */
2088 p
= store_tag_length (p
, TAG_OBJECT_ID
, DIM (oid_pkcs_12_CertBag
));
2089 memcpy (p
, oid_pkcs_12_CertBag
, DIM (oid_pkcs_12_CertBag
));
2090 p
+= DIM (oid_pkcs_12_CertBag
);
2092 /* 3. Store a [0] tag. */
2093 p
= store_tag_length (p
, 0xa0, len
[3]);
2095 /* 4. Store a sequence. */
2096 p
= store_tag_length (p
, TAG_SEQUENCE
, len
[4]);
2098 /* 5. Store the x509Certificate OID. */
2099 p
= store_tag_length (p
, TAG_OBJECT_ID
,
2100 DIM (oid_x509Certificate_for_pkcs_12
));
2101 memcpy (p
, oid_x509Certificate_for_pkcs_12
,
2102 DIM (oid_x509Certificate_for_pkcs_12
));
2103 p
+= DIM (oid_x509Certificate_for_pkcs_12
);
2105 /* 6. Store a [0] tag. */
2106 p
= store_tag_length (p
, 0xa0, len
[6]);
2108 /* 7. And the octet string with the actual certificate. */
2109 p
= store_tag_length (p
, TAG_OCTET_STRING
, buflen
);
2110 memcpy (p
, buffer
, buflen
);
2113 /* Append the attributes whose length we calculated at step 2b. */
2116 memcpy (p
, data_attrtemplate
, DIM (data_attrtemplate
));
2117 for (i
=0; i
< 8; i
++)
2118 p
[DATA_ATTRTEMPLATE_KEYID_OFF
+2*i
+1] = keyidstr
[i
];
2119 p
+= DIM (data_attrtemplate
);
2120 memcpy (p
, sha1hash
, 20);
2124 certseqlen
= p
- certseq
;
2125 if (needed
!= certseqlen
)
2126 log_debug ("length mismatch: %lu, %lu\n",
2127 (unsigned long)needed
, (unsigned long)certseqlen
);
2129 /* Append some pad characters; we already allocated extra space. */
2130 n
= 8 - certseqlen
% 8;
2131 for (i
=0; i
< n
; i
++, certseqlen
++)
2134 *r_length
= certseqlen
;
2139 /* Expect the RSA key parameters in KPARMS and a password in PW.
2140 Create a PKCS structure from it and return it as well as the length
2141 in R_LENGTH; return NULL in case of an error. If CHARSET is not
2142 NULL, re-encode PW to that character set. */
2144 p12_build (gcry_mpi_t
*kparms
, unsigned char *cert
, size_t certlen
,
2145 const char *pw
, const char *charset
, size_t *r_length
)
2147 unsigned char *buffer
= NULL
;
2150 struct buffer_s seqlist
[3];
2152 unsigned char sha1hash
[20];
2155 size_t pwbufsize
= 0;
2157 n
= buflen
= 0; /* (avoid compiler warning). */
2158 memset (sha1hash
, 0, 20);
2161 if (charset
&& pw
&& *pw
)
2166 size_t inbytes
, outbytes
;
2168 /* We assume that the converted passphrase is at max 2 times
2169 longer than its utf-8 encoding. */
2170 pwbufsize
= strlen (pw
)*2 + 1;
2171 pwbuf
= gcry_malloc_secure (pwbufsize
);
2174 log_error ("out of secure memory while converting passphrase\n");
2178 cd
= jnlib_iconv_open (charset
, "utf-8");
2179 if (cd
== (jnlib_iconv_t
)(-1))
2181 log_error ("can't convert passphrase to"
2182 " requested charset `%s': %s\n",
2183 charset
, strerror (errno
));
2189 inbytes
= strlen (pw
);
2191 outbytes
= pwbufsize
- 1;
2192 if ( jnlib_iconv (cd
, (const char **)&inptr
, &inbytes
,
2193 &outptr
, &outbytes
) == (size_t)-1)
2195 log_error ("error converting passphrase to"
2196 " requested charset `%s': %s\n",
2197 charset
, strerror (errno
));
2199 jnlib_iconv_close (cd
);
2203 jnlib_iconv_close (cd
);
2208 if (cert
&& certlen
)
2210 /* Calculate the hash value we need for the bag attributes. */
2211 gcry_md_hash_buffer (GCRY_MD_SHA1
, sha1hash
, cert
, certlen
);
2212 sprintf (keyidstr
, "%02x%02x%02x%02x",
2213 sha1hash
[16], sha1hash
[17], sha1hash
[18], sha1hash
[19]);
2215 /* Encode the certificate. */
2216 buffer
= build_cert_sequence (cert
, certlen
, sha1hash
, keyidstr
,
2222 gcry_randomize (salt
, 8, GCRY_STRONG_RANDOM
);
2223 crypt_block (buffer
, buflen
, salt
, 8, 2048, pw
,
2224 GCRY_CIPHER_RFC2268_40
, 1);
2226 /* Encode the encrypted stuff into a bag. */
2227 seqlist
[seqlistidx
].buffer
= build_cert_bag (buffer
, buflen
, salt
, &n
);
2228 seqlist
[seqlistidx
].length
= n
;
2231 if (!seqlist
[seqlistidx
].buffer
)
2239 /* Encode the key. */
2240 buffer
= build_key_sequence (kparms
, &buflen
);
2245 gcry_randomize (salt
, 8, GCRY_STRONG_RANDOM
);
2246 crypt_block (buffer
, buflen
, salt
, 8, 2048, pw
, GCRY_CIPHER_3DES
, 1);
2248 /* Encode the encrypted stuff into a bag. */
2249 if (cert
&& certlen
)
2250 seqlist
[seqlistidx
].buffer
= build_key_bag (buffer
, buflen
, salt
,
2251 sha1hash
, keyidstr
, &n
);
2253 seqlist
[seqlistidx
].buffer
= build_key_bag (buffer
, buflen
, salt
,
2255 seqlist
[seqlistidx
].length
= n
;
2258 if (!seqlist
[seqlistidx
].buffer
)
2263 seqlist
[seqlistidx
].buffer
= NULL
;
2264 seqlist
[seqlistidx
].length
= 0;
2266 buffer
= create_final (seqlist
, pw
, &buflen
);
2271 wipememory (pwbuf
, pwbufsize
);
2274 for ( ; seqlistidx
; seqlistidx
--)
2275 gcry_free (seqlist
[seqlistidx
].buffer
);
2277 *r_length
= buffer
? buflen
: 0;
2285 cert_cb (void *opaque
, const unsigned char *cert
, size_t certlen
)
2287 printf ("got a certificate of %u bytes length\n", certlen
);
2291 main (int argc
, char **argv
)
2301 fprintf (stderr
, "usage: testp12 file passphrase\n");
2305 gcry_control (GCRYCTL_DISABLE_SECMEM
, NULL
);
2306 gcry_control (GCRYCTL_INITIALIZATION_FINISHED
, NULL
);
2308 fp
= fopen (argv
[1], "rb");
2311 fprintf (stderr
, "can't open `%s': %s\n", argv
[1], strerror (errno
));
2315 if (fstat (fileno(fp
), &st
))
2317 fprintf (stderr
, "can't stat `%s': %s\n", argv
[1], strerror (errno
));
2321 buflen
= st
.st_size
;
2322 buf
= gcry_malloc (buflen
+1);
2323 if (!buf
|| fread (buf
, buflen
, 1, fp
) != 1)
2325 fprintf (stderr
, "error reading `%s': %s\n", argv
[1], strerror (errno
));
2330 result
= p12_parse (buf
, buflen
, argv
[2], cert_cb
, NULL
);
2334 unsigned char *tmpbuf
;
2336 for (i
=0; result
[i
]; i
++)
2338 rc
= gcry_mpi_aprint (GCRYMPI_FMT_HEX
, &tmpbuf
,
2341 printf ("%d: [error printing number: %s]\n",
2342 i
, gpg_strerror (rc
));
2345 printf ("%d: %s\n", i
, tmpbuf
);
2357 compile-command: "gcc -Wall -O0 -g -DTEST=1 -o minip12 minip12.c ../jnlib/libjnlib.a -L /usr/local/lib -lgcrypt -lgpg-error"