| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
5.1.4 PKCS #12 structures
A PKCS #12 structure [PKCS12] private keys and certificates. It is commonly used in browsers to export and import the user’s identities.
In GnuTLS the PKCS #12 structures are handled
using the gnutls_pkcs12_t type. This is an abstract type that
may hold several gnutls_pkcs12_bag_t types. The Bag types are
the holders of the actual data, which may be certificates, private
keys or encrypted data. An Bag of type encrypted should be decrypted
in order for its data to be accessed.
An example of a PKCS #12 structure generation can be found below.
/* This example code is placed in the public domain. */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <gnutls/gnutls.h>
#include <gnutls/pkcs12.h>
#include "examples.h"
#define OUTFILE "out.p12"
/* This function will write a pkcs12 structure into a file.
* cert: is a DER encoded certificate
* pkcs8_key: is a PKCS #8 encrypted key (note that this must be
* encrypted using a PKCS #12 cipher, or some browsers will crash)
* password: is the password used to encrypt the PKCS #12 packet.
*/
int
write_pkcs12 (const gnutls_datum_t * cert,
const gnutls_datum_t * pkcs8_key, const char *password)
{
gnutls_pkcs12_t pkcs12;
int ret, bag_index;
gnutls_pkcs12_bag_t bag, key_bag;
char pkcs12_struct[10 * 1024];
size_t pkcs12_struct_size;
FILE *fd;
/* A good idea might be to use gnutls_x509_privkey_get_key_id()
* to obtain a unique ID.
*/
gnutls_datum_t key_id = { (char *) "\x00\x00\x07", 3 };
gnutls_global_init ();
/* Firstly we create two helper bags, which hold the certificate,
* and the (encrypted) key.
*/
gnutls_pkcs12_bag_init (&bag);
gnutls_pkcs12_bag_init (&key_bag);
ret = gnutls_pkcs12_bag_set_data (bag, GNUTLS_BAG_CERTIFICATE, cert);
if (ret < 0)
{
fprintf (stderr, "ret: %s\n", gnutls_strerror (ret));
return 1;
}
/* ret now holds the bag's index.
*/
bag_index = ret;
/* Associate a friendly name with the given certificate. Used
* by browsers.
*/
gnutls_pkcs12_bag_set_friendly_name (bag, bag_index, "My name");
/* Associate the certificate with the key using a unique key
* ID.
*/
gnutls_pkcs12_bag_set_key_id (bag, bag_index, &key_id);
/* use weak encryption for the certificate.
*/
gnutls_pkcs12_bag_encrypt (bag, password, GNUTLS_PKCS_USE_PKCS12_RC2_40);
/* Now the key.
*/
ret = gnutls_pkcs12_bag_set_data (key_bag,
GNUTLS_BAG_PKCS8_ENCRYPTED_KEY,
pkcs8_key);
if (ret < 0)
{
fprintf (stderr, "ret: %s\n", gnutls_strerror (ret));
return 1;
}
/* Note that since the PKCS #8 key is already encrypted we don't
* bother encrypting that bag.
*/
bag_index = ret;
gnutls_pkcs12_bag_set_friendly_name (key_bag, bag_index, "My name");
gnutls_pkcs12_bag_set_key_id (key_bag, bag_index, &key_id);
/* The bags were filled. Now create the PKCS #12 structure.
*/
gnutls_pkcs12_init (&pkcs12);
/* Insert the two bags in the PKCS #12 structure.
*/
gnutls_pkcs12_set_bag (pkcs12, bag);
gnutls_pkcs12_set_bag (pkcs12, key_bag);
/* Generate a message authentication code for the PKCS #12
* structure.
*/
gnutls_pkcs12_generate_mac (pkcs12, password);
pkcs12_struct_size = sizeof (pkcs12_struct);
ret =
gnutls_pkcs12_export (pkcs12, GNUTLS_X509_FMT_DER, pkcs12_struct,
&pkcs12_struct_size);
if (ret < 0)
{
fprintf (stderr, "ret: %s\n", gnutls_strerror (ret));
return 1;
}
fd = fopen (OUTFILE, "w");
if (fd == NULL)
{
fprintf (stderr, "cannot open file\n");
return 1;
}
fwrite (pkcs12_struct, 1, pkcs12_struct_size, fd);
fclose (fd);
gnutls_pkcs12_bag_deinit (bag);
gnutls_pkcs12_bag_deinit (key_bag);
gnutls_pkcs12_deinit (pkcs12);
return 0;
}
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
