Tizen 2.0 Release
[external/libgnutls26.git] / lib / x509 / privkey_pkcs8.c
1 /*
2  * Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009, 2010 Free Software
3  * Foundation, Inc.
4  *
5  * Author: Nikos Mavrogiannopoulos
6  *
7  * This file is part of GnuTLS.
8  *
9  * The GnuTLS is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public License
11  * as published by the Free Software Foundation; either version 2.1 of
12  * the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
22  * USA
23  *
24  */
25
26 #include <gnutls_int.h>
27
28 #ifdef ENABLE_PKI
29
30 #include <gnutls_datum.h>
31 #include <gnutls_global.h>
32 #include <gnutls_errors.h>
33 #include <gnutls_rsa_export.h>
34 #include <common.h>
35 #include <gnutls_x509.h>
36 #include <x509_b64.h>
37 #include "x509_int.h"
38 #include <gnutls_algorithms.h>
39 #include <gnutls_num.h>
40 #include <random.h>
41 #include <pbkdf2-sha1.h>
42
43 #define PBES2_OID "1.2.840.113549.1.5.13"
44 #define PBKDF2_OID "1.2.840.113549.1.5.12"
45 #define DES_EDE3_CBC_OID "1.2.840.113549.3.7"
46 #define AES_128_CBC_OID "2.16.840.1.101.3.4.1.2"
47 #define AES_192_CBC_OID "2.16.840.1.101.3.4.1.22"
48 #define AES_256_CBC_OID "2.16.840.1.101.3.4.1.42"
49 #define DES_CBC_OID "1.3.14.3.2.7"
50
51 /* oid_pbeWithSHAAnd3_KeyTripleDES_CBC */
52 #define PKCS12_PBE_3DES_SHA1_OID "1.2.840.113549.1.12.1.3"
53 #define PKCS12_PBE_ARCFOUR_SHA1_OID "1.2.840.113549.1.12.1.1"
54 #define PKCS12_PBE_RC2_40_SHA1_OID "1.2.840.113549.1.12.1.6"
55
56 struct pbkdf2_params
57 {
58   opaque salt[32];
59   int salt_size;
60   unsigned int iter_count;
61   unsigned int key_size;
62 };
63
64 struct pbe_enc_params
65 {
66   gnutls_cipher_algorithm_t cipher;
67   opaque iv[MAX_CIPHER_BLOCK_SIZE];
68   int iv_size;
69 };
70
71 static int generate_key (schema_id schema, const char *password,
72                          struct pbkdf2_params *kdf_params,
73                          struct pbe_enc_params *enc_params,
74                          gnutls_datum_t * key);
75 static int read_pbkdf2_params (ASN1_TYPE pbes2_asn,
76                                const gnutls_datum_t * der,
77                                struct pbkdf2_params *params);
78 static int read_pbe_enc_params (ASN1_TYPE pbes2_asn,
79                                 const gnutls_datum_t * der,
80                                 struct pbe_enc_params *params);
81 static int decrypt_data (schema_id, ASN1_TYPE pkcs8_asn, const char *root,
82                          const char *password,
83                          const struct pbkdf2_params *kdf_params,
84                          const struct pbe_enc_params *enc_params,
85                          gnutls_datum_t * decrypted_data);
86 static int decode_private_key_info (const gnutls_datum_t * der,
87                                     gnutls_x509_privkey_t pkey);
88 static int write_schema_params (schema_id schema, ASN1_TYPE pkcs8_asn,
89                                 const char *where,
90                                 const struct pbkdf2_params *kdf_params,
91                                 const struct pbe_enc_params *enc_params);
92 static int encrypt_data (const gnutls_datum_t * plain,
93                          const struct pbe_enc_params *enc_params,
94                          gnutls_datum_t * key, gnutls_datum_t * encrypted);
95
96 static int read_pkcs12_kdf_params (ASN1_TYPE pbes2_asn,
97                                    struct pbkdf2_params *params);
98 static int write_pkcs12_kdf_params (ASN1_TYPE pbes2_asn,
99                                     const struct pbkdf2_params *params);
100
101 #define PEM_PKCS8 "ENCRYPTED PRIVATE KEY"
102 #define PEM_UNENCRYPTED_PKCS8 "PRIVATE KEY"
103
104 /* Returns a negative error code if the encryption schema in
105  * the OID is not supported. The schema ID is returned.
106  */
107 static int
108 check_schema (const char *oid)
109 {
110
111   if (strcmp (oid, PBES2_OID) == 0)
112     return PBES2_GENERIC;       /* ok */
113
114   if (strcmp (oid, PKCS12_PBE_3DES_SHA1_OID) == 0)
115     return PKCS12_3DES_SHA1;
116
117   if (strcmp (oid, PKCS12_PBE_ARCFOUR_SHA1_OID) == 0)
118     return PKCS12_ARCFOUR_SHA1;
119
120   if (strcmp (oid, PKCS12_PBE_RC2_40_SHA1_OID) == 0)
121     return PKCS12_RC2_40_SHA1;
122
123   _gnutls_x509_log ("PKCS encryption schema OID '%s' is unsupported.\n", oid);
124
125   return GNUTLS_E_UNKNOWN_CIPHER_TYPE;
126 }
127
128 /* Encodes a private key to the raw format PKCS #8 needs.
129  * For RSA it is a PKCS #1 DER private key and for DSA it is
130  * an ASN.1 INTEGER of the x value.
131  */
132 inline static int
133 _encode_privkey (gnutls_x509_privkey_t pkey, gnutls_datum_t * raw)
134 {
135   size_t size = 0;
136   opaque *data = NULL;
137   int ret;
138   ASN1_TYPE spk = ASN1_TYPE_EMPTY;
139
140   switch (pkey->pk_algorithm)
141     {
142     case GNUTLS_PK_RSA:
143       ret =
144         gnutls_x509_privkey_export (pkey, GNUTLS_X509_FMT_DER, NULL, &size);
145       if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
146         {
147           gnutls_assert ();
148           goto error;
149         }
150
151       data = gnutls_malloc (size);
152       if (data == NULL)
153         {
154           gnutls_assert ();
155           ret = GNUTLS_E_MEMORY_ERROR;
156           goto error;
157         }
158
159
160       ret =
161         gnutls_x509_privkey_export (pkey, GNUTLS_X509_FMT_DER, data, &size);
162       if (ret < 0)
163         {
164           gnutls_assert ();
165           goto error;
166         }
167
168       raw->data = data;
169       raw->size = size;
170       break;
171     case GNUTLS_PK_DSA:
172       /* DSAPublicKey == INTEGER */
173       if ((ret = asn1_create_element
174            (_gnutls_get_gnutls_asn (), "GNUTLS.DSAPublicKey", &spk))
175           != ASN1_SUCCESS)
176         {
177           gnutls_assert ();
178           return _gnutls_asn2err (ret);
179         }
180
181       ret = _gnutls_x509_write_int (spk, "", pkey->params[4], 1);
182       if (ret < 0)
183         {
184           gnutls_assert ();
185           goto error;
186         }
187       ret = _gnutls_x509_der_encode (spk, "", raw, 0);
188       if (ret < 0)
189         {
190           gnutls_assert ();
191           goto error;
192         }
193
194       asn1_delete_structure (&spk);
195       break;
196
197     default:
198       gnutls_assert ();
199       return GNUTLS_E_INVALID_REQUEST;
200     }
201
202   return 0;
203
204 error:
205   gnutls_free (data);
206   asn1_delete_structure (&spk);
207   return ret;
208
209 }
210
211 /* 
212  * Encodes a PKCS #1 private key to a PKCS #8 private key
213  * info. The output will be allocated and stored into der. Also
214  * the ASN1_TYPE of private key info will be returned.
215  */
216 static int
217 encode_to_private_key_info (gnutls_x509_privkey_t pkey,
218                             gnutls_datum_t * der, ASN1_TYPE * pkey_info)
219 {
220   int result, len;
221   opaque null = 0;
222   const char *oid;
223   gnutls_datum_t algo_params = { NULL, 0 };
224   gnutls_datum_t algo_privkey = { NULL, 0 };
225
226   if (pkey->pk_algorithm != GNUTLS_PK_RSA
227       && pkey->pk_algorithm != GNUTLS_PK_DSA)
228     {
229       gnutls_assert ();
230       return GNUTLS_E_UNIMPLEMENTED_FEATURE;
231     }
232
233   if (pkey->pk_algorithm == GNUTLS_PK_RSA)
234     {
235       oid = PK_PKIX1_RSA_OID;
236       /* parameters are null 
237        */
238     }
239   else
240     {
241       oid = PK_DSA_OID;
242       result =
243         _gnutls_x509_write_dsa_params (pkey->params, pkey->params_size,
244                                        &algo_params);
245       if (result < 0)
246         {
247           gnutls_assert ();
248           return result;
249         }
250     }
251
252   if ((result =
253        asn1_create_element (_gnutls_get_pkix (),
254                             "PKIX1.pkcs-8-PrivateKeyInfo",
255                             pkey_info)) != ASN1_SUCCESS)
256     {
257       gnutls_assert ();
258       result = _gnutls_asn2err (result);
259       goto error;
260     }
261
262   /* Write the version.
263    */
264   result = asn1_write_value (*pkey_info, "version", &null, 1);
265   if (result != ASN1_SUCCESS)
266     {
267       gnutls_assert ();
268       result = _gnutls_asn2err (result);
269       goto error;
270     }
271
272   /* write the privateKeyAlgorithm
273    * fields. (OID+NULL data)
274    */
275   result =
276     asn1_write_value (*pkey_info, "privateKeyAlgorithm.algorithm", oid, 1);
277   if (result != ASN1_SUCCESS)
278     {
279       gnutls_assert ();
280       result = _gnutls_asn2err (result);
281       goto error;
282     }
283
284   result =
285     asn1_write_value (*pkey_info, "privateKeyAlgorithm.parameters",
286                       algo_params.data, algo_params.size);
287   _gnutls_free_datum (&algo_params);
288   if (result != ASN1_SUCCESS)
289     {
290       gnutls_assert ();
291       result = _gnutls_asn2err (result);
292       goto error;
293     }
294
295
296   /* Write the raw private key
297    */
298   result = _encode_privkey (pkey, &algo_privkey);
299   if (result < 0)
300     {
301       gnutls_assert ();
302       goto error;
303     }
304
305   result =
306     asn1_write_value (*pkey_info, "privateKey", algo_privkey.data,
307                       algo_privkey.size);
308   _gnutls_free_datum (&algo_privkey);
309
310   if (result != ASN1_SUCCESS)
311     {
312       gnutls_assert ();
313       result = _gnutls_asn2err (result);
314       goto error;
315     }
316
317   /* Append an empty Attributes field.
318    */
319   result = asn1_write_value (*pkey_info, "attributes", NULL, 0);
320   if (result != ASN1_SUCCESS)
321     {
322       gnutls_assert ();
323       result = _gnutls_asn2err (result);
324       goto error;
325     }
326
327   /* DER Encode the generated private key info.
328    */
329   len = 0;
330   result = asn1_der_coding (*pkey_info, "", NULL, &len, NULL);
331   if (result != ASN1_MEM_ERROR)
332     {
333       gnutls_assert ();
334       result = _gnutls_asn2err (result);
335       goto error;
336     }
337
338   /* allocate data for the der
339    */
340   der->size = len;
341   der->data = gnutls_malloc (len);
342   if (der->data == NULL)
343     {
344       gnutls_assert ();
345       return GNUTLS_E_MEMORY_ERROR;
346     }
347
348   result = asn1_der_coding (*pkey_info, "", der->data, &len, NULL);
349   if (result != ASN1_SUCCESS)
350     {
351       gnutls_assert ();
352       result = _gnutls_asn2err (result);
353       goto error;
354     }
355
356   return 0;
357
358 error:
359   asn1_delete_structure (pkey_info);
360   _gnutls_free_datum (&algo_params);
361   _gnutls_free_datum (&algo_privkey);
362   return result;
363
364 }
365
366 static const char *
367 cipher_to_pkcs_params (int cipher, const char **oid)
368 {
369   switch (cipher)
370     {
371     case GNUTLS_CIPHER_AES_128_CBC:
372       if (oid)
373         *oid = AES_128_CBC_OID;
374       return "PKIX1.pkcs-5-aes128-CBC-params";
375       break;
376     case GNUTLS_CIPHER_AES_192_CBC:
377       if (oid)
378         *oid = AES_192_CBC_OID;
379       return "PKIX1.pkcs-5-aes192-CBC-params";
380       break;
381     case GNUTLS_CIPHER_AES_256_CBC:
382       if (oid)
383         *oid = AES_256_CBC_OID;
384       return "PKIX1.pkcs-5-aes256-CBC-params";
385       break;
386     case GNUTLS_CIPHER_3DES_CBC:
387       if (oid)
388         *oid = DES_EDE3_CBC_OID;
389       return "PKIX1.pkcs-5-des-EDE3-CBC-params";
390       break;
391     default:
392       return NULL;
393       break;
394     }
395 }
396
397 static int
398 cipher_to_schema (int cipher)
399 {
400   switch (cipher)
401     {
402     case GNUTLS_CIPHER_AES_128_CBC:
403       return PBES2_AES_128;
404       break;
405     case GNUTLS_CIPHER_AES_192_CBC:
406       return PBES2_AES_192;
407       break;
408     case GNUTLS_CIPHER_AES_256_CBC:
409       return PBES2_AES_256;
410       break;
411     case GNUTLS_CIPHER_3DES_CBC:
412       return PBES2_3DES;
413       break;
414     default:
415       return GNUTLS_E_UNKNOWN_CIPHER_TYPE;
416       break;
417     }
418 }
419
420
421 int
422 _gnutls_pkcs_flags_to_schema (unsigned int flags)
423 {
424   int schema;
425
426   if (flags & GNUTLS_PKCS_USE_PKCS12_ARCFOUR)
427     schema = PKCS12_ARCFOUR_SHA1;
428   else if (flags & GNUTLS_PKCS_USE_PKCS12_RC2_40)
429     schema = PKCS12_RC2_40_SHA1;
430   else if (flags & GNUTLS_PKCS_USE_PBES2_3DES)
431     schema = PBES2_3DES;
432   else if (flags & GNUTLS_PKCS_USE_PBES2_AES_128)
433     schema = PBES2_AES_128;
434   else if (flags & GNUTLS_PKCS_USE_PBES2_AES_192)
435     schema = PBES2_AES_192;
436   else if (flags & GNUTLS_PKCS_USE_PBES2_AES_256)
437     schema = PBES2_AES_256;
438   else
439     {
440       gnutls_assert ();
441       _gnutls_x509_log
442         ("Selecting default encryption PKCS12_3DES_SHA1 (flags: %u).\n",
443          flags);
444       schema = PKCS12_3DES_SHA1;
445     }
446
447   return schema;
448 }
449
450 /* returns the OID corresponding to given schema
451  */
452 static int
453 schema_to_oid (schema_id schema, const char **str_oid)
454 {
455   int result = 0;
456
457   switch (schema)
458     {
459     case PBES2_3DES:
460     case PBES2_AES_128:
461     case PBES2_AES_192:
462     case PBES2_AES_256:
463       *str_oid = PBES2_OID;
464       break;
465     case PKCS12_3DES_SHA1:
466       *str_oid = PKCS12_PBE_3DES_SHA1_OID;
467       break;
468     case PKCS12_ARCFOUR_SHA1:
469       *str_oid = PKCS12_PBE_ARCFOUR_SHA1_OID;
470       break;
471     case PKCS12_RC2_40_SHA1:
472       *str_oid = PKCS12_PBE_RC2_40_SHA1_OID;
473       break;
474     default:
475       gnutls_assert ();
476       result = GNUTLS_E_INTERNAL_ERROR;
477     }
478
479   return result;
480 }
481
482 /* Converts a PKCS #8 private key info to
483  * a PKCS #8 EncryptedPrivateKeyInfo.
484  */
485 static int
486 encode_to_pkcs8_key (schema_id schema, const gnutls_datum_t * der_key,
487                      const char *password, ASN1_TYPE * out)
488 {
489   int result;
490   gnutls_datum_t key = { NULL, 0 };
491   gnutls_datum_t tmp = { NULL, 0 };
492   ASN1_TYPE pkcs8_asn = ASN1_TYPE_EMPTY;
493   struct pbkdf2_params kdf_params;
494   struct pbe_enc_params enc_params;
495   const char *str_oid;
496
497
498   if ((result =
499        asn1_create_element (_gnutls_get_pkix (),
500                             "PKIX1.pkcs-8-EncryptedPrivateKeyInfo",
501                             &pkcs8_asn)) != ASN1_SUCCESS)
502     {
503       gnutls_assert ();
504       result = _gnutls_asn2err (result);
505       goto error;
506     }
507
508   /* Write the encryption schema OID
509    */
510   result = schema_to_oid (schema, &str_oid);
511   if (result < 0)
512     {
513       gnutls_assert ();
514       return result;
515     }
516
517   result =
518     asn1_write_value (pkcs8_asn, "encryptionAlgorithm.algorithm", str_oid, 1);
519
520   if (result != ASN1_SUCCESS)
521     {
522       gnutls_assert ();
523       result = _gnutls_asn2err (result);
524       goto error;
525     }
526
527   /* Generate a symmetric key.
528    */
529
530   result = generate_key (schema, password, &kdf_params, &enc_params, &key);
531   if (result < 0)
532     {
533       gnutls_assert ();
534       goto error;
535     }
536
537   result =
538     write_schema_params (schema, pkcs8_asn,
539                          "encryptionAlgorithm.parameters", &kdf_params,
540                          &enc_params);
541   if (result < 0)
542     {
543       gnutls_assert ();
544       goto error;
545     }
546
547   /* Parameters have been encoded. Now
548    * encrypt the Data.
549    */
550   result = encrypt_data (der_key, &enc_params, &key, &tmp);
551   if (result < 0)
552     {
553       gnutls_assert ();
554       goto error;
555     }
556
557   /* write the encrypted data.
558    */
559   result = asn1_write_value (pkcs8_asn, "encryptedData", tmp.data, tmp.size);
560   if (result != ASN1_SUCCESS)
561     {
562       gnutls_assert ();
563       result = _gnutls_asn2err (result);
564       goto error;
565     }
566
567   _gnutls_free_datum (&tmp);
568   _gnutls_free_datum (&key);
569
570   *out = pkcs8_asn;
571
572   return 0;
573
574 error:
575   _gnutls_free_datum (&key);
576   _gnutls_free_datum (&tmp);
577   asn1_delete_structure (&pkcs8_asn);
578   return result;
579 }
580
581
582 /**
583  * gnutls_x509_privkey_export_pkcs8:
584  * @key: Holds the key
585  * @format: the format of output params. One of PEM or DER.
586  * @password: the password that will be used to encrypt the key.
587  * @flags: an ORed sequence of gnutls_pkcs_encrypt_flags_t
588  * @output_data: will contain a private key PEM or DER encoded
589  * @output_data_size: holds the size of output_data (and will be
590  *   replaced by the actual size of parameters)
591  *
592  * This function will export the private key to a PKCS8 structure.
593  * Both RSA and DSA keys can be exported. For DSA keys we use
594  * PKCS #11 definitions. If the flags do not specify the encryption
595  * cipher, then the default 3DES (PBES2) will be used.
596  *
597  * The @password can be either ASCII or UTF-8 in the default PBES2
598  * encryption schemas, or ASCII for the PKCS12 schemas.
599  *
600  * If the buffer provided is not long enough to hold the output, then
601  * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
602  * be returned.
603  *
604  * If the structure is PEM encoded, it will have a header
605  * of "BEGIN ENCRYPTED PRIVATE KEY" or "BEGIN PRIVATE KEY" if
606  * encryption is not used.
607  *
608  * Return value: In case of failure a negative value will be
609  *   returned, and 0 on success.
610  **/
611 int
612 gnutls_x509_privkey_export_pkcs8 (gnutls_x509_privkey_t key,
613                                   gnutls_x509_crt_fmt_t format,
614                                   const char *password,
615                                   unsigned int flags,
616                                   void *output_data,
617                                   size_t * output_data_size)
618 {
619   ASN1_TYPE pkcs8_asn, pkey_info;
620   int ret;
621   gnutls_datum_t tmp;
622   schema_id schema;
623
624   if (key == NULL)
625     {
626       gnutls_assert ();
627       return GNUTLS_E_INVALID_REQUEST;
628     }
629
630   /* Get the private key info
631    * tmp holds the DER encoding.
632    */
633   ret = encode_to_private_key_info (key, &tmp, &pkey_info);
634   if (ret < 0)
635     {
636       gnutls_assert ();
637       return ret;
638     }
639
640   schema = _gnutls_pkcs_flags_to_schema (flags);
641
642   if ((flags & GNUTLS_PKCS_PLAIN) || password == NULL)
643     {
644       _gnutls_free_datum (&tmp);
645
646       ret =
647         _gnutls_x509_export_int (pkey_info, format,
648                                  PEM_UNENCRYPTED_PKCS8,
649                                  output_data, output_data_size);
650
651       asn1_delete_structure (&pkey_info);
652     }
653   else
654     {
655       asn1_delete_structure (&pkey_info);       /* we don't need it */
656
657       ret = encode_to_pkcs8_key (schema, &tmp, password, &pkcs8_asn);
658       _gnutls_free_datum (&tmp);
659
660       if (ret < 0)
661         {
662           gnutls_assert ();
663           return ret;
664         }
665
666       ret =
667         _gnutls_x509_export_int (pkcs8_asn, format, PEM_PKCS8,
668                                  output_data, output_data_size);
669
670       asn1_delete_structure (&pkcs8_asn);
671     }
672
673   return ret;
674 }
675
676
677 /* Read the parameters cipher, IV, salt etc using the given
678  * schema ID.
679  */
680 static int
681 read_pkcs_schema_params (schema_id * schema, const char *password,
682                          const opaque * data, int data_size,
683                          struct pbkdf2_params *kdf_params,
684                          struct pbe_enc_params *enc_params)
685 {
686   ASN1_TYPE pbes2_asn = ASN1_TYPE_EMPTY;
687   int result;
688   gnutls_datum_t tmp;
689
690   switch (*schema)
691     {
692
693     case PBES2_GENERIC:
694
695       /* Now check the key derivation and the encryption
696        * functions.
697        */
698       if ((result =
699            asn1_create_element (_gnutls_get_pkix (),
700                                 "PKIX1.pkcs-5-PBES2-params",
701                                 &pbes2_asn)) != ASN1_SUCCESS)
702         {
703           gnutls_assert ();
704           result = _gnutls_asn2err (result);
705           goto error;
706         }
707
708       /* Decode the parameters.
709        */
710       result = asn1_der_decoding (&pbes2_asn, data, data_size, NULL);
711       if (result != ASN1_SUCCESS)
712         {
713           gnutls_assert ();
714           result = _gnutls_asn2err (result);
715           goto error;
716         }
717
718       tmp.data = (opaque *) data;
719       tmp.size = data_size;
720
721       result = read_pbkdf2_params (pbes2_asn, &tmp, kdf_params);
722       if (result < 0)
723         {
724           gnutls_assert ();
725           result = _gnutls_asn2err (result);
726           goto error;
727         }
728
729       result = read_pbe_enc_params (pbes2_asn, &tmp, enc_params);
730       if (result < 0)
731         {
732           gnutls_assert ();
733           result = _gnutls_asn2err (result);
734           goto error;
735         }
736
737       asn1_delete_structure (&pbes2_asn);
738
739       result = cipher_to_schema (enc_params->cipher);
740       if (result < 0)
741         {
742           gnutls_assert ();
743           goto error;
744         }
745
746       *schema = result;
747       return 0;
748
749     case PKCS12_3DES_SHA1:
750     case PKCS12_ARCFOUR_SHA1:
751     case PKCS12_RC2_40_SHA1:
752
753       if ((*schema) == PKCS12_3DES_SHA1)
754         {
755           enc_params->cipher = GNUTLS_CIPHER_3DES_CBC;
756           enc_params->iv_size = 8;
757         }
758       else if ((*schema) == PKCS12_ARCFOUR_SHA1)
759         {
760           enc_params->cipher = GNUTLS_CIPHER_ARCFOUR_128;
761           enc_params->iv_size = 0;
762         }
763       else if ((*schema) == PKCS12_RC2_40_SHA1)
764         {
765           enc_params->cipher = GNUTLS_CIPHER_RC2_40_CBC;
766           enc_params->iv_size = 8;
767         }
768
769       if ((result =
770            asn1_create_element (_gnutls_get_pkix (),
771                                 "PKIX1.pkcs-12-PbeParams",
772                                 &pbes2_asn)) != ASN1_SUCCESS)
773         {
774           gnutls_assert ();
775           result = _gnutls_asn2err (result);
776           goto error;
777         }
778
779       /* Decode the parameters.
780        */
781       result = asn1_der_decoding (&pbes2_asn, data, data_size, NULL);
782       if (result != ASN1_SUCCESS)
783         {
784           gnutls_assert ();
785           result = _gnutls_asn2err (result);
786           goto error;
787         }
788
789       result = read_pkcs12_kdf_params (pbes2_asn, kdf_params);
790       if (result < 0)
791         {
792           gnutls_assert ();
793           goto error;
794         }
795
796       if (enc_params->iv_size)
797         {
798           result =
799             _gnutls_pkcs12_string_to_key (2 /*IV*/, kdf_params->salt,
800                                           kdf_params->salt_size,
801                                           kdf_params->iter_count, password,
802                                           enc_params->iv_size,
803                                           enc_params->iv);
804           if (result < 0)
805             {
806               gnutls_assert ();
807               goto error;
808             }
809
810         }
811
812       asn1_delete_structure (&pbes2_asn);
813
814       return 0;
815
816     default:
817       gnutls_assert ();
818     }                           /* switch */
819
820   return GNUTLS_E_UNKNOWN_CIPHER_TYPE;
821
822 error:
823   asn1_delete_structure (&pbes2_asn);
824   return result;
825 }
826
827
828 /* Converts a PKCS #8 key to
829  * an internal structure (gnutls_private_key)
830  * (normally a PKCS #1 encoded RSA key)
831  */
832 static int
833 decode_pkcs8_key (const gnutls_datum_t * raw_key,
834                   const char *password, gnutls_x509_privkey_t pkey)
835 {
836   int result, len;
837   char enc_oid[64];
838   gnutls_datum_t tmp;
839   ASN1_TYPE pbes2_asn = ASN1_TYPE_EMPTY, pkcs8_asn = ASN1_TYPE_EMPTY;
840   int params_start, params_end, params_len;
841   struct pbkdf2_params kdf_params;
842   struct pbe_enc_params enc_params;
843   schema_id schema;
844
845   if ((result =
846        asn1_create_element (_gnutls_get_pkix (),
847                             "PKIX1.pkcs-8-EncryptedPrivateKeyInfo",
848                             &pkcs8_asn)) != ASN1_SUCCESS)
849     {
850       gnutls_assert ();
851       result = _gnutls_asn2err (result);
852       goto error;
853     }
854
855   result = asn1_der_decoding (&pkcs8_asn, raw_key->data, raw_key->size, NULL);
856   if (result != ASN1_SUCCESS)
857     {
858       gnutls_assert ();
859       result = _gnutls_asn2err (result);
860       goto error;
861     }
862
863   /* Check the encryption schema OID
864    */
865   len = sizeof (enc_oid);
866   result =
867     asn1_read_value (pkcs8_asn, "encryptionAlgorithm.algorithm",
868                      enc_oid, &len);
869   if (result != ASN1_SUCCESS)
870     {
871       gnutls_assert ();
872       goto error;
873     }
874
875   if ((result = check_schema (enc_oid)) < 0)
876     {
877       gnutls_assert ();
878       goto error;
879     }
880
881   schema = result;
882
883   /* Get the DER encoding of the parameters.
884    */
885   result =
886     asn1_der_decoding_startEnd (pkcs8_asn, raw_key->data,
887                                 raw_key->size,
888                                 "encryptionAlgorithm.parameters",
889                                 &params_start, &params_end);
890   if (result != ASN1_SUCCESS)
891     {
892       gnutls_assert ();
893       result = _gnutls_asn2err (result);
894       goto error;
895     }
896   params_len = params_end - params_start + 1;
897
898   result =
899     read_pkcs_schema_params (&schema, password,
900                              &raw_key->data[params_start],
901                              params_len, &kdf_params, &enc_params);
902
903   if (result < 0)
904     {
905       gnutls_assert ();
906       goto error;
907     }
908
909   /* Parameters have been decoded. Now
910    * decrypt the EncryptedData.
911    */
912   result =
913     decrypt_data (schema, pkcs8_asn, "encryptedData", password,
914                   &kdf_params, &enc_params, &tmp);
915   if (result < 0)
916     {
917       gnutls_assert ();
918       goto error;
919     }
920
921   asn1_delete_structure (&pkcs8_asn);
922
923   result = decode_private_key_info (&tmp, pkey);
924   _gnutls_free_datum (&tmp);
925
926   if (result < 0)
927     {
928       /* We've gotten this far. In the real world it's almost certain
929        * that we're dealing with a good file, but wrong password.
930        * Sadly like 90% of random data is somehow valid DER for the
931        * a first small number of bytes, so no easy way to guarantee. */
932       if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND ||
933           result == GNUTLS_E_ASN1_IDENTIFIER_NOT_FOUND ||
934           result == GNUTLS_E_ASN1_DER_ERROR ||
935           result == GNUTLS_E_ASN1_VALUE_NOT_FOUND ||
936           result == GNUTLS_E_ASN1_GENERIC_ERROR ||
937           result == GNUTLS_E_ASN1_VALUE_NOT_VALID ||
938           result == GNUTLS_E_ASN1_TAG_ERROR ||
939           result == GNUTLS_E_ASN1_TAG_IMPLICIT ||
940           result == GNUTLS_E_ASN1_TYPE_ANY_ERROR ||
941           result == GNUTLS_E_ASN1_SYNTAX_ERROR ||
942           result == GNUTLS_E_ASN1_DER_OVERFLOW)
943         {
944           result = GNUTLS_E_DECRYPTION_FAILED;
945         }
946
947       gnutls_assert ();
948       goto error;
949     }
950
951   return 0;
952
953 error:
954   asn1_delete_structure (&pbes2_asn);
955   asn1_delete_structure (&pkcs8_asn);
956   return result;
957 }
958
959 /* Decodes an RSA privateKey from a PKCS8 structure.
960  */
961 static int
962 _decode_pkcs8_rsa_key (ASN1_TYPE pkcs8_asn, gnutls_x509_privkey_t pkey)
963 {
964   int ret;
965   gnutls_datum_t tmp;
966
967   ret = _gnutls_x509_read_value (pkcs8_asn, "privateKey", &tmp, 0);
968   if (ret < 0)
969     {
970       gnutls_assert ();
971       goto error;
972     }
973
974   pkey->key = _gnutls_privkey_decode_pkcs1_rsa_key (&tmp, pkey);
975   _gnutls_free_datum (&tmp);
976   if (pkey->key == NULL)
977     {
978       gnutls_assert ();
979       goto error;
980     }
981
982   return 0;
983
984 error:
985   gnutls_x509_privkey_deinit (pkey);
986   return ret;
987 }
988
989 /* Decodes an DSA privateKey and params from a PKCS8 structure.
990  */
991 static int
992 _decode_pkcs8_dsa_key (ASN1_TYPE pkcs8_asn, gnutls_x509_privkey_t pkey)
993 {
994   int ret;
995   gnutls_datum_t tmp;
996
997   ret = _gnutls_x509_read_value (pkcs8_asn, "privateKey", &tmp, 0);
998   if (ret < 0)
999     {
1000       gnutls_assert ();
1001       goto error;
1002     }
1003
1004   ret = _gnutls_x509_read_der_int (tmp.data, tmp.size, &pkey->params[4]);
1005   _gnutls_free_datum (&tmp);
1006
1007   if (ret < 0)
1008     {
1009       gnutls_assert ();
1010       goto error;
1011     }
1012
1013   ret =
1014     _gnutls_x509_read_value (pkcs8_asn, "privateKeyAlgorithm.parameters",
1015                              &tmp, 0);
1016   if (ret < 0)
1017     {
1018       gnutls_assert ();
1019       goto error;
1020     }
1021
1022   ret = _gnutls_x509_read_dsa_params (tmp.data, tmp.size, pkey->params);
1023   _gnutls_free_datum (&tmp);
1024   if (ret < 0)
1025     {
1026       gnutls_assert ();
1027       goto error;
1028     }
1029
1030   /* the public key can be generated as g^x mod p */
1031   pkey->params[3] = _gnutls_mpi_alloc_like (pkey->params[0]);
1032   if (pkey->params[3] == NULL)
1033     {
1034       gnutls_assert ();
1035       goto error;
1036     }
1037
1038   _gnutls_mpi_powm (pkey->params[3], pkey->params[2], pkey->params[4],
1039                     pkey->params[0]);
1040
1041   ret = _gnutls_asn1_encode_dsa (&pkey->key, pkey->params);
1042   if (ret < 0)
1043     {
1044       gnutls_assert ();
1045       goto error;
1046     }
1047
1048   pkey->params_size = DSA_PRIVATE_PARAMS;
1049
1050   return 0;
1051
1052 error:
1053   gnutls_x509_privkey_deinit (pkey);
1054   return ret;
1055 }
1056
1057
1058 static int
1059 decode_private_key_info (const gnutls_datum_t * der,
1060                          gnutls_x509_privkey_t pkey)
1061 {
1062   int result, len;
1063   opaque oid[64];
1064   ASN1_TYPE pkcs8_asn = ASN1_TYPE_EMPTY;
1065
1066
1067   if ((result =
1068        asn1_create_element (_gnutls_get_pkix (),
1069                             "PKIX1.pkcs-8-PrivateKeyInfo",
1070                             &pkcs8_asn)) != ASN1_SUCCESS)
1071     {
1072       gnutls_assert ();
1073       result = _gnutls_asn2err (result);
1074       goto error;
1075     }
1076
1077   result = asn1_der_decoding (&pkcs8_asn, der->data, der->size, NULL);
1078   if (result != ASN1_SUCCESS)
1079     {
1080       gnutls_assert ();
1081       result = _gnutls_asn2err (result);
1082       goto error;
1083     }
1084
1085   /* Check the private key algorithm OID
1086    */
1087   len = sizeof (oid);
1088   result =
1089     asn1_read_value (pkcs8_asn, "privateKeyAlgorithm.algorithm", oid, &len);
1090   if (result != ASN1_SUCCESS)
1091     {
1092       gnutls_assert ();
1093       result = _gnutls_asn2err (result);
1094       goto error;
1095     }
1096
1097   /* we only support RSA and DSA private keys.
1098    */
1099   if (strcmp (oid, PK_PKIX1_RSA_OID) == 0)
1100     pkey->pk_algorithm = GNUTLS_PK_RSA;
1101   else if (strcmp (oid, PK_DSA_OID) == 0)
1102     pkey->pk_algorithm = GNUTLS_PK_DSA;
1103   else
1104     {
1105       gnutls_assert ();
1106       _gnutls_x509_log
1107         ("PKCS #8 private key OID '%s' is unsupported.\n", oid);
1108       result = GNUTLS_E_UNKNOWN_PK_ALGORITHM;
1109       goto error;
1110     }
1111
1112   /* Get the DER encoding of the actual private key.
1113    */
1114
1115   if (pkey->pk_algorithm == GNUTLS_PK_RSA)
1116     result = _decode_pkcs8_rsa_key (pkcs8_asn, pkey);
1117   else if (pkey->pk_algorithm == GNUTLS_PK_DSA)
1118     result = _decode_pkcs8_dsa_key (pkcs8_asn, pkey);
1119
1120   if (result < 0)
1121     {
1122       gnutls_assert ();
1123       return result;
1124     }
1125
1126   result = 0;
1127
1128 error:
1129   asn1_delete_structure (&pkcs8_asn);
1130
1131   return result;
1132
1133 }
1134
1135 /**
1136  * gnutls_x509_privkey_import_pkcs8:
1137  * @key: The structure to store the parsed key
1138  * @data: The DER or PEM encoded key.
1139  * @format: One of DER or PEM
1140  * @password: the password to decrypt the key (if it is encrypted).
1141  * @flags: 0 if encrypted or GNUTLS_PKCS_PLAIN if not encrypted.
1142  *
1143  * This function will convert the given DER or PEM encoded PKCS8 2.0
1144  * encrypted key to the native gnutls_x509_privkey_t format. The
1145  * output will be stored in @key.  Both RSA and DSA keys can be
1146  * imported, and flags can only be used to indicate an unencrypted
1147  * key.
1148  *
1149  * The @password can be either ASCII or UTF-8 in the default PBES2
1150  * encryption schemas, or ASCII for the PKCS12 schemas.
1151  *
1152  * If the Certificate is PEM encoded it should have a header of
1153  * "ENCRYPTED PRIVATE KEY", or "PRIVATE KEY". You only need to
1154  * specify the flags if the key is DER encoded, since in that case
1155  * the encryption status cannot be auto-detected.
1156  *
1157  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
1158  *   negative error value.
1159  **/
1160 int
1161 gnutls_x509_privkey_import_pkcs8 (gnutls_x509_privkey_t key,
1162                                   const gnutls_datum_t * data,
1163                                   gnutls_x509_crt_fmt_t format,
1164                                   const char *password, unsigned int flags)
1165 {
1166   int result = 0, need_free = 0;
1167   gnutls_datum_t _data;
1168
1169   if (key == NULL)
1170     {
1171       gnutls_assert ();
1172       return GNUTLS_E_INVALID_REQUEST;
1173     }
1174
1175   _data.data = data->data;
1176   _data.size = data->size;
1177
1178   key->pk_algorithm = GNUTLS_PK_UNKNOWN;
1179
1180   /* If the Certificate is in PEM format then decode it
1181    */
1182   if (format == GNUTLS_X509_FMT_PEM)
1183     {
1184       opaque *out;
1185
1186       /* Try the first header 
1187        */
1188       result =
1189         _gnutls_fbase64_decode (PEM_UNENCRYPTED_PKCS8,
1190                                 data->data, data->size, &out);
1191
1192       if (result < 0)
1193         {                       /* Try the encrypted header 
1194                                  */
1195           result =
1196             _gnutls_fbase64_decode (PEM_PKCS8, data->data, data->size, &out);
1197
1198           if (result <= 0)
1199             {
1200               if (result == 0)
1201                 result = GNUTLS_E_INTERNAL_ERROR;
1202               gnutls_assert ();
1203               return result;
1204             }
1205         }
1206       else if (flags == 0)
1207         flags |= GNUTLS_PKCS_PLAIN;
1208
1209       _data.data = out;
1210       _data.size = result;
1211
1212       need_free = 1;
1213     }
1214
1215   if (flags & GNUTLS_PKCS_PLAIN)
1216     {
1217       result = decode_private_key_info (&_data, key);
1218     }
1219   else
1220     {                           /* encrypted. */
1221       result = decode_pkcs8_key (&_data, password, key);
1222     }
1223
1224   if (result < 0)
1225     {
1226       gnutls_assert ();
1227       goto cleanup;
1228     }
1229
1230   if (need_free)
1231     _gnutls_free_datum (&_data);
1232
1233   /* The key has now been decoded.
1234    */
1235
1236   return 0;
1237
1238 cleanup:
1239   key->pk_algorithm = GNUTLS_PK_UNKNOWN;
1240   if (need_free)
1241     _gnutls_free_datum (&_data);
1242   return result;
1243 }
1244
1245 /* Reads the PBKDF2 parameters.
1246  */
1247 static int
1248 read_pbkdf2_params (ASN1_TYPE pbes2_asn,
1249                     const gnutls_datum_t * der, struct pbkdf2_params *params)
1250 {
1251   int params_start, params_end;
1252   int params_len, len, result;
1253   ASN1_TYPE pbkdf2_asn = ASN1_TYPE_EMPTY;
1254   char oid[64];
1255
1256   memset (params, 0, sizeof (*params));
1257
1258   /* Check the key derivation algorithm
1259    */
1260   len = sizeof (oid);
1261   result =
1262     asn1_read_value (pbes2_asn, "keyDerivationFunc.algorithm", oid, &len);
1263   if (result != ASN1_SUCCESS)
1264     {
1265       gnutls_assert ();
1266       return _gnutls_asn2err (result);
1267     }
1268   _gnutls_hard_log ("keyDerivationFunc.algorithm: %s\n", oid);
1269
1270   if (strcmp (oid, PBKDF2_OID) != 0)
1271     {
1272       gnutls_assert ();
1273       _gnutls_x509_log
1274         ("PKCS #8 key derivation OID '%s' is unsupported.\n", oid);
1275       return _gnutls_asn2err (result);
1276     }
1277
1278   result =
1279     asn1_der_decoding_startEnd (pbes2_asn, der->data, der->size,
1280                                 "keyDerivationFunc.parameters",
1281                                 &params_start, &params_end);
1282   if (result != ASN1_SUCCESS)
1283     {
1284       gnutls_assert ();
1285       return _gnutls_asn2err (result);
1286     }
1287   params_len = params_end - params_start + 1;
1288
1289   /* Now check the key derivation and the encryption
1290    * functions.
1291    */
1292   if ((result =
1293        asn1_create_element (_gnutls_get_pkix (),
1294                             "PKIX1.pkcs-5-PBKDF2-params",
1295                             &pbkdf2_asn)) != ASN1_SUCCESS)
1296     {
1297       gnutls_assert ();
1298       return _gnutls_asn2err (result);
1299     }
1300
1301   result =
1302     asn1_der_decoding (&pbkdf2_asn, &der->data[params_start],
1303                        params_len, NULL);
1304   if (result != ASN1_SUCCESS)
1305     {
1306       gnutls_assert ();
1307       result = _gnutls_asn2err (result);
1308       goto error;
1309     }
1310
1311   /* read the salt */
1312   params->salt_size = sizeof (params->salt);
1313   result =
1314     asn1_read_value (pbkdf2_asn, "salt.specified", params->salt,
1315                      &params->salt_size);
1316   if (result != ASN1_SUCCESS)
1317     {
1318       gnutls_assert ();
1319       result = _gnutls_asn2err (result);
1320       goto error;
1321     }
1322   _gnutls_hard_log ("salt.specified.size: %d\n", params->salt_size);
1323
1324   /* read the iteration count 
1325    */
1326   result =
1327     _gnutls_x509_read_uint (pbkdf2_asn, "iterationCount",
1328                             &params->iter_count);
1329   if (result != ASN1_SUCCESS)
1330     {
1331       gnutls_assert ();
1332       goto error;
1333     }
1334   _gnutls_hard_log ("iterationCount: %d\n", params->iter_count);
1335
1336   /* read the keylength, if it is set.
1337    */
1338   result =
1339     _gnutls_x509_read_uint (pbkdf2_asn, "keyLength", &params->key_size);
1340   if (result < 0)
1341     {
1342       params->key_size = 0;
1343     }
1344   _gnutls_hard_log ("keyLength: %d\n", params->key_size);
1345
1346   /* We don't read the PRF. We only use the default.
1347    */
1348
1349   result = 0;
1350
1351 error:
1352   asn1_delete_structure (&pbkdf2_asn);
1353   return result;
1354
1355 }
1356
1357 /* Reads the PBE parameters from PKCS-12 schemas (*&#%*&#% RSA).
1358  */
1359 static int
1360 read_pkcs12_kdf_params (ASN1_TYPE pbes2_asn, struct pbkdf2_params *params)
1361 {
1362   int result;
1363
1364   memset (params, 0, sizeof (*params));
1365
1366   /* read the salt */
1367   params->salt_size = sizeof (params->salt);
1368   result =
1369     asn1_read_value (pbes2_asn, "salt", params->salt, &params->salt_size);
1370   if (result != ASN1_SUCCESS)
1371     {
1372       gnutls_assert ();
1373       result = _gnutls_asn2err (result);
1374       goto error;
1375     }
1376   _gnutls_hard_log ("salt.size: %d\n", params->salt_size);
1377
1378   /* read the iteration count 
1379    */
1380   result =
1381     _gnutls_x509_read_uint (pbes2_asn, "iterations", &params->iter_count);
1382   if (result != ASN1_SUCCESS)
1383     {
1384       gnutls_assert ();
1385       goto error;
1386     }
1387   _gnutls_hard_log ("iterationCount: %d\n", params->iter_count);
1388
1389   params->key_size = 0;
1390
1391   return 0;
1392
1393 error:
1394   return result;
1395
1396 }
1397
1398 /* Writes the PBE parameters for PKCS-12 schemas.
1399  */
1400 static int
1401 write_pkcs12_kdf_params (ASN1_TYPE pbes2_asn,
1402                          const struct pbkdf2_params *kdf_params)
1403 {
1404   int result;
1405
1406   /* write the salt 
1407    */
1408   result =
1409     asn1_write_value (pbes2_asn, "salt",
1410                       kdf_params->salt, kdf_params->salt_size);
1411   if (result != ASN1_SUCCESS)
1412     {
1413       gnutls_assert ();
1414       result = _gnutls_asn2err (result);
1415       goto error;
1416     }
1417   _gnutls_hard_log ("salt.size: %d\n", kdf_params->salt_size);
1418
1419   /* write the iteration count 
1420    */
1421   result =
1422     _gnutls_x509_write_uint32 (pbes2_asn, "iterations",
1423                                kdf_params->iter_count);
1424   if (result < 0)
1425     {
1426       gnutls_assert ();
1427       goto error;
1428     }
1429   _gnutls_hard_log ("iterationCount: %d\n", kdf_params->iter_count);
1430
1431   return 0;
1432
1433 error:
1434   return result;
1435
1436 }
1437
1438
1439 /* Converts an OID to a gnutls cipher type.
1440  */
1441 inline static int
1442 oid2cipher (const char *oid, gnutls_cipher_algorithm_t * algo)
1443 {
1444
1445   *algo = 0;
1446
1447   if (strcmp (oid, DES_EDE3_CBC_OID) == 0)
1448     {
1449       *algo = GNUTLS_CIPHER_3DES_CBC;
1450       return 0;
1451     }
1452   else if (strcmp (oid, DES_CBC_OID) == 0)
1453     {
1454       *algo = GNUTLS_CIPHER_DES_CBC;
1455       return 0;
1456     }
1457   else if (strcmp (oid, AES_128_CBC_OID) == 0)
1458     {
1459       *algo = GNUTLS_CIPHER_AES_128_CBC;
1460       return 0;
1461     }
1462   else if (strcmp (oid, AES_192_CBC_OID) == 0)
1463     {
1464       *algo = GNUTLS_CIPHER_AES_192_CBC;
1465       return 0;
1466     }
1467   else if (strcmp (oid, AES_256_CBC_OID) == 0)
1468     {
1469       *algo = GNUTLS_CIPHER_AES_256_CBC;
1470       return 0;
1471     }
1472
1473   _gnutls_x509_log ("PKCS #8 encryption OID '%s' is unsupported.\n", oid);
1474   return GNUTLS_E_UNKNOWN_CIPHER_TYPE;
1475 }
1476
1477
1478
1479 static int
1480 read_pbe_enc_params (ASN1_TYPE pbes2_asn,
1481                      const gnutls_datum_t * der,
1482                      struct pbe_enc_params *params)
1483 {
1484   int params_start, params_end;
1485   int params_len, len, result;
1486   ASN1_TYPE pbe_asn = ASN1_TYPE_EMPTY;
1487   char oid[64];
1488   const char *eparams;
1489
1490   memset (params, 0, sizeof (*params));
1491
1492   /* Check the encryption algorithm
1493    */
1494   len = sizeof (oid);
1495   result =
1496     asn1_read_value (pbes2_asn, "encryptionScheme.algorithm", oid, &len);
1497   if (result != ASN1_SUCCESS)
1498     {
1499       gnutls_assert ();
1500       goto error;
1501     }
1502   _gnutls_hard_log ("encryptionScheme.algorithm: %s\n", oid);
1503
1504   if ((result = oid2cipher (oid, &params->cipher)) < 0)
1505     {
1506       gnutls_assert ();
1507       goto error;
1508     }
1509
1510   result =
1511     asn1_der_decoding_startEnd (pbes2_asn, der->data, der->size,
1512                                 "encryptionScheme.parameters",
1513                                 &params_start, &params_end);
1514   if (result != ASN1_SUCCESS)
1515     {
1516       gnutls_assert ();
1517       return _gnutls_asn2err (result);
1518     }
1519   params_len = params_end - params_start + 1;
1520
1521   /* Now check the encryption parameters.
1522    */
1523   eparams = cipher_to_pkcs_params (params->cipher, NULL);
1524   if (eparams == NULL)
1525     {
1526       gnutls_assert ();
1527       return GNUTLS_E_INVALID_REQUEST;
1528     }
1529
1530   if ((result =
1531        asn1_create_element (_gnutls_get_pkix (),
1532                             eparams, &pbe_asn)) != ASN1_SUCCESS)
1533     {
1534       gnutls_assert ();
1535       return _gnutls_asn2err (result);
1536     }
1537
1538   result =
1539     asn1_der_decoding (&pbe_asn, &der->data[params_start], params_len, NULL);
1540   if (result != ASN1_SUCCESS)
1541     {
1542       gnutls_assert ();
1543       result = _gnutls_asn2err (result);
1544       goto error;
1545     }
1546
1547   /* read the IV */
1548   params->iv_size = sizeof (params->iv);
1549   result = asn1_read_value (pbe_asn, "", params->iv, &params->iv_size);
1550   if (result != ASN1_SUCCESS)
1551     {
1552       gnutls_assert ();
1553       result = _gnutls_asn2err (result);
1554       goto error;
1555     }
1556   _gnutls_hard_log ("IV.size: %d\n", params->iv_size);
1557   
1558   result = 0;
1559
1560 error:
1561   asn1_delete_structure (&pbe_asn);
1562   return result;
1563
1564 }
1565
1566 static int
1567 decrypt_data (schema_id schema, ASN1_TYPE pkcs8_asn,
1568               const char *root, const char *password,
1569               const struct pbkdf2_params *kdf_params,
1570               const struct pbe_enc_params *enc_params,
1571               gnutls_datum_t * decrypted_data)
1572 {
1573   int result;
1574   int data_size;
1575   opaque *data = NULL, *key = NULL;
1576   gnutls_datum_t dkey, d_iv;
1577   cipher_hd_st ch;
1578   int ch_init = 0;
1579   int key_size;
1580
1581   data_size = 0;
1582   result = asn1_read_value (pkcs8_asn, root, NULL, &data_size);
1583   if (result != ASN1_MEM_ERROR)
1584     {
1585       gnutls_assert ();
1586       return _gnutls_asn2err (result);
1587     }
1588
1589   data = gnutls_malloc (data_size);
1590   if (data == NULL)
1591     {
1592       gnutls_assert ();
1593       return GNUTLS_E_MEMORY_ERROR;
1594     }
1595
1596   result = asn1_read_value (pkcs8_asn, root, data, &data_size);
1597   if (result != ASN1_SUCCESS)
1598     {
1599       gnutls_assert ();
1600       result = _gnutls_asn2err (result);
1601       goto error;
1602     }
1603
1604   if (kdf_params->key_size == 0)
1605     {
1606       key_size = gnutls_cipher_get_key_size (enc_params->cipher);
1607     }
1608   else
1609     key_size = kdf_params->key_size;
1610
1611   key = gnutls_malloc (key_size);
1612   if (key == NULL)
1613     {
1614       gnutls_assert ();
1615       result = GNUTLS_E_MEMORY_ERROR;
1616       goto error;
1617     }
1618
1619   /* generate the key
1620    */
1621   switch (schema)
1622     {
1623     case PBES2_3DES:
1624     case PBES2_AES_128:
1625     case PBES2_AES_192:
1626     case PBES2_AES_256:
1627
1628       result = _gnutls_pbkdf2_sha1 (password, strlen (password),
1629                                     kdf_params->salt, kdf_params->salt_size,
1630                                     kdf_params->iter_count, key, key_size);
1631
1632       if (result < 0)
1633         {
1634           gnutls_assert ();
1635           goto error;
1636         }
1637       break;
1638     default:
1639       result =
1640         _gnutls_pkcs12_string_to_key (1 /*KEY*/, kdf_params->salt,
1641                                       kdf_params->salt_size,
1642                                       kdf_params->iter_count, password,
1643                                       key_size, key);
1644
1645       if (result < 0)
1646         {
1647           gnutls_assert ();
1648           goto error;
1649         }
1650     }
1651
1652   /* do the decryption.
1653    */
1654   dkey.data = key;
1655   dkey.size = key_size;
1656
1657   d_iv.data = (opaque *) enc_params->iv;
1658   d_iv.size = enc_params->iv_size;
1659   result = _gnutls_cipher_init (&ch, enc_params->cipher, &dkey, &d_iv);
1660
1661   gnutls_free (key);
1662   key = NULL;
1663
1664   if (result < 0)
1665     {
1666       gnutls_assert ();
1667       goto error;
1668     }
1669
1670   ch_init = 1;
1671
1672   result = _gnutls_cipher_decrypt (&ch, data, data_size);
1673   if (result < 0)
1674     {
1675       gnutls_assert ();
1676       goto error;
1677     }
1678
1679   decrypted_data->data = data;
1680
1681   if (gnutls_cipher_get_block_size (enc_params->cipher) != 1)
1682     decrypted_data->size = data_size - data[data_size - 1];
1683   else
1684     decrypted_data->size = data_size;
1685
1686   _gnutls_cipher_deinit (&ch);
1687
1688   return 0;
1689
1690 error:
1691   gnutls_free (data);
1692   gnutls_free (key);
1693   if (ch_init != 0)
1694     _gnutls_cipher_deinit (&ch);
1695   return result;
1696 }
1697
1698
1699 /* Writes the PBKDF2 parameters.
1700  */
1701 static int
1702 write_pbkdf2_params (ASN1_TYPE pbes2_asn,
1703                      const struct pbkdf2_params *kdf_params)
1704 {
1705   int result;
1706   ASN1_TYPE pbkdf2_asn = ASN1_TYPE_EMPTY;
1707   opaque tmp[64];
1708
1709   /* Write the key derivation algorithm
1710    */
1711   result =
1712     asn1_write_value (pbes2_asn, "keyDerivationFunc.algorithm",
1713                       PBKDF2_OID, 1);
1714   if (result != ASN1_SUCCESS)
1715     {
1716       gnutls_assert ();
1717       return _gnutls_asn2err (result);
1718     }
1719
1720   /* Now write the key derivation and the encryption
1721    * functions.
1722    */
1723   if ((result =
1724        asn1_create_element (_gnutls_get_pkix (),
1725                             "PKIX1.pkcs-5-PBKDF2-params",
1726                             &pbkdf2_asn)) != ASN1_SUCCESS)
1727     {
1728       gnutls_assert ();
1729       return _gnutls_asn2err (result);
1730     }
1731
1732   result = asn1_write_value (pbkdf2_asn, "salt", "specified", 1);
1733   if (result != ASN1_SUCCESS)
1734     {
1735       gnutls_assert ();
1736       result = _gnutls_asn2err (result);
1737       goto error;
1738     }
1739
1740   /* write the salt 
1741    */
1742   result =
1743     asn1_write_value (pbkdf2_asn, "salt.specified",
1744                       kdf_params->salt, kdf_params->salt_size);
1745   if (result != ASN1_SUCCESS)
1746     {
1747       gnutls_assert ();
1748       result = _gnutls_asn2err (result);
1749       goto error;
1750     }
1751   _gnutls_hard_log ("salt.specified.size: %d\n", kdf_params->salt_size);
1752
1753   /* write the iteration count 
1754    */
1755   _gnutls_write_uint32 (kdf_params->iter_count, tmp);
1756
1757   result = asn1_write_value (pbkdf2_asn, "iterationCount", tmp, 4);
1758   if (result != ASN1_SUCCESS)
1759     {
1760       gnutls_assert ();
1761       result = _gnutls_asn2err (result);
1762       goto error;
1763     }
1764   _gnutls_hard_log ("iterationCount: %d\n", kdf_params->iter_count);
1765
1766   /* write the keylength, if it is set.
1767    */
1768   result = asn1_write_value (pbkdf2_asn, "keyLength", NULL, 0);
1769   if (result != ASN1_SUCCESS)
1770     {
1771       gnutls_assert ();
1772       result = _gnutls_asn2err (result);
1773       goto error;
1774     }
1775
1776   /* We write an emptry prf.
1777    */
1778   result = asn1_write_value (pbkdf2_asn, "prf", NULL, 0);
1779   if (result != ASN1_SUCCESS)
1780     {
1781       gnutls_assert ();
1782       result = _gnutls_asn2err (result);
1783       goto error;
1784     }
1785
1786   /* now encode them an put the DER output
1787    * in the keyDerivationFunc.parameters
1788    */
1789   result = _gnutls_x509_der_encode_and_copy (pbkdf2_asn, "",
1790                                              pbes2_asn,
1791                                              "keyDerivationFunc.parameters",
1792                                              0);
1793   if (result < 0)
1794     {
1795       gnutls_assert ();
1796       goto error;
1797     }
1798
1799   return 0;
1800
1801 error:
1802   asn1_delete_structure (&pbkdf2_asn);
1803   return result;
1804
1805 }
1806
1807
1808 static int
1809 write_pbe_enc_params (ASN1_TYPE pbes2_asn,
1810                       const struct pbe_enc_params *params)
1811 {
1812   int result;
1813   ASN1_TYPE pbe_asn = ASN1_TYPE_EMPTY;
1814   const char *oid, *eparams;
1815
1816   /* Write the encryption algorithm
1817    */
1818   eparams = cipher_to_pkcs_params (params->cipher, &oid);
1819   if (eparams == NULL)
1820     {
1821       gnutls_assert ();
1822       return GNUTLS_E_INVALID_REQUEST;
1823     }
1824
1825   result = asn1_write_value (pbes2_asn, "encryptionScheme.algorithm", oid, 1);
1826   if (result != ASN1_SUCCESS)
1827     {
1828       gnutls_assert ();
1829       goto error;
1830     }
1831   _gnutls_hard_log ("encryptionScheme.algorithm: %s\n", oid);
1832
1833   /* Now check the encryption parameters.
1834    */
1835   if ((result =
1836        asn1_create_element (_gnutls_get_pkix (),
1837                             eparams, &pbe_asn)) != ASN1_SUCCESS)
1838     {
1839       gnutls_assert ();
1840       return _gnutls_asn2err (result);
1841     }
1842
1843   /* read the salt */
1844   result = asn1_write_value (pbe_asn, "", params->iv, params->iv_size);
1845   if (result != ASN1_SUCCESS)
1846     {
1847       gnutls_assert ();
1848       result = _gnutls_asn2err (result);
1849       goto error;
1850     }
1851   _gnutls_hard_log ("IV.size: %d\n", params->iv_size);
1852
1853   /* now encode them an put the DER output
1854    * in the encryptionScheme.parameters
1855    */
1856   result = _gnutls_x509_der_encode_and_copy (pbe_asn, "",
1857                                              pbes2_asn,
1858                                              "encryptionScheme.parameters",
1859                                              0);
1860   if (result < 0)
1861     {
1862       gnutls_assert ();
1863       goto error;
1864     }
1865
1866   return 0;
1867
1868 error:
1869   asn1_delete_structure (&pbe_asn);
1870   return result;
1871
1872 }
1873
1874 /* Generates a key and also stores the key parameters.
1875  */
1876 static int
1877 generate_key (schema_id schema,
1878               const char *password,
1879               struct pbkdf2_params *kdf_params,
1880               struct pbe_enc_params *enc_params, gnutls_datum_t * key)
1881 {
1882   opaque rnd[2];
1883   int ret;
1884
1885   ret = _gnutls_rnd (GNUTLS_RND_RANDOM, rnd, 2);
1886   if (ret < 0)
1887     {
1888       gnutls_assert ();
1889       return ret;
1890     }
1891
1892   /* generate salt */
1893   kdf_params->salt_size =
1894     MIN (sizeof (kdf_params->salt), (unsigned) (10 + (rnd[1] % 10)));
1895
1896   switch (schema)
1897     {
1898     case PBES2_3DES:
1899       enc_params->cipher = GNUTLS_CIPHER_3DES_CBC;
1900       break;
1901     case PBES2_AES_128:
1902       enc_params->cipher = GNUTLS_CIPHER_AES_128_CBC;
1903       break;
1904     case PBES2_AES_192:
1905       enc_params->cipher = GNUTLS_CIPHER_AES_192_CBC;
1906       break;
1907     case PBES2_AES_256:
1908       enc_params->cipher = GNUTLS_CIPHER_AES_256_CBC;
1909       break;
1910       /* non PBES2 algorithms */
1911     case PKCS12_ARCFOUR_SHA1:
1912       enc_params->cipher = GNUTLS_CIPHER_ARCFOUR_128;
1913       kdf_params->salt_size = 8;
1914       break;
1915     case PKCS12_3DES_SHA1:
1916       enc_params->cipher = GNUTLS_CIPHER_3DES_CBC;
1917       kdf_params->salt_size = 8;
1918       break;
1919     case PKCS12_RC2_40_SHA1:
1920       enc_params->cipher = GNUTLS_CIPHER_RC2_40_CBC;
1921       kdf_params->salt_size = 8;
1922       break;
1923     default:
1924       gnutls_assert ();
1925       return GNUTLS_E_INVALID_REQUEST;
1926     }
1927
1928   ret = _gnutls_rnd (GNUTLS_RND_RANDOM, kdf_params->salt,
1929                      kdf_params->salt_size);
1930   if (ret < 0)
1931     {
1932       gnutls_assert ();
1933       return GNUTLS_E_RANDOM_FAILED;
1934     }
1935
1936   kdf_params->iter_count = 256 + rnd[0];
1937   key->size = kdf_params->key_size =
1938     gnutls_cipher_get_key_size (enc_params->cipher);
1939
1940   enc_params->iv_size = _gnutls_cipher_get_iv_size (enc_params->cipher);
1941   key->data = gnutls_secure_malloc (key->size);
1942   if (key->data == NULL)
1943     {
1944       gnutls_assert ();
1945       return GNUTLS_E_MEMORY_ERROR;
1946     }
1947
1948   /* now generate the key. 
1949    */
1950
1951   switch (schema)
1952     {
1953     case PBES2_3DES:
1954     case PBES2_AES_128:
1955     case PBES2_AES_192:
1956     case PBES2_AES_256:
1957
1958       ret = _gnutls_pbkdf2_sha1 (password, strlen (password),
1959                                  kdf_params->salt, kdf_params->salt_size,
1960                                  kdf_params->iter_count,
1961                                  key->data, kdf_params->key_size);
1962       if (ret < 0)
1963         {
1964           gnutls_assert ();
1965           return ret;
1966         }
1967
1968       if (enc_params->iv_size)
1969         {
1970           ret = _gnutls_rnd (GNUTLS_RND_NONCE,
1971                              enc_params->iv, enc_params->iv_size);
1972           if (ret < 0)
1973             {
1974               gnutls_assert ();
1975               return ret;
1976             }
1977         }
1978       break;
1979
1980     default:
1981       ret =
1982         _gnutls_pkcs12_string_to_key (1 /*KEY*/, kdf_params->salt,
1983                                       kdf_params->salt_size,
1984                                       kdf_params->iter_count, password,
1985                                       kdf_params->key_size, key->data);
1986       if (ret < 0)
1987         {
1988           gnutls_assert ();
1989           return ret;
1990         }
1991
1992       /* Now generate the IV
1993        */
1994       if (enc_params->iv_size)
1995         {
1996           ret =
1997             _gnutls_pkcs12_string_to_key (2 /*IV*/, kdf_params->salt,
1998                                           kdf_params->salt_size,
1999                                           kdf_params->iter_count, password,
2000                                           enc_params->iv_size,
2001                                           enc_params->iv);
2002           if (ret < 0)
2003             {
2004               gnutls_assert ();
2005               return ret;
2006             }
2007         }
2008     }
2009
2010
2011   return 0;
2012 }
2013
2014
2015 /* Encodes the parameters to be written in the encryptionAlgorithm.parameters
2016  * part.
2017  */
2018 static int
2019 write_schema_params (schema_id schema, ASN1_TYPE pkcs8_asn,
2020                      const char *where,
2021                      const struct pbkdf2_params *kdf_params,
2022                      const struct pbe_enc_params *enc_params)
2023 {
2024   int result;
2025   ASN1_TYPE pbes2_asn = ASN1_TYPE_EMPTY;
2026
2027   switch (schema)
2028     {
2029     case PBES2_3DES:
2030     case PBES2_AES_128:
2031     case PBES2_AES_192:
2032     case PBES2_AES_256:
2033       if ((result =
2034            asn1_create_element (_gnutls_get_pkix (),
2035                                 "PKIX1.pkcs-5-PBES2-params",
2036                                 &pbes2_asn)) != ASN1_SUCCESS)
2037         {
2038           gnutls_assert ();
2039           return _gnutls_asn2err (result);
2040         }
2041
2042       result = write_pbkdf2_params (pbes2_asn, kdf_params);
2043       if (result < 0)
2044         {
2045           gnutls_assert ();
2046           goto error;
2047         }
2048
2049       result = write_pbe_enc_params (pbes2_asn, enc_params);
2050       if (result < 0)
2051         {
2052           gnutls_assert ();
2053           goto error;
2054         }
2055
2056       result = _gnutls_x509_der_encode_and_copy (pbes2_asn, "",
2057                                                  pkcs8_asn, where, 0);
2058       if (result < 0)
2059         {
2060           gnutls_assert ();
2061           goto error;
2062         }
2063
2064       asn1_delete_structure (&pbes2_asn);
2065       break;
2066
2067     default:
2068
2069       if ((result =
2070            asn1_create_element (_gnutls_get_pkix (),
2071                                 "PKIX1.pkcs-12-PbeParams",
2072                                 &pbes2_asn)) != ASN1_SUCCESS)
2073         {
2074           gnutls_assert ();
2075           result = _gnutls_asn2err (result);
2076           goto error;
2077         }
2078
2079       result = write_pkcs12_kdf_params (pbes2_asn, kdf_params);
2080       if (result < 0)
2081         {
2082           gnutls_assert ();
2083           goto error;
2084         }
2085
2086       result = _gnutls_x509_der_encode_and_copy (pbes2_asn, "",
2087                                                  pkcs8_asn, where, 0);
2088       if (result < 0)
2089         {
2090           gnutls_assert ();
2091           goto error;
2092         }
2093
2094       asn1_delete_structure (&pbes2_asn);
2095
2096     }
2097
2098   return 0;
2099
2100 error:
2101   asn1_delete_structure (&pbes2_asn);
2102   return result;
2103
2104 }
2105
2106 static int
2107 encrypt_data (const gnutls_datum_t * plain,
2108               const struct pbe_enc_params *enc_params,
2109               gnutls_datum_t * key, gnutls_datum_t * encrypted)
2110 {
2111   int result;
2112   int data_size;
2113   opaque *data = NULL;
2114   gnutls_datum_t d_iv;
2115   cipher_hd_st ch;
2116   int ch_init = 0;
2117   opaque pad, pad_size;
2118
2119   pad_size = gnutls_cipher_get_block_size (enc_params->cipher);
2120
2121   if (pad_size == 1)            /* stream */
2122     pad_size = 0;
2123
2124   data = gnutls_malloc (plain->size + pad_size);
2125   if (data == NULL)
2126     {
2127       gnutls_assert ();
2128       return GNUTLS_E_MEMORY_ERROR;
2129     }
2130
2131   memcpy (data, plain->data, plain->size);
2132
2133   if (pad_size > 0)
2134     {
2135       pad = pad_size - (plain->size % pad_size);
2136       if (pad == 0)
2137         pad = pad_size;
2138       memset (&data[plain->size], pad, pad);
2139     }
2140   else
2141     pad = 0;
2142
2143   data_size = plain->size + pad;
2144
2145   d_iv.data = (opaque *) enc_params->iv;
2146   d_iv.size = enc_params->iv_size;
2147   result = _gnutls_cipher_init (&ch, enc_params->cipher, key, &d_iv);
2148
2149   if (result < 0)
2150     {
2151       gnutls_assert ();
2152       goto error;
2153     }
2154
2155   ch_init = 1;
2156
2157   result = _gnutls_cipher_encrypt (&ch, data, data_size);
2158   if (result < 0)
2159     {
2160       gnutls_assert ();
2161       goto error;
2162     }
2163
2164   encrypted->data = data;
2165   encrypted->size = data_size;
2166
2167   _gnutls_cipher_deinit (&ch);
2168
2169   return 0;
2170
2171 error:
2172   gnutls_free (data);
2173   if (ch_init != 0)
2174     _gnutls_cipher_deinit (&ch);
2175   return result;
2176 }
2177
2178 /* Decrypts a PKCS #7 encryptedData. The output is allocated
2179  * and stored in dec.
2180  */
2181 int
2182 _gnutls_pkcs7_decrypt_data (const gnutls_datum_t * data,
2183                             const char *password, gnutls_datum_t * dec)
2184 {
2185   int result, len;
2186   char enc_oid[64];
2187   gnutls_datum_t tmp;
2188   ASN1_TYPE pbes2_asn = ASN1_TYPE_EMPTY, pkcs7_asn = ASN1_TYPE_EMPTY;
2189   int params_start, params_end, params_len;
2190   struct pbkdf2_params kdf_params;
2191   struct pbe_enc_params enc_params;
2192   schema_id schema;
2193
2194   if ((result =
2195        asn1_create_element (_gnutls_get_pkix (),
2196                             "PKIX1.pkcs-7-EncryptedData",
2197                             &pkcs7_asn)) != ASN1_SUCCESS)
2198     {
2199       gnutls_assert ();
2200       result = _gnutls_asn2err (result);
2201       goto error;
2202     }
2203
2204   result = asn1_der_decoding (&pkcs7_asn, data->data, data->size, NULL);
2205   if (result != ASN1_SUCCESS)
2206     {
2207       gnutls_assert ();
2208       result = _gnutls_asn2err (result);
2209       goto error;
2210     }
2211
2212   /* Check the encryption schema OID
2213    */
2214   len = sizeof (enc_oid);
2215   result =
2216     asn1_read_value (pkcs7_asn,
2217                      "encryptedContentInfo.contentEncryptionAlgorithm.algorithm",
2218                      enc_oid, &len);
2219   if (result != ASN1_SUCCESS)
2220     {
2221       gnutls_assert ();
2222       result = _gnutls_asn2err (result);
2223       goto error;
2224     }
2225
2226   if ((result = check_schema (enc_oid)) < 0)
2227     {
2228       gnutls_assert ();
2229       goto error;
2230     }
2231   schema = result;
2232
2233   /* Get the DER encoding of the parameters.
2234    */
2235   result =
2236     asn1_der_decoding_startEnd (pkcs7_asn, data->data, data->size,
2237                                 "encryptedContentInfo.contentEncryptionAlgorithm.parameters",
2238                                 &params_start, &params_end);
2239   if (result != ASN1_SUCCESS)
2240     {
2241       gnutls_assert ();
2242       result = _gnutls_asn2err (result);
2243       goto error;
2244     }
2245   params_len = params_end - params_start + 1;
2246
2247   result =
2248     read_pkcs_schema_params (&schema, password,
2249                              &data->data[params_start],
2250                              params_len, &kdf_params, &enc_params);
2251   if (result < ASN1_SUCCESS)
2252     {
2253       gnutls_assert ();
2254       result = _gnutls_asn2err (result);
2255       goto error;
2256     }
2257
2258   /* Parameters have been decoded. Now
2259    * decrypt the EncryptedData.
2260    */
2261
2262   result =
2263     decrypt_data (schema, pkcs7_asn,
2264                   "encryptedContentInfo.encryptedContent", password,
2265                   &kdf_params, &enc_params, &tmp);
2266   if (result < 0)
2267     {
2268       gnutls_assert ();
2269       goto error;
2270     }
2271
2272   asn1_delete_structure (&pkcs7_asn);
2273
2274   *dec = tmp;
2275
2276   return 0;
2277
2278 error:
2279   asn1_delete_structure (&pbes2_asn);
2280   asn1_delete_structure (&pkcs7_asn);
2281   return result;
2282 }
2283
2284 /* Encrypts to a PKCS #7 encryptedData. The output is allocated
2285  * and stored in enc.
2286  */
2287 int
2288 _gnutls_pkcs7_encrypt_data (schema_id schema,
2289                             const gnutls_datum_t * data,
2290                             const char *password, gnutls_datum_t * enc)
2291 {
2292   int result;
2293   gnutls_datum_t key = { NULL, 0 };
2294   gnutls_datum_t tmp = { NULL, 0 };
2295   ASN1_TYPE pkcs7_asn = ASN1_TYPE_EMPTY;
2296   struct pbkdf2_params kdf_params;
2297   struct pbe_enc_params enc_params;
2298   const char *str_oid;
2299
2300   if ((result =
2301        asn1_create_element (_gnutls_get_pkix (),
2302                             "PKIX1.pkcs-7-EncryptedData",
2303                             &pkcs7_asn)) != ASN1_SUCCESS)
2304     {
2305       gnutls_assert ();
2306       result = _gnutls_asn2err (result);
2307       goto error;
2308     }
2309
2310   /* Write the encryption schema OID
2311    */
2312   result = schema_to_oid (schema, &str_oid);
2313   if (result < 0)
2314     {
2315       gnutls_assert ();
2316       return result;
2317     }
2318
2319   result =
2320     asn1_write_value (pkcs7_asn,
2321                       "encryptedContentInfo.contentEncryptionAlgorithm.algorithm",
2322                       str_oid, 1);
2323
2324   if (result != ASN1_SUCCESS)
2325     {
2326       gnutls_assert ();
2327       result = _gnutls_asn2err (result);
2328       goto error;
2329     }
2330
2331   /* Generate a symmetric key.
2332    */
2333
2334   result = generate_key (schema, password, &kdf_params, &enc_params, &key);
2335   if (result < 0)
2336     {
2337       gnutls_assert ();
2338       goto error;
2339     }
2340
2341   result = write_schema_params (schema, pkcs7_asn,
2342                                 "encryptedContentInfo.contentEncryptionAlgorithm.parameters",
2343                                 &kdf_params, &enc_params);
2344   if (result < 0)
2345     {
2346       gnutls_assert ();
2347       goto error;
2348     }
2349
2350   /* Parameters have been encoded. Now
2351    * encrypt the Data.
2352    */
2353   result = encrypt_data (data, &enc_params, &key, &tmp);
2354   if (result < 0)
2355     {
2356       gnutls_assert ();
2357       goto error;
2358     }
2359
2360   /* write the encrypted data.
2361    */
2362   result =
2363     asn1_write_value (pkcs7_asn,
2364                       "encryptedContentInfo.encryptedContent", tmp.data,
2365                       tmp.size);
2366   if (result != ASN1_SUCCESS)
2367     {
2368       gnutls_assert ();
2369       result = _gnutls_asn2err (result);
2370       goto error;
2371     }
2372
2373   _gnutls_free_datum (&tmp);
2374   _gnutls_free_datum (&key);
2375
2376   /* Now write the rest of the pkcs-7 stuff.
2377    */
2378
2379   result = _gnutls_x509_write_uint32 (pkcs7_asn, "version", 0);
2380   if (result < 0)
2381     {
2382       gnutls_assert ();
2383       goto error;
2384     }
2385
2386   result =
2387     asn1_write_value (pkcs7_asn, "encryptedContentInfo.contentType",
2388                       DATA_OID, 1);
2389   if (result != ASN1_SUCCESS)
2390     {
2391       gnutls_assert ();
2392       result = _gnutls_asn2err (result);
2393       goto error;
2394     }
2395
2396   result = asn1_write_value (pkcs7_asn, "unprotectedAttrs", NULL, 0);
2397   if (result != ASN1_SUCCESS)
2398     {
2399       gnutls_assert ();
2400       result = _gnutls_asn2err (result);
2401       goto error;
2402     }
2403
2404   /* Now encode and copy the DER stuff.
2405    */
2406   result = _gnutls_x509_der_encode (pkcs7_asn, "", enc, 0);
2407
2408   asn1_delete_structure (&pkcs7_asn);
2409
2410   if (result < 0)
2411     {
2412       gnutls_assert ();
2413       goto error;
2414     }
2415
2416
2417 error:
2418   _gnutls_free_datum (&key);
2419   _gnutls_free_datum (&tmp);
2420   asn1_delete_structure (&pkcs7_asn);
2421   return result;
2422 }
2423
2424
2425 #endif