1
/* minip12.c - A minimal pkcs-12 implementation.
2
* Copyright (C) 2002, 2003, 2004 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 2 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, write to the Free Software
18
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
36
#include "../jnlib/logging.h"
40
#define DIM(v) (sizeof(v)/sizeof((v)[0]))
61
TAG_OBJECT_DESCRIPTOR = 7,
65
TAG_EMBEDDED_PDV = 11,
67
TAG_REALTIVE_OID = 13,
70
TAG_NUMERIC_STRING = 18,
71
TAG_PRINTABLE_STRING = 19,
72
TAG_TELETEX_STRING = 20,
73
TAG_VIDEOTEX_STRING = 21,
76
TAG_GENERALIZED_TIME = 24,
77
TAG_GRAPHIC_STRING = 25,
78
TAG_VISIBLE_STRING = 26,
79
TAG_GENERAL_STRING = 27,
80
TAG_UNIVERSAL_STRING = 28,
81
TAG_CHARACTER_STRING = 29,
86
static unsigned char const oid_data[9] = {
87
0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01 };
88
static unsigned char const oid_encryptedData[9] = {
89
0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x06 };
90
static unsigned char const oid_pkcs_12_pkcs_8ShroudedKeyBag[11] = {
91
0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x0A, 0x01, 0x02 };
92
static unsigned char const oid_pkcs_12_CertBag[11] = {
93
0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x0A, 0x01, 0x03 };
94
static unsigned char const oid_pkcs_12_CrlBag[11] = {
95
0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x0A, 0x01, 0x04 };
97
static unsigned char const oid_pbeWithSHAAnd3_KeyTripleDES_CBC[10] = {
98
0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x03 };
99
static unsigned char const oid_pbeWithSHAAnd40BitRC2_CBC[10] = {
100
0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x06 };
101
static unsigned char const oid_x509Certificate_for_pkcs_12[10] = {
102
0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x16, 0x01 };
105
static unsigned char const oid_rsaEncryption[9] = {
106
0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01 };
109
static unsigned char const data_3desiter2048[30] = {
110
0x30, 0x1C, 0x06, 0x0A, 0x2A, 0x86, 0x48, 0x86,
111
0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x03, 0x30, 0x0E,
112
0x04, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
113
0xFF, 0xFF, 0x02, 0x02, 0x08, 0x00 };
114
#define DATA_3DESITER2048_SALT_OFF 18
116
static unsigned char const data_rc2iter2048[30] = {
117
0x30, 0x1C, 0x06, 0x0A, 0x2A, 0x86, 0x48, 0x86,
118
0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x06, 0x30, 0x0E,
119
0x04, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
120
0xFF, 0xFF, 0x02, 0x02, 0x08, 0x00 };
121
#define DATA_RC2ITER2048_SALT_OFF 18
126
unsigned char *buffer;
136
unsigned long length; /* length part of the TLV */
138
int ndef; /* It is an indefinite length */
142
/* Parse the buffer at the address BUFFER which is of SIZE and return
143
the tag and the length part from the TLV triplet. Update BUFFER
144
and SIZE on success. */
146
parse_tag (unsigned char const **buffer, size_t *size, struct tag_info *ti)
150
const unsigned char *buf = *buffer;
151
size_t length = *size;
159
return -1; /* premature eof */
160
c = *buf++; length--;
163
ti->class = (c & 0xc0) >> 6;
164
ti->is_constructed = !!(c & 0x20);
174
return -1; /* premature eof */
175
c = *buf++; length--;
185
return -1; /* prematureeof */
186
c = *buf++; length--;
194
return -1; /* forbidden length value */
197
unsigned long len = 0;
198
int count = c & 0x7f;
200
for (; count; count--)
204
return -1; /* premature_eof */
205
c = *buf++; length--;
212
if (ti->class == UNIVERSAL && !ti->tag)
215
if (ti->length > length)
216
return -1; /* data larger than buffer. */
225
string_to_key (int id, char *salt, int iter, const char *pw,
226
int req_keylen, unsigned char *keybuf)
230
gcry_mpi_t num_b1 = NULL;
232
unsigned char hash[20], buf_b[64], buf_i[128], *p;
240
log_error ("password too long\n");
244
/* Store salt and password in BUF_I */
246
for(i=0; i < 64; i++)
248
for(i=j=0; i < 64; i += 2)
252
if (++j > pwlen) /* Note, that we include the trailing zero */
258
rc = gcry_md_open (&md, GCRY_MD_SHA1, 0);
261
log_error ( "gcry_md_open failed: %s\n", gpg_strerror (rc));
264
for(i=0; i < 64; i++)
265
gcry_md_putc (md, id);
266
gcry_md_write (md, buf_i, 128);
267
memcpy (hash, gcry_md_read (md, 0), 20);
269
for (i=1; i < iter; i++)
270
gcry_md_hash_buffer (GCRY_MD_SHA1, hash, hash, 20);
272
for (i=0; i < 20 && cur_keylen < req_keylen; i++)
273
keybuf[cur_keylen++] = hash[i];
274
if (cur_keylen == req_keylen)
276
gcry_mpi_release (num_b1);
277
return 0; /* ready */
280
/* need more bytes. */
281
for(i=0; i < 64; i++)
282
buf_b[i] = hash[i % 20];
283
rc = gcry_mpi_scan (&num_b1, GCRYMPI_FMT_USG, buf_b, 64, &n);
286
log_error ( "gcry_mpi_scan failed: %s\n", gpg_strerror (rc));
289
gcry_mpi_add_ui (num_b1, num_b1, 1);
290
for (i=0; i < 128; i += 64)
294
rc = gcry_mpi_scan (&num_ij, GCRYMPI_FMT_USG, buf_i + i, 64, &n);
297
log_error ( "gcry_mpi_scan failed: %s\n",
301
gcry_mpi_add (num_ij, num_ij, num_b1);
302
gcry_mpi_clear_highbit (num_ij, 64*8);
303
rc = gcry_mpi_print (GCRYMPI_FMT_USG, buf_i + i, 64, &n, num_ij);
306
log_error ( "gcry_mpi_print failed: %s\n",
310
gcry_mpi_release (num_ij);
317
set_key_iv (gcry_cipher_hd_t chd, char *salt, int iter, const char *pw,
320
unsigned char keybuf[24];
323
assert (keybytes == 5 || keybytes == 24);
324
if (string_to_key (1, salt, iter, pw, keybytes, keybuf))
326
rc = gcry_cipher_setkey (chd, keybuf, keybytes);
329
log_error ( "gcry_cipher_setkey failed: %s\n", gpg_strerror (rc));
333
if (string_to_key (2, salt, iter, pw, 8, keybuf))
335
rc = gcry_cipher_setiv (chd, keybuf, 8);
338
log_error ("gcry_cipher_setiv failed: %s\n", gpg_strerror (rc));
346
crypt_block (unsigned char *buffer, size_t length, char *salt, int iter,
347
const char *pw, int cipher_algo, int encrypt)
349
gcry_cipher_hd_t chd;
352
rc = gcry_cipher_open (&chd, cipher_algo, GCRY_CIPHER_MODE_CBC, 0);
355
log_error ( "gcry_cipher_open failed: %s\n", gpg_strerror(rc));
356
wipememory (buffer, length);
359
if (set_key_iv (chd, salt, iter, pw,
360
cipher_algo == GCRY_CIPHER_RFC2268_40? 5:24))
362
wipememory (buffer, length);
366
rc = encrypt? gcry_cipher_encrypt (chd, buffer, length, NULL, 0)
367
: gcry_cipher_decrypt (chd, buffer, length, NULL, 0);
371
wipememory (buffer, length);
372
log_error ( "en/de-crytion failed: %s\n", gpg_strerror (rc));
377
gcry_cipher_close (chd);
383
parse_bag_encrypted_data (const unsigned char *buffer, size_t length,
384
int startoffset, const char *pw,
385
void (*certcb)(void*, const unsigned char*, size_t),
389
const unsigned char *p = buffer;
394
unsigned char *plain = NULL;
398
if (parse_tag (&p, &n, &ti))
400
if (ti.class != CONTEXT || ti.tag)
402
if (parse_tag (&p, &n, &ti))
404
if (ti.tag != TAG_SEQUENCE)
407
where = "bag.encryptedData.version";
408
if (parse_tag (&p, &n, &ti))
410
if (ti.tag != TAG_INTEGER || ti.length != 1 || *p != 0)
413
if (parse_tag (&p, &n, &ti))
415
if (ti.tag != TAG_SEQUENCE)
418
where = "bag.encryptedData.data";
419
if (parse_tag (&p, &n, &ti))
421
if (ti.tag != TAG_OBJECT_ID || ti.length != DIM(oid_data)
422
|| memcmp (p, oid_data, DIM(oid_data)))
427
where = "bag.encryptedData.keyinfo";
428
if (parse_tag (&p, &n, &ti))
430
if (ti.class || ti.tag != TAG_SEQUENCE)
432
if (parse_tag (&p, &n, &ti))
434
if (!ti.class && ti.tag == TAG_OBJECT_ID
435
&& ti.length == DIM(oid_pbeWithSHAAnd40BitRC2_CBC)
436
&& !memcmp (p, oid_pbeWithSHAAnd40BitRC2_CBC,
437
DIM(oid_pbeWithSHAAnd40BitRC2_CBC)))
439
p += DIM(oid_pbeWithSHAAnd40BitRC2_CBC);
440
n -= DIM(oid_pbeWithSHAAnd40BitRC2_CBC);
445
where = "rc2-params";
446
if (parse_tag (&p, &n, &ti))
448
if (ti.class || ti.tag != TAG_SEQUENCE)
450
if (parse_tag (&p, &n, &ti))
452
if (ti.class || ti.tag != TAG_OCTET_STRING || ti.length != 8 )
457
if (parse_tag (&p, &n, &ti))
459
if (ti.class || ti.tag != TAG_INTEGER || !ti.length )
461
for (iter=0; ti.length; ti.length--)
464
iter |= (*p++) & 0xff;
468
where = "rc2-ciphertext";
469
if (parse_tag (&p, &n, &ti))
471
if (ti.class != CONTEXT || ti.tag != 0 || !ti.length )
474
log_info ("%lu bytes of RC2 encrypted text\n", ti.length);
476
plain = gcry_malloc_secure (ti.length);
479
log_error ("error allocating decryption buffer\n");
482
memcpy (plain, p, ti.length);
483
crypt_block (plain, ti.length, salt, iter, pw, GCRY_CIPHER_RFC2268_40, 0);
489
/* FILE *fp = fopen ("tmp-rc2-plain.der", "wb"); */
490
/* if (!fp || fwrite (p, n, 1, fp) != 1) */
495
where = "outer.outer.seq";
496
if (parse_tag (&p, &n, &ti))
501
if (ti.class || ti.tag != TAG_SEQUENCE)
507
if (parse_tag (&p, &n, &ti))
513
/* Loop over all certificates inside the bab. */
518
where = "certbag.nextcert";
519
if (ti.class || ti.tag != TAG_SEQUENCE)
522
where = "certbag.objectidentifier";
523
if (parse_tag (&p, &n, &ti))
525
if (ti.class || ti.tag != TAG_OBJECT_ID)
527
if ( ti.length == DIM(oid_pkcs_12_CertBag)
528
&& !memcmp (p, oid_pkcs_12_CertBag, DIM(oid_pkcs_12_CertBag)))
530
p += DIM(oid_pkcs_12_CertBag);
531
n -= DIM(oid_pkcs_12_CertBag);
533
else if ( ti.length == DIM(oid_pkcs_12_CrlBag)
534
&& !memcmp (p, oid_pkcs_12_CrlBag, DIM(oid_pkcs_12_CrlBag)))
536
p += DIM(oid_pkcs_12_CrlBag);
537
n -= DIM(oid_pkcs_12_CrlBag);
543
where = "certbag.before.certheader";
544
if (parse_tag (&p, &n, &ti))
546
if (ti.class != CONTEXT || ti.tag)
550
log_info ("skipping unsupported crlBag\n");
556
if (parse_tag (&p, &n, &ti))
558
if (ti.class || ti.tag != TAG_SEQUENCE)
560
if (parse_tag (&p, &n, &ti))
562
if (ti.class || ti.tag != TAG_OBJECT_ID
563
|| ti.length != DIM(oid_x509Certificate_for_pkcs_12)
564
|| memcmp (p, oid_x509Certificate_for_pkcs_12,
565
DIM(oid_x509Certificate_for_pkcs_12)))
567
p += DIM(oid_x509Certificate_for_pkcs_12);
568
n -= DIM(oid_x509Certificate_for_pkcs_12);
570
where = "certbag.before.octetstring";
571
if (parse_tag (&p, &n, &ti))
573
if (ti.class != CONTEXT || ti.tag)
575
if (parse_tag (&p, &n, &ti))
577
if (ti.class || ti.tag != TAG_OCTET_STRING || ti.ndef)
580
/* Return the certificate. */
582
certcb (certcbarg, p, ti.length);
588
/* Ugly hack to cope with the padding: Forget about the rest if
589
that it is less than the cipher's block length. */
593
/* Skip the optional SET with the pkcs12 cert attributes. */
596
where = "bag.attributes";
597
if (parse_tag (&p, &n, &ti))
599
if (!ti.class && ti.tag == TAG_SEQUENCE)
600
; /* No attributes. */
601
else if (!ti.class && ti.tag == TAG_SET && !ti.ndef)
602
{ /* The optional SET. */
607
if (n && parse_tag (&p, &n, &ti))
620
log_error ("encryptedData error at \"%s\", offset %u\n",
621
where, (p - buffer)+startoffset);
624
/* Note, that the following string might be used by other programs
625
to check for a bad passphrase; it should therefore not be
626
translated or changed. */
627
log_error ("possibly bad passphrase given\n");
633
parse_bag_data (const unsigned char *buffer, size_t length, int startoffset,
638
const unsigned char *p = buffer;
644
unsigned char *plain = NULL;
645
gcry_mpi_t *result = NULL;
649
if (parse_tag (&p, &n, &ti))
651
if (ti.class != CONTEXT || ti.tag)
653
if (parse_tag (&p, &n, &ti))
655
if (ti.class || ti.tag != TAG_OCTET_STRING)
658
where = "data.outerseqs";
659
if (parse_tag (&p, &n, &ti))
661
if (ti.class || ti.tag != TAG_SEQUENCE)
663
if (parse_tag (&p, &n, &ti))
665
if (ti.class || ti.tag != TAG_SEQUENCE)
668
where = "data.objectidentifier";
669
if (parse_tag (&p, &n, &ti))
671
if (ti.class || ti.tag != TAG_OBJECT_ID
672
|| ti.length != DIM(oid_pkcs_12_pkcs_8ShroudedKeyBag)
673
|| memcmp (p, oid_pkcs_12_pkcs_8ShroudedKeyBag,
674
DIM(oid_pkcs_12_pkcs_8ShroudedKeyBag)))
676
p += DIM(oid_pkcs_12_pkcs_8ShroudedKeyBag);
677
n -= DIM(oid_pkcs_12_pkcs_8ShroudedKeyBag);
679
where = "shrouded,outerseqs";
680
if (parse_tag (&p, &n, &ti))
682
if (ti.class != CONTEXT || ti.tag)
684
if (parse_tag (&p, &n, &ti))
686
if (ti.class || ti.tag != TAG_SEQUENCE)
688
if (parse_tag (&p, &n, &ti))
690
if (ti.class || ti.tag != TAG_SEQUENCE)
692
if (parse_tag (&p, &n, &ti))
694
if (ti.class || ti.tag != TAG_OBJECT_ID
695
|| ti.length != DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC)
696
|| memcmp (p, oid_pbeWithSHAAnd3_KeyTripleDES_CBC,
697
DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC)))
699
p += DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC);
700
n -= DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC);
702
where = "3des-params";
703
if (parse_tag (&p, &n, &ti))
705
if (ti.class || ti.tag != TAG_SEQUENCE)
707
if (parse_tag (&p, &n, &ti))
709
if (ti.class || ti.tag != TAG_OCTET_STRING || ti.length != 8 )
714
if (parse_tag (&p, &n, &ti))
716
if (ti.class || ti.tag != TAG_INTEGER || !ti.length )
718
for (iter=0; ti.length; ti.length--)
721
iter |= (*p++) & 0xff;
725
where = "3des-ciphertext";
726
if (parse_tag (&p, &n, &ti))
728
if (ti.class || ti.tag != TAG_OCTET_STRING || !ti.length )
731
log_info ("%lu bytes of 3DES encrypted text\n", ti.length);
733
plain = gcry_malloc_secure (ti.length);
736
log_error ("error allocating decryption buffer\n");
739
memcpy (plain, p, ti.length);
740
crypt_block (plain, ti.length, salt, iter, pw, GCRY_CIPHER_3DES, 0);
745
where = "decrypted-text";
746
if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE)
748
if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_INTEGER
749
|| ti.length != 1 || *p)
752
if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE)
755
if (parse_tag (&p, &n, &ti))
760
if (ti.class || ti.tag != TAG_OBJECT_ID
761
|| ti.length != DIM(oid_rsaEncryption)
762
|| memcmp (p, oid_rsaEncryption,
763
DIM(oid_rsaEncryption)))
765
p += DIM (oid_rsaEncryption);
766
n -= DIM (oid_rsaEncryption);
774
if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_OCTET_STRING)
776
if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE)
780
result = gcry_calloc (10, sizeof *result);
783
log_error ( "error allocating result array\n");
788
where = "reading.key-parameters";
789
for (result_count=0; len && result_count < 9;)
791
if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_INTEGER)
799
if (!result_count && ti.length == 1 && !*p)
800
; /* ignore the very first one if it is a 0 */
803
rc = gcry_mpi_scan (result+result_count, GCRYMPI_FMT_USG, p,
807
log_error ("error parsing key parameter: %s\n",
825
for (i=0; result[i]; i++)
826
gcry_mpi_release (result[i]);
829
log_error ( "data error at \"%s\", offset %u\n",
830
where, (p - buffer) + startoffset);
835
/* Parse a PKCS12 object and return an array of MPI representing the
836
secret key parameters. This is a very limited implementation in
837
that it is only able to look for 3DES encoded encryptedData and
838
tries to extract the first private key object it finds. In case of
839
an error NULL is returned. CERTCB and CERRTCBARG are used to pass
840
X.509 certificates back to the caller. */
842
p12_parse (const unsigned char *buffer, size_t length, const char *pw,
843
void (*certcb)(void*, const unsigned char*, size_t),
847
const unsigned char *p = buffer;
850
int bagseqlength, len;
853
if (parse_tag (&p, &n, &ti))
855
if (ti.tag != TAG_SEQUENCE)
858
where = "pfxVersion";
859
if (parse_tag (&p, &n, &ti))
861
if (ti.tag != TAG_INTEGER || ti.length != 1 || *p != 3)
866
if (parse_tag (&p, &n, &ti))
868
if (ti.tag != TAG_SEQUENCE)
870
if (parse_tag (&p, &n, &ti))
872
if (ti.tag != TAG_OBJECT_ID || ti.length != DIM(oid_data)
873
|| memcmp (p, oid_data, DIM(oid_data)))
878
if (parse_tag (&p, &n, &ti))
880
if (ti.class != CONTEXT || ti.tag)
882
if (parse_tag (&p, &n, &ti))
884
if (ti.class != UNIVERSAL || ti.tag != TAG_OCTET_STRING)
888
if (parse_tag (&p, &n, &ti))
890
if (ti.class != UNIVERSAL || ti.tag != TAG_SEQUENCE)
892
bagseqlength = ti.length;
895
/*log_debug ( "at offset %u\n", (p - buffer));*/
896
where = "bag-sequence";
897
if (parse_tag (&p, &n, &ti))
899
if (ti.class != UNIVERSAL || ti.tag != TAG_SEQUENCE)
902
if (bagseqlength < ti.nhdr)
904
bagseqlength -= ti.nhdr;
905
if (bagseqlength < ti.length)
907
bagseqlength -= ti.length;
910
if (parse_tag (&p, &n, &ti))
913
if (ti.tag == TAG_OBJECT_ID && ti.length == DIM(oid_encryptedData)
914
&& !memcmp (p, oid_encryptedData, DIM(oid_encryptedData)))
916
p += DIM(oid_encryptedData);
917
n -= DIM(oid_encryptedData);
918
len -= DIM(oid_encryptedData);
919
where = "bag.encryptedData";
920
if (parse_bag_encrypted_data (p, n, (p - buffer), pw,
924
else if (ti.tag == TAG_OBJECT_ID && ti.length == DIM(oid_data)
925
&& !memcmp (p, oid_data, DIM(oid_data)))
929
len -= DIM(oid_data);
930
return parse_bag_data (p, n, (p-buffer), pw);
933
log_info ( "unknown bag type - skipped\n");
935
if (len < 0 || len > n)
943
log_error ("error at \"%s\", offset %u\n", where, (p - buffer));
950
compute_tag_length (size_t n)
955
needed += 2; /* tag and one length byte */
957
needed += 3; /* tag, number of length bytes, 1 length byte */
959
needed += 4; /* tag, number of length bytes, 2 length bytes */
962
log_error ("object too larger to encode\n");
968
static unsigned char *
969
store_tag_length (unsigned char *p, int tag, size_t n)
971
if (tag == TAG_SEQUENCE)
972
tag |= 0x20; /* constructed */
993
/* Create the final PKCS-12 object from the sequences contained in
994
SEQLIST. That array is terminated with an NULL object */
995
static unsigned char *
996
create_final (struct buffer_s *sequences, size_t *r_length)
1001
unsigned char *result, *p;
1004
/* 8 steps to create the pkcs#12 Krampf. */
1006
/* 7. All the buffers. */
1007
for (i=0; sequences[i].buffer; i++)
1008
needed += sequences[i].length;
1010
/* 6. This goes into a sequences. */
1012
n = compute_tag_length (needed);
1015
/* 5. Encapsulate all in an octet string. */
1017
n = compute_tag_length (needed);
1020
/* 4. And tag it with [0]. */
1022
n = compute_tag_length (needed);
1025
/* 3. Prepend an data OID. */
1026
needed += 2 + DIM (oid_data);
1028
/* 2. Put all into a sequences. */
1030
n = compute_tag_length (needed);
1033
/* 1. Prepend the version integer 3. */
1036
/* 0. And the final outer sequence. */
1038
n = compute_tag_length (needed);
1041
/* Allocate a buffer. */
1042
result = gcry_malloc (needed);
1045
log_error ("error allocating buffer\n");
1050
/* 0. Store the very outer sequence. */
1051
p = store_tag_length (p, TAG_SEQUENCE, len[0]);
1053
/* 1. Store the version integer 3. */
1058
/* 2. Store another sequence. */
1059
p = store_tag_length (p, TAG_SEQUENCE, len[2]);
1061
/* 3. Store the data OID. */
1062
p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_data));
1063
memcpy (p, oid_data, DIM (oid_data));
1064
p += DIM (oid_data);
1066
/* 4. Next comes a context tag. */
1067
p = store_tag_length (p, 0xa0, len[4]);
1069
/* 5. And an octet string. */
1070
p = store_tag_length (p, TAG_OCTET_STRING, len[5]);
1072
/* 6. And the inner sequence. */
1073
p = store_tag_length (p, TAG_SEQUENCE, len[6]);
1075
/* 7. Append all the buffers. */
1076
for (i=0; sequences[i].buffer; i++)
1078
memcpy (p, sequences[i].buffer, sequences[i].length);
1079
p += sequences[i].length;
1083
resultlen = p - result;
1084
if (needed != resultlen)
1085
log_debug ("length mismatch: %u, %u\n", needed, resultlen);
1087
*r_length = resultlen;
1092
/* Build a DER encoded SEQUENCE with the key:
1097
OBJECT IDENTIFIER rsaEncryption (1 2 840 113549 1 1 1)
1100
OCTET STRING, encapsulates {
1116
static unsigned char *
1117
build_key_sequence (gcry_mpi_t *kparms, size_t *r_length)
1121
unsigned char *plain, *p;
1123
size_t outseqlen, oidseqlen, octstrlen, inseqlen;
1125
needed = 3; /* The version(?) integer of value 0. */
1126
for (i=0; kparms[i]; i++)
1129
rc = gcry_mpi_print (GCRYMPI_FMT_STD, NULL, 0, &n, kparms[i]);
1132
log_error ("error formatting parameter: %s\n", gpg_strerror (rc));
1136
n = compute_tag_length (n);
1143
log_error ("invalid paramters for p12_build\n");
1146
/* Now this all goes into a sequence. */
1148
n = compute_tag_length (needed);
1152
/* Encapsulate all into an octet string. */
1154
n = compute_tag_length (needed);
1158
/* Prepend the object identifier sequence. */
1159
oidseqlen = 2 + DIM (oid_rsaEncryption) + 2;
1160
needed += 2 + oidseqlen;
1161
/* The version number. */
1163
/* And finally put the whole thing into a sequence. */
1165
n = compute_tag_length (needed);
1170
/* allocate 8 extra bytes for padding */
1171
plain = gcry_malloc_secure (needed+8);
1174
log_error ("error allocating encryption buffer\n");
1178
/* And now fill the plaintext buffer. */
1180
p = store_tag_length (p, TAG_SEQUENCE, outseqlen);
1181
/* Store version. */
1185
/* Store object identifier sequence. */
1186
p = store_tag_length (p, TAG_SEQUENCE, oidseqlen);
1187
p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_rsaEncryption));
1188
memcpy (p, oid_rsaEncryption, DIM (oid_rsaEncryption));
1189
p += DIM (oid_rsaEncryption);
1192
/* Start with the octet string. */
1193
p = store_tag_length (p, TAG_OCTET_STRING, octstrlen);
1194
p = store_tag_length (p, TAG_SEQUENCE, inseqlen);
1195
/* Store the key parameters. */
1199
for (i=0; kparms[i]; i++)
1202
rc = gcry_mpi_print (GCRYMPI_FMT_STD, NULL, 0, &n, kparms[i]);
1205
log_error ("oops: error formatting parameter: %s\n",
1210
p = store_tag_length (p, TAG_INTEGER, n);
1212
n = plain + needed - p;
1213
rc = gcry_mpi_print (GCRYMPI_FMT_STD, p, n, &n, kparms[i]);
1216
log_error ("oops: error storing parameter: %s\n",
1224
plainlen = p - plain;
1225
assert (needed == plainlen);
1226
/* Append some pad characters; we already allocated extra space. */
1227
n = 8 - plainlen % 8;
1228
for (;(plainlen % 8); plainlen++)
1231
*r_length = plainlen;
1237
static unsigned char *
1238
build_key_bag (unsigned char *buffer, size_t buflen, char *salt,
1241
size_t len[11], needed;
1242
unsigned char *p, *keybag;
1245
/* Walk 11 steps down to collect the info: */
1247
/* 10. The data goes into an octet string. */
1248
needed = compute_tag_length (buflen);
1251
/* 9. Prepend the algorithm identifier. */
1252
needed += DIM (data_3desiter2048);
1254
/* 8. Put a sequence around. */
1256
needed += compute_tag_length (needed);
1258
/* 7. Prepend a [0] tag. */
1260
needed += compute_tag_length (needed);
1262
/* 6. Prepend the shroudedKeyBag OID. */
1263
needed += 2 + DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag);
1265
/* 5+4. Put all into two sequences. */
1267
needed += compute_tag_length ( needed);
1269
needed += compute_tag_length (needed);
1271
/* 3. This all goes into an octet string. */
1273
needed += compute_tag_length (needed);
1275
/* 2. Prepend another [0] tag. */
1277
needed += compute_tag_length (needed);
1279
/* 1. Prepend the data OID. */
1280
needed += 2 + DIM (oid_data);
1282
/* 0. Prepend another sequence. */
1284
needed += compute_tag_length (needed);
1286
/* Now that we have all length information, allocate a buffer. */
1287
p = keybag = gcry_malloc (needed);
1290
log_error ("error allocating buffer\n");
1294
/* Walk 11 steps up to store the data. */
1296
/* 0. Store the first sequence. */
1297
p = store_tag_length (p, TAG_SEQUENCE, len[0]);
1299
/* 1. Store the data OID. */
1300
p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_data));
1301
memcpy (p, oid_data, DIM (oid_data));
1302
p += DIM (oid_data);
1304
/* 2. Store a [0] tag. */
1305
p = store_tag_length (p, 0xa0, len[2]);
1307
/* 3. And an octet string. */
1308
p = store_tag_length (p, TAG_OCTET_STRING, len[3]);
1310
/* 4+5. Two sequences. */
1311
p = store_tag_length (p, TAG_SEQUENCE, len[4]);
1312
p = store_tag_length (p, TAG_SEQUENCE, len[5]);
1314
/* 6. Store the shroudedKeyBag OID. */
1315
p = store_tag_length (p, TAG_OBJECT_ID,
1316
DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag));
1317
memcpy (p, oid_pkcs_12_pkcs_8ShroudedKeyBag,
1318
DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag));
1319
p += DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag);
1321
/* 7. Store a [0] tag. */
1322
p = store_tag_length (p, 0xa0, len[7]);
1324
/* 8. Store a sequence. */
1325
p = store_tag_length (p, TAG_SEQUENCE, len[8]);
1327
/* 9. Now for the pre-encoded algorithm identifier and the salt. */
1328
memcpy (p, data_3desiter2048, DIM (data_3desiter2048));
1329
memcpy (p + DATA_3DESITER2048_SALT_OFF, salt, 8);
1330
p += DIM (data_3desiter2048);
1332
/* 10. And finally the octet string with the encrypted data. */
1333
p = store_tag_length (p, TAG_OCTET_STRING, buflen);
1334
memcpy (p, buffer, buflen);
1336
keybaglen = p - keybag;
1338
if (needed != keybaglen)
1339
log_debug ("length mismatch: %u, %u\n", needed, keybaglen);
1341
*r_length = keybaglen;
1346
static unsigned char *
1347
build_cert_bag (unsigned char *buffer, size_t buflen, char *salt,
1350
size_t len[9], needed;
1351
unsigned char *p, *certbag;
1354
/* Walk 9 steps down to collect the info: */
1356
/* 8. The data goes into an octet string. */
1357
needed = compute_tag_length (buflen);
1360
/* 7. The algorithm identifier. */
1361
needed += DIM (data_rc2iter2048);
1363
/* 6. The data OID. */
1364
needed += 2 + DIM (oid_data);
1366
/* 5. A sequence. */
1368
needed += compute_tag_length ( needed);
1370
/* 4. An integer. */
1373
/* 3. A sequence. */
1375
needed += compute_tag_length (needed);
1379
needed += compute_tag_length (needed);
1381
/* 1. The encryptedData OID. */
1382
needed += 2 + DIM (oid_encryptedData);
1384
/* 0. The first sequence. */
1386
needed += compute_tag_length (needed);
1388
/* Now that we have all length information, allocate a buffer. */
1389
p = certbag = gcry_malloc (needed);
1392
log_error ("error allocating buffer\n");
1396
/* Walk 9 steps up to store the data. */
1398
/* 0. Store the first sequence. */
1399
p = store_tag_length (p, TAG_SEQUENCE, len[0]);
1401
/* 1. Store the encryptedData OID. */
1402
p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_encryptedData));
1403
memcpy (p, oid_encryptedData, DIM (oid_encryptedData));
1404
p += DIM (oid_encryptedData);
1406
/* 2. Store a [0] tag. */
1407
p = store_tag_length (p, 0xa0, len[2]);
1409
/* 3. Store a sequence. */
1410
p = store_tag_length (p, TAG_SEQUENCE, len[3]);
1412
/* 4. Store the integer 0. */
1417
/* 5. Store a sequence. */
1418
p = store_tag_length (p, TAG_SEQUENCE, len[5]);
1420
/* 6. Store the data OID. */
1421
p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_data));
1422
memcpy (p, oid_data, DIM (oid_data));
1423
p += DIM (oid_data);
1425
/* 7. Now for the pre-encoded algorithm identifier and the salt. */
1426
memcpy (p, data_rc2iter2048, DIM (data_rc2iter2048));
1427
memcpy (p + DATA_RC2ITER2048_SALT_OFF, salt, 8);
1428
p += DIM (data_rc2iter2048);
1430
/* 8. And finally the [0] tag with the encrypted data. */
1431
p = store_tag_length (p, 0xa0, buflen);
1432
memcpy (p, buffer, buflen);
1434
certbaglen = p - certbag;
1436
if (needed != certbaglen)
1437
log_debug ("length mismatch: %u, %u\n", needed, certbaglen);
1439
*r_length = certbaglen;
1444
static unsigned char *
1445
build_cert_sequence (unsigned char *buffer, size_t buflen, size_t *r_length)
1447
size_t len[8], needed, n;
1448
unsigned char *p, *certseq;
1451
/* Walk 8 steps down to collect the info: */
1453
/* 7. The data goes into an octet string. */
1454
needed = compute_tag_length (buflen);
1459
needed += compute_tag_length (needed);
1462
needed += 2 + DIM (oid_x509Certificate_for_pkcs_12);
1464
/* 4. A sequence. */
1466
needed += compute_tag_length (needed);
1470
needed += compute_tag_length (needed);
1473
needed += 2 + DIM (oid_pkcs_12_CertBag);
1475
/* 1. A sequence. */
1477
needed += compute_tag_length (needed);
1479
/* 0. The first sequence. */
1481
needed += compute_tag_length (needed);
1483
/* Now that we have all length information, allocate a buffer. */
1484
p = certseq = gcry_malloc (needed + 8 /*(for padding)*/);
1487
log_error ("error allocating buffer\n");
1491
/* Walk 8 steps up to store the data. */
1493
/* 0. Store the first sequence. */
1494
p = store_tag_length (p, TAG_SEQUENCE, len[0]);
1496
/* 1. Store the second sequence. */
1497
p = store_tag_length (p, TAG_SEQUENCE, len[1]);
1499
/* 2. Store the pkcs12-cert-bag OID. */
1500
p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_pkcs_12_CertBag));
1501
memcpy (p, oid_pkcs_12_CertBag, DIM (oid_pkcs_12_CertBag));
1502
p += DIM (oid_pkcs_12_CertBag);
1504
/* 3. Store a [0] tag. */
1505
p = store_tag_length (p, 0xa0, len[3]);
1507
/* 4. Store a sequence. */
1508
p = store_tag_length (p, TAG_SEQUENCE, len[4]);
1510
/* 5. Store the x509Certificate OID. */
1511
p = store_tag_length (p, TAG_OBJECT_ID,
1512
DIM (oid_x509Certificate_for_pkcs_12));
1513
memcpy (p, oid_x509Certificate_for_pkcs_12,
1514
DIM (oid_x509Certificate_for_pkcs_12));
1515
p += DIM (oid_x509Certificate_for_pkcs_12);
1517
/* 6. Store a [0] tag. */
1518
p = store_tag_length (p, 0xa0, len[6]);
1520
/* 7. And finally the octet string with the actual certificate. */
1521
p = store_tag_length (p, TAG_OCTET_STRING, buflen);
1522
memcpy (p, buffer, buflen);
1524
certseqlen = p - certseq;
1526
if (needed != certseqlen)
1527
log_debug ("length mismatch: %u, %u\n", needed, certseqlen);
1529
/* Append some pad characters; we already allocated extra space. */
1530
n = 8 - certseqlen % 8;
1531
for (;(certseqlen % 8); certseqlen++)
1534
*r_length = certseqlen;
1539
/* Expect the RSA key parameters in KPARMS and a password in
1540
PW. Create a PKCS structure from it and return it as well as the
1541
length in R_LENGTH; return NULL in case of an error. */
1543
p12_build (gcry_mpi_t *kparms, unsigned char *cert, size_t certlen,
1544
const char *pw, size_t *r_length)
1546
unsigned char *buffer;
1549
struct buffer_s seqlist[2];
1552
if (cert && certlen)
1554
/* Encode the certificate. */
1555
buffer = build_cert_sequence (cert, certlen, &buflen);
1560
gcry_randomize (salt, 8, GCRY_STRONG_RANDOM);
1561
crypt_block (buffer, buflen, salt, 2048, pw, GCRY_CIPHER_RFC2268_40, 1);
1563
/* Encode the encrypted stuff into a bag. */
1564
seqlist[seqlistidx].buffer = build_cert_bag (buffer, buflen, salt, &n);
1565
seqlist[seqlistidx].length = n;
1568
if (!seqlist[seqlistidx].buffer)
1575
/* Encode the key. */
1576
buffer = build_key_sequence (kparms, &buflen);
1581
gcry_randomize (salt, 8, GCRY_STRONG_RANDOM);
1582
crypt_block (buffer, buflen, salt, 2048, pw, GCRY_CIPHER_3DES, 1);
1584
/* Encode the encrypted stuff into a bag. */
1585
seqlist[seqlistidx].buffer = build_key_bag (buffer, buflen, salt, &n);
1586
seqlist[seqlistidx].length = n;
1589
if (!seqlist[seqlistidx].buffer)
1594
seqlist[seqlistidx].buffer = NULL;
1595
seqlist[seqlistidx].length = 0;
1597
buffer = create_final (seqlist, &buflen);
1600
for ( ; seqlistidx; seqlistidx--)
1601
gcry_free (seqlist[seqlistidx].buffer);
1603
*r_length = buffer? buflen : 0;
1611
cert_cb (void *opaque, const unsigned char *cert, size_t certlen)
1613
printf ("got a certificate of %u bytes length\n", certlen);
1617
main (int argc, char **argv)
1627
fprintf (stderr, "usage: testp12 file passphrase\n");
1631
gcry_control (GCRYCTL_DISABLE_SECMEM, NULL);
1632
gcry_control (GCRYCTL_INITIALIZATION_FINISHED, NULL);
1634
fp = fopen (argv[1], "rb");
1637
fprintf (stderr, "can't open `%s': %s\n", argv[1], strerror (errno));
1641
if (fstat (fileno(fp), &st))
1643
fprintf (stderr, "can't stat `%s': %s\n", argv[1], strerror (errno));
1647
buflen = st.st_size;
1648
buf = gcry_malloc (buflen+1);
1649
if (!buf || fread (buf, buflen, 1, fp) != 1)
1651
fprintf (stderr, "error reading `%s': %s\n", argv[1], strerror (errno));
1656
result = p12_parse (buf, buflen, argv[2], cert_cb, NULL);
1660
unsigned char *tmpbuf;
1662
for (i=0; result[i]; i++)
1664
rc = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &tmpbuf,
1667
printf ("%d: [error printing number: %s]\n",
1668
i, gpg_strerror (rc));
1671
printf ("%d: %s\n", i, tmpbuf);
1683
compile-command: "gcc -Wall -O -g -DTEST=1 -o minip12 minip12.c ../jnlib/libjnlib.a -L /usr/local/lib -lgcrypt -lgpg-error"