|
Packit Service |
4684c1 |
/* This example code is placed in the public domain. */
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#ifdef HAVE_CONFIG_H
|
|
Packit Service |
4684c1 |
#include <config.h>
|
|
Packit Service |
4684c1 |
#endif
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#include <stdio.h>
|
|
Packit Service |
4684c1 |
#include <stdlib.h>
|
|
Packit Service |
4684c1 |
#include <gnutls/gnutls.h>
|
|
Packit Service |
4684c1 |
#include <gnutls/pkcs12.h>
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#include "examples.h"
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#define OUTFILE "out.p12"
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* This function will write a pkcs12 structure into a file.
|
|
Packit Service |
4684c1 |
* cert: is a DER encoded certificate
|
|
Packit Service |
4684c1 |
* pkcs8_key: is a PKCS #8 encrypted key (note that this must be
|
|
Packit Service |
4684c1 |
* encrypted using a PKCS #12 cipher, or some browsers will crash)
|
|
Packit Service |
4684c1 |
* password: is the password used to encrypt the PKCS #12 packet.
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
int
|
|
Packit Service |
4684c1 |
write_pkcs12(const gnutls_datum_t * cert,
|
|
Packit Service |
4684c1 |
const gnutls_datum_t * pkcs8_key, const char *password)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
gnutls_pkcs12_t pkcs12;
|
|
Packit Service |
4684c1 |
int ret, bag_index;
|
|
Packit Service |
4684c1 |
gnutls_pkcs12_bag_t bag, key_bag;
|
|
Packit Service |
4684c1 |
char pkcs12_struct[10 * 1024];
|
|
Packit Service |
4684c1 |
size_t pkcs12_struct_size;
|
|
Packit Service |
4684c1 |
FILE *fp;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* A good idea might be to use gnutls_x509_privkey_get_key_id()
|
|
Packit Service |
4684c1 |
* to obtain a unique ID.
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
gnutls_datum_t key_id = { (void *) "\x00\x00\x07", 3 };
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
gnutls_global_init();
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* Firstly we create two helper bags, which hold the certificate,
|
|
Packit Service |
4684c1 |
* and the (encrypted) key.
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
gnutls_pkcs12_bag_init(&bag;;
|
|
Packit Service |
4684c1 |
gnutls_pkcs12_bag_init(&key_bag);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
gnutls_pkcs12_bag_set_data(bag, GNUTLS_BAG_CERTIFICATE, cert);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
fprintf(stderr, "ret: %s\n", gnutls_strerror(ret));
|
|
Packit Service |
4684c1 |
return 1;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* ret now holds the bag's index.
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
bag_index = ret;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* Associate a friendly name with the given certificate. Used
|
|
Packit Service |
4684c1 |
* by browsers.
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
gnutls_pkcs12_bag_set_friendly_name(bag, bag_index, "My name");
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* Associate the certificate with the key using a unique key
|
|
Packit Service |
4684c1 |
* ID.
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
gnutls_pkcs12_bag_set_key_id(bag, bag_index, &key_id);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* use weak encryption for the certificate.
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
gnutls_pkcs12_bag_encrypt(bag, password,
|
|
Packit Service |
4684c1 |
GNUTLS_PKCS_USE_PKCS12_RC2_40);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* Now the key.
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = gnutls_pkcs12_bag_set_data(key_bag,
|
|
Packit Service |
4684c1 |
GNUTLS_BAG_PKCS8_ENCRYPTED_KEY,
|
|
Packit Service |
4684c1 |
pkcs8_key);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
fprintf(stderr, "ret: %s\n", gnutls_strerror(ret));
|
|
Packit Service |
4684c1 |
return 1;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* Note that since the PKCS #8 key is already encrypted we don't
|
|
Packit Service |
4684c1 |
* bother encrypting that bag.
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
bag_index = ret;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
gnutls_pkcs12_bag_set_friendly_name(key_bag, bag_index, "My name");
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
gnutls_pkcs12_bag_set_key_id(key_bag, bag_index, &key_id);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* The bags were filled. Now create the PKCS #12 structure.
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
gnutls_pkcs12_init(&pkcs12);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* Insert the two bags in the PKCS #12 structure.
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
gnutls_pkcs12_set_bag(pkcs12, bag);
|
|
Packit Service |
4684c1 |
gnutls_pkcs12_set_bag(pkcs12, key_bag);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* Generate a message authentication code for the PKCS #12
|
|
Packit Service |
4684c1 |
* structure.
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
gnutls_pkcs12_generate_mac(pkcs12, password);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
pkcs12_struct_size = sizeof(pkcs12_struct);
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
gnutls_pkcs12_export(pkcs12, GNUTLS_X509_FMT_DER,
|
|
Packit Service |
4684c1 |
pkcs12_struct, &pkcs12_struct_size);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
fprintf(stderr, "ret: %s\n", gnutls_strerror(ret));
|
|
Packit Service |
4684c1 |
return 1;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
fp = fopen(OUTFILE, "w");
|
|
Packit Service |
4684c1 |
if (fp == NULL) {
|
|
Packit Service |
4684c1 |
fprintf(stderr, "cannot open file\n");
|
|
Packit Service |
4684c1 |
return 1;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
fwrite(pkcs12_struct, 1, pkcs12_struct_size, fp);
|
|
Packit Service |
4684c1 |
fclose(fp);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
gnutls_pkcs12_bag_deinit(bag);
|
|
Packit Service |
4684c1 |
gnutls_pkcs12_bag_deinit(key_bag);
|
|
Packit Service |
4684c1 |
gnutls_pkcs12_deinit(pkcs12);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|