/** * gnutls_pkcs12_bag_set_crl - This function inserts the CRL into the bag * @bag: The bag * @crl: the CRL to be copied. * * This function will insert the given CRL into the * bag. This is just a wrapper over gnutls_pkcs12_bag_set_data(). * * Returns the index of the added bag on success, or a negative * value on failure. * **/ int gnutls_pkcs12_bag_set_crl (gnutls_pkcs12_bag_t bag, gnutls_x509_crl_t crl) { int ret; gnutls_datum_t data; if (bag == NULL) { gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } ret = _gnutls_x509_der_encode (crl->crl, "", &data, 0); if (ret < 0) { gnutls_assert (); return ret; } ret = gnutls_pkcs12_bag_set_data (bag, GNUTLS_BAG_CRL, &data); _gnutls_free_datum (&data); return ret; }
/** * gnutls_pkcs12_bag_set_privkey: * @bag: The bag * @privkey: the private key to be copied. * @password: the password to protect the key with (may be %NULL) * @flags: should be one of #gnutls_pkcs_encrypt_flags_t elements bitwise or'd * * This function will insert the given private key into the * bag. This is just a wrapper over gnutls_pkcs12_bag_set_data(). * * Returns: the index of the added bag on success, or a negative * value on failure. **/ int gnutls_pkcs12_bag_set_privkey(gnutls_pkcs12_bag_t bag, gnutls_x509_privkey_t privkey, const char *password, unsigned flags) { int ret; gnutls_datum_t data = {NULL, 0}; if (bag == NULL) { gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; } ret = gnutls_x509_privkey_export2_pkcs8(privkey, GNUTLS_X509_FMT_DER, password, flags, &data); if (ret < 0) return gnutls_assert_val(ret); if (password == NULL) { ret = gnutls_pkcs12_bag_set_data(bag, GNUTLS_BAG_PKCS8_KEY, &data); if (ret < 0) { gnutls_assert(); goto cleanup; } } else { ret = gnutls_pkcs12_bag_set_data(bag, GNUTLS_BAG_PKCS8_ENCRYPTED_KEY, &data); if (ret < 0) { gnutls_assert(); goto cleanup; } } cleanup: _gnutls_free_datum(&data); return ret; }
/* 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 = { "\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; }