Tizen 2.0 Release
[external/libgnutls26.git] / doc / examples / ex-pkcs12.c
1 /* This example code is placed in the public domain. */
2
3 #ifdef HAVE_CONFIG_H
4 #include <config.h>
5 #endif
6
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <gnutls/gnutls.h>
10 #include <gnutls/pkcs12.h>
11
12 #include "examples.h"
13
14 #define OUTFILE "out.p12"
15
16 /* This function will write a pkcs12 structure into a file.
17  * cert: is a DER encoded certificate
18  * pkcs8_key: is a PKCS #8 encrypted key (note that this must be
19  *  encrypted using a PKCS #12 cipher, or some browsers will crash)
20  * password: is the password used to encrypt the PKCS #12 packet.
21  */
22 int
23 write_pkcs12 (const gnutls_datum_t * cert,
24               const gnutls_datum_t * pkcs8_key, const char *password)
25 {
26   gnutls_pkcs12_t pkcs12;
27   int ret, bag_index;
28   gnutls_pkcs12_bag_t bag, key_bag;
29   char pkcs12_struct[10 * 1024];
30   size_t pkcs12_struct_size;
31   FILE *fd;
32
33   /* A good idea might be to use gnutls_x509_privkey_get_key_id()
34    * to obtain a unique ID.
35    */
36   gnutls_datum_t key_id = { (char *) "\x00\x00\x07", 3 };
37
38   gnutls_global_init ();
39
40   /* Firstly we create two helper bags, which hold the certificate,
41    * and the (encrypted) key.
42    */
43
44   gnutls_pkcs12_bag_init (&bag);
45   gnutls_pkcs12_bag_init (&key_bag);
46
47   ret = gnutls_pkcs12_bag_set_data (bag, GNUTLS_BAG_CERTIFICATE, cert);
48   if (ret < 0)
49     {
50       fprintf (stderr, "ret: %s\n", gnutls_strerror (ret));
51       return 1;
52     }
53
54   /* ret now holds the bag's index.
55    */
56   bag_index = ret;
57
58   /* Associate a friendly name with the given certificate. Used
59    * by browsers.
60    */
61   gnutls_pkcs12_bag_set_friendly_name (bag, bag_index, "My name");
62
63   /* Associate the certificate with the key using a unique key
64    * ID.
65    */
66   gnutls_pkcs12_bag_set_key_id (bag, bag_index, &key_id);
67
68   /* use weak encryption for the certificate. 
69    */
70   gnutls_pkcs12_bag_encrypt (bag, password, GNUTLS_PKCS_USE_PKCS12_RC2_40);
71
72   /* Now the key.
73    */
74
75   ret = gnutls_pkcs12_bag_set_data (key_bag,
76                                     GNUTLS_BAG_PKCS8_ENCRYPTED_KEY,
77                                     pkcs8_key);
78   if (ret < 0)
79     {
80       fprintf (stderr, "ret: %s\n", gnutls_strerror (ret));
81       return 1;
82     }
83
84   /* Note that since the PKCS #8 key is already encrypted we don't
85    * bother encrypting that bag.
86    */
87   bag_index = ret;
88
89   gnutls_pkcs12_bag_set_friendly_name (key_bag, bag_index, "My name");
90
91   gnutls_pkcs12_bag_set_key_id (key_bag, bag_index, &key_id);
92
93
94   /* The bags were filled. Now create the PKCS #12 structure.
95    */
96   gnutls_pkcs12_init (&pkcs12);
97
98   /* Insert the two bags in the PKCS #12 structure.
99    */
100
101   gnutls_pkcs12_set_bag (pkcs12, bag);
102   gnutls_pkcs12_set_bag (pkcs12, key_bag);
103
104
105   /* Generate a message authentication code for the PKCS #12
106    * structure.
107    */
108   gnutls_pkcs12_generate_mac (pkcs12, password);
109
110   pkcs12_struct_size = sizeof (pkcs12_struct);
111   ret =
112     gnutls_pkcs12_export (pkcs12, GNUTLS_X509_FMT_DER, pkcs12_struct,
113                           &pkcs12_struct_size);
114   if (ret < 0)
115     {
116       fprintf (stderr, "ret: %s\n", gnutls_strerror (ret));
117       return 1;
118     }
119
120   fd = fopen (OUTFILE, "w");
121   if (fd == NULL)
122     {
123       fprintf (stderr, "cannot open file\n");
124       return 1;
125     }
126   fwrite (pkcs12_struct, 1, pkcs12_struct_size, fd);
127   fclose (fd);
128
129   gnutls_pkcs12_bag_deinit (bag);
130   gnutls_pkcs12_bag_deinit (key_bag);
131   gnutls_pkcs12_deinit (pkcs12);
132
133   return 0;
134 }