Commit 9a48b07e authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

Various enhancements to PKCS#12 code, new
medium level API, improved PKCS12_create
and additional functionality in pkcs12
utility.
parent 230fd6b7
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -4,6 +4,22 @@

 Changes between 0.9.7 and 0.9.8  [xx XXX 2002]

  *) Add new 'medium level' PKCS#12 API. Certificates and keys
     can be added using this API to created arbitrary PKCS#12
     files while avoiding the low level API.

     New options to PKCS12_create(), key or cert can be NULL and
     will then be omitted from the output file. The encryption
     algorithm NIDs can be set to -1 for no encryption, the mac
     iteration count can be set to 0 to omit the mac.

     Enhance pkcs12 utility by making the -nokeys and -nocerts
     options work when creating a PKCS#12 file. New option -nomac
     to omit the mac, NONE can be set for an encryption algorithm.
     New code is modified to use the enhanced PKCS12_create()
     instead of the low level API.
     [Steve Henson]

  *) Extend ASN1 encoder to support indefinite length constructed
     encoding. This can output sequences tags and octet strings in
     this form. Modify pk7_asn1.c to support indefinite length
+94 −139
Original line number Diff line number Diff line
@@ -2,10 +2,10 @@
#if !defined(OPENSSL_NO_DES) && !defined(OPENSSL_NO_SHA1)

/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
 * project 1999.
 * project.
 */
/* ====================================================================
 * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
 * Copyright (c) 1999-2002 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
@@ -164,10 +164,14 @@ int MAIN(int argc, char **argv)
					 maciter = PKCS12_DEFAULT_ITER;
		else if (!strcmp (*args, "-nomaciter"))
					 maciter = 1;
		else if (!strcmp (*args, "-nomac"))
					 maciter = -1;
		else if (!strcmp (*args, "-nodes")) enc=NULL;
		else if (!strcmp (*args, "-certpbe")) {
			if (args[1]) {
				args++;
				if (!strcmp(*args, "NONE"))
					cert_pbe = -1;
				cert_pbe=OBJ_txt2nid(*args);
				if(cert_pbe == NID_undef) {
					BIO_printf(bio_err,
@@ -178,6 +182,9 @@ int MAIN(int argc, char **argv)
		} else if (!strcmp (*args, "-keypbe")) {
			if (args[1]) {
				args++;
				if (!strcmp(*args, "NONE"))
					key_pbe = -1;
				else
					key_pbe=OBJ_txt2nid(*args);
				if(key_pbe == NID_undef) {
					BIO_printf(bio_err,
@@ -357,24 +364,6 @@ int MAIN(int argc, char **argv)
	    goto end;
   }

#if 0
   if (certfile) {
    	if(!(certsin = BIO_new_file(certfile, "r"))) {
	    BIO_printf(bio_err, "Can't open certificate file %s\n", certfile);
	    perror (certfile);
	    goto end;
	}
    }

    if (keyname) {
    	if(!(inkey = BIO_new_file(keyname, "r"))) {
	    BIO_printf(bio_err, "Can't key certificate file %s\n", keyname);
	    perror (keyname);
	    goto end;
	}
     }
#endif

#ifdef CRYPTO_MDEBUG
    CRYPTO_pop_info();
    CRYPTO_push_info("write files");
@@ -411,25 +400,29 @@ int MAIN(int argc, char **argv)

    if (export_cert) {
	EVP_PKEY *key = NULL;
	STACK_OF(PKCS12_SAFEBAG) *bags = NULL;
	STACK_OF(PKCS7) *safes = NULL;
	PKCS12_SAFEBAG *bag = NULL;
	PKCS8_PRIV_KEY_INFO *p8 = NULL;
	PKCS7 *authsafe = NULL;
	X509 *ucert = NULL;
	X509 *ucert = NULL, *x = NULL;
	STACK_OF(X509) *certs=NULL;
	char *catmp = NULL;
	unsigned char *catmp = NULL;
	int i;
	unsigned char keyid[EVP_MAX_MD_SIZE];
	unsigned int keyidlen = 0;

	if ((options & (NOCERTS|NOKEYS)) == (NOCERTS|NOKEYS))
		{	
		BIO_printf(bio_err, "Nothing to do!\n");
		goto export_end;
		}

	if (options & NOCERTS)
		chain = 0;

#ifdef CRYPTO_MDEBUG
	CRYPTO_push_info("process -export_cert");
	CRYPTO_push_info("reading private key");
#endif
	key = load_key(bio_err, keyname ? keyname : infile, FORMAT_PEM, 1,
		passin, e, "private key");
	if (!key) {
	if (!(options & NOKEYS))
		{
		key = load_key(bio_err, keyname ? keyname : infile,
				FORMAT_PEM, 1, passin, e, "private key");
		if (!key)
			goto export_end;
		}

@@ -439,50 +432,62 @@ int MAIN(int argc, char **argv)
#endif

	/* Load in all certs in input file */
	if(!(certs = load_certs(bio_err, infile, FORMAT_PEM, NULL, e,
		"certificates"))) {
	if(!(options & NOCERTS))
		{
		certs = load_certs(bio_err, infile, FORMAT_PEM, NULL, e,
							"certificates");
		if (!certs)
			goto export_end;
	}

#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
	CRYPTO_push_info("reading certs from input 2");
#endif

	for(i = 0; i < sk_X509_num(certs); i++) {
		ucert = sk_X509_value(certs, i);
		if(X509_check_private_key(ucert, key)) {
			X509_digest(ucert, EVP_sha1(), keyid, &keyidlen);
		if (key)
			{
			/* Look for matching private key */
			for(i = 0; i < sk_X509_num(certs); i++)
				{
				x = sk_X509_value(certs, i);
				if(X509_check_private_key(x, key))
					{
					ucert = x;
					/* Zero keyid and alias */
					X509_keyid_set1(ucert, NULL, 0);
					X509_alias_set1(ucert, NULL, 0);
					/* Remove from list */
					sk_X509_delete(certs, i);
					break;
					}
				}
	if(!keyidlen) {
		ucert = NULL;
			if (!ucert)
				{
				BIO_printf(bio_err, "No certificate matches private key\n");
				goto export_end;
				}
			}

		}

#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
	CRYPTO_push_info("reading certs from certfile");
	CRYPTO_push_info("reading certs from input 2");
#endif

	bags = sk_PKCS12_SAFEBAG_new_null ();

	/* Add any more certificates asked for */
	if (certfile) {
	if(certfile)
		{
		STACK_OF(X509) *morecerts=NULL;
		if(!(morecerts = load_certs(bio_err, certfile, FORMAT_PEM,
					    NULL, e,
					    "certificates from certfile"))) {
					    "certificates from certfile")))
			goto export_end;
		}
		while(sk_X509_num(morecerts) > 0) {
		while(sk_X509_num(morecerts) > 0)
			sk_X509_push(certs, sk_X509_shift(morecerts));
		}
		sk_X509_free(morecerts);
 		}

#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
	CRYPTO_push_info("reading certs from certfile");
#endif

#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
	CRYPTO_push_info("building chain");
@@ -518,92 +523,43 @@ int MAIN(int argc, char **argv)
		}			
    	}

#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
	CRYPTO_push_info("building bags");
#endif
	/* Add any CA names */

	for (i = 0; i < sk_num(canames); i++)
		{
		catmp = (unsigned char *)sk_value(canames, i);
		X509_alias_set1(sk_X509_value(certs, i), catmp, -1);
		}
		
	/* We now have loads of certificates: include them all */
	for(i = 0; i < sk_X509_num(certs); i++) {
		X509 *cert = NULL;
		cert = sk_X509_value(certs, i);
		bag = PKCS12_x5092certbag(cert);
		/* If it matches private key set id */
		if(cert == ucert) {
			if(name) PKCS12_add_friendlyname(bag, name, -1);
			PKCS12_add_localkeyid(bag, keyid, keyidlen);
		} else if((catmp = sk_shift(canames))) 
				PKCS12_add_friendlyname(bag, catmp, -1);
		sk_PKCS12_SAFEBAG_push(bags, bag);
	}
	sk_X509_pop_free(certs, X509_free);
	certs = NULL;

#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
	CRYPTO_push_info("encrypting bags");
	CRYPTO_push_info("reading password");
#endif

	if(!noprompt &&
		EVP_read_pw_string(pass, 50, "Enter Export Password:", 1)) {
		EVP_read_pw_string(pass, 50, "Enter Export Password:", 1))
		{
	    	BIO_printf (bio_err, "Can't read Password\n");
	    	goto export_end;
        	}
	if (!twopass) strcpy(macpass, pass);
	/* Turn certbags into encrypted authsafe */
	authsafe = PKCS12_pack_p7encdata(cert_pbe, cpass, -1, NULL, 0,
								 iter, bags);
	sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
	bags = NULL;

	if (!authsafe) {
		ERR_print_errors (bio_err);
		goto export_end;
	}

	safes = sk_PKCS7_new_null ();
	sk_PKCS7_push (safes, authsafe);

#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
	CRYPTO_push_info("building shrouded key bag");
	CRYPTO_push_info("creating PKCS#12 structure");
#endif

	/* Make a shrouded key bag */
	p8 = EVP_PKEY2PKCS8 (key);
	if(keytype) PKCS8_add_keyusage(p8, keytype);
	bag = PKCS12_MAKE_SHKEYBAG(key_pbe, cpass, -1, NULL, 0, iter, p8);
	PKCS8_PRIV_KEY_INFO_free(p8);
	p8 = NULL;
        if (name) PKCS12_add_friendlyname (bag, name, -1);
	if(csp_name) PKCS12_add_CSPName_asc(bag, csp_name, -1);
	PKCS12_add_localkeyid (bag, keyid, keyidlen);
	bags = sk_PKCS12_SAFEBAG_new_null();
	sk_PKCS12_SAFEBAG_push (bags, bag);

#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
	CRYPTO_push_info("encrypting shrouded key bag");
#endif
	p12 = PKCS12_create(pass, name, key, ucert, certs,
				key_pbe, cert_pbe, iter, -1, keytype);

	/* Turn it into unencrypted safe bag */
	authsafe = PKCS12_pack_p7data (bags);
	sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
	bags = NULL;
	sk_PKCS7_push (safes, authsafe);

#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
	CRYPTO_push_info("building pkcs12");
#endif

	p12 = PKCS12_init(NID_pkcs7_data);

	PKCS12_pack_authsafes(p12, safes);

	sk_PKCS7_pop_free(safes, PKCS7_free);
	safes = NULL;
	if (!p12)
		{
	    	ERR_print_errors (bio_err);
		goto export_end;
		}

	if (maciter != -1)
		PKCS12_set_mac(p12, mpass, -1, NULL, 0, maciter, NULL);

#ifdef CRYPTO_MDEBUG
@@ -624,8 +580,7 @@ int MAIN(int argc, char **argv)

	if (key) EVP_PKEY_free(key);
	if (certs) sk_X509_pop_free(certs, X509_free);
	if (safes) sk_PKCS7_pop_free(safes, PKCS7_free);
	if (bags) sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
	if (ucert) X509_free(ucert);

#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
+23 −0
Original line number Diff line number Diff line
@@ -91,6 +91,14 @@ static X509_CERT_AUX *aux_get(X509 *x)
int X509_alias_set1(X509 *x, unsigned char *name, int len)
{
	X509_CERT_AUX *aux;
	if (!name)
		{
		if (!x || !x->aux || !x->aux->alias)
			return 1;
		ASN1_UTF8STRING_free(x->aux->alias);
		x->aux->alias = NULL;
		return 1;
		}
	if(!(aux = aux_get(x))) return 0;
	if(!aux->alias && !(aux->alias = ASN1_UTF8STRING_new())) return 0;
	return ASN1_STRING_set(aux->alias, name, len);
@@ -99,6 +107,14 @@ int X509_alias_set1(X509 *x, unsigned char *name, int len)
int X509_keyid_set1(X509 *x, unsigned char *id, int len)
{
	X509_CERT_AUX *aux;
	if (!id)
		{
		if (!x || !x->aux || !x->aux->keyid)
			return 1;
		ASN1_OCTET_STRING_free(x->aux->keyid);
		x->aux->keyid = NULL;
		return 1;
		}
	if(!(aux = aux_get(x))) return 0;
	if(!aux->keyid && !(aux->keyid = ASN1_OCTET_STRING_new())) return 0;
	return ASN1_STRING_set(aux->keyid, id, len);
@@ -111,6 +127,13 @@ unsigned char *X509_alias_get0(X509 *x, int *len)
	return x->aux->alias->data;
}

unsigned char *X509_keyid_get0(X509 *x, int *len)
{
	if(!x->aux || !x->aux->keyid) return NULL;
	if(len) *len = x->aux->keyid->length;
	return x->aux->keyid->data;
}

int X509_add1_trust_object(X509 *x, ASN1_OBJECT *obj)
{
	X509_CERT_AUX *aux;
+244 −72
Original line number Diff line number Diff line
/* p12_crt.c */
/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
 * project 1999.
 * project.
 */
/* ====================================================================
 * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
 * Copyright (c) 1999-2002 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
@@ -60,104 +60,276 @@
#include "cryptlib.h"
#include <openssl/pkcs12.h>


static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags, PKCS12_SAFEBAG *bag);

PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert,
	     STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter, int mac_iter,
	     int keytype)
{
	PKCS12 *p12;
	STACK_OF(PKCS12_SAFEBAG) *bags;
	STACK_OF(PKCS7) *safes;
	PKCS12_SAFEBAG *bag;
	PKCS8_PRIV_KEY_INFO *p8;
	PKCS7 *authsafe;
	X509 *tcert;
	PKCS12 *p12 = NULL;
	STACK_OF(PKCS7) *safes = NULL;
	STACK_OF(PKCS12_SAFEBAG) *bags = NULL;
	PKCS12_SAFEBAG *bag = NULL;
	int i;
	unsigned char keyid[EVP_MAX_MD_SIZE];
	unsigned int keyidlen;
	unsigned int keyidlen = 0;

	/* Set defaults */
	if(!nid_cert) nid_cert = NID_pbe_WithSHA1And40BitRC2_CBC;
	if(!nid_key) nid_key = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
	if(!iter) iter = PKCS12_DEFAULT_ITER;
	if(!mac_iter) mac_iter = 1;
	if (!nid_cert)
		nid_cert = NID_pbe_WithSHA1And40BitRC2_CBC;
	if (!nid_key)
		nid_key = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
	if (!iter)
		iter = PKCS12_DEFAULT_ITER;
	if (!mac_iter)
		mac_iter = 1;

	if(!pkey || !cert) {
	if(!pkey && !cert && !ca)
		{
		PKCS12err(PKCS12_F_PKCS12_CREATE,PKCS12_R_INVALID_NULL_ARGUMENT);
		return NULL;
		}

	if(!X509_check_private_key(cert, pkey)) return NULL;

	if(!(bags = sk_PKCS12_SAFEBAG_new_null ())) {
		PKCS12err(PKCS12_F_PKCS12_CREATE,ERR_R_MALLOC_FAILURE);
	if (pkey && cert)
		{
		if(!X509_check_private_key(cert, pkey))
			return NULL;
	}

	/* Add user certificate */
	if(!(bag = PKCS12_x5092certbag(cert))) return NULL;
	if(name && !PKCS12_add_friendlyname(bag, name, -1)) return NULL;
		X509_digest(cert, EVP_sha1(), keyid, &keyidlen);
	if(!PKCS12_add_localkeyid(bag, keyid, keyidlen)) return NULL;
		}

	if(!sk_PKCS12_SAFEBAG_push(bags, bag)) {
		PKCS12err(PKCS12_F_PKCS12_CREATE,ERR_R_MALLOC_FAILURE);
		return NULL;
	if (cert)
		{
		bag = PKCS12_add_cert(&bags, cert);
		if(name && !PKCS12_add_friendlyname(bag, name, -1))
			goto err;
		if(keyidlen && !PKCS12_add_localkeyid(bag, keyid, keyidlen))
			goto err;
		}

	/* Add all other certificates */
	if(ca) {
		for(i = 0; i < sk_X509_num(ca); i++) {
			tcert = sk_X509_value(ca, i);
			if(!(bag = PKCS12_x5092certbag(tcert))) return NULL;
			if(!sk_PKCS12_SAFEBAG_push(bags, bag)) {
				PKCS12err(PKCS12_F_PKCS12_CREATE,ERR_R_MALLOC_FAILURE);
				return NULL;
			}
	for(i = 0; i < sk_X509_num(ca); i++)
		{
		if (!PKCS12_add_cert(&bags, sk_X509_value(ca, i)))
			goto err;
		}

	if (bags && !PKCS12_add_safe(&safes, bags, nid_cert, iter, pass))
			goto err;

	sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
	bags = NULL;

	if (pkey)
		{
		bag = PKCS12_add_key(&bags, pkey, keytype, iter, nid_key, pass);
		if (!bag)
			goto err;
		if(name && !PKCS12_add_friendlyname(bag, name, -1))
			goto err;
		if(keyidlen && !PKCS12_add_localkeyid(bag, keyid, keyidlen))
			goto err;
		}

	/* Turn certbags into encrypted authsafe */
	authsafe = PKCS12_pack_p7encdata (nid_cert, pass, -1, NULL, 0,
					  iter, bags);
	if (bags && !PKCS12_add_safe(&safes, bags, -1, 0, NULL))
			goto err;

	sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
	bags = NULL;

	p12 = PKCS12_add_safes(safes, 0);

	sk_PKCS7_pop_free(safes, PKCS7_free);

	safes = NULL;

	if ((mac_iter != -1) &&
		!PKCS12_set_mac(p12, pass, -1, NULL, 0, mac_iter, NULL))
	    goto err;

	return p12;

	err:

	if (p12)
		PKCS12_free(p12);
	if (safes)
		sk_PKCS7_pop_free(safes, PKCS7_free);
	if (bags)
		sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
	return NULL;

}

PKCS12_SAFEBAG *PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert)
	{
	PKCS12_SAFEBAG *bag = NULL;
	char *name;
	int namelen = -1;
	unsigned char *keyid;
	int keyidlen = -1;

	/* Add user certificate */
	if(!(bag = PKCS12_x5092certbag(cert)))
		goto err;

	/* Use friendlyName and localKeyID in certificate.
	 * (if present)
	 */

	name = (char *)X509_alias_get0(cert, &namelen);

	if(name && !PKCS12_add_friendlyname(bag, name, namelen))
		goto err;

	keyid = X509_keyid_get0(cert, &keyidlen);

	if(keyid && !PKCS12_add_localkeyid(bag, keyid, keyidlen))
		goto err;

	if (!pkcs12_add_bag(pbags, bag))
		goto err;

	return bag;

	err:

	if (!authsafe) return NULL;
	if (bag)
		PKCS12_SAFEBAG_free(bag);

	if(!(safes = sk_PKCS7_new_null ())
	   || !sk_PKCS7_push(safes, authsafe)) {
		PKCS12err(PKCS12_F_PKCS12_CREATE,ERR_R_MALLOC_FAILURE);
	return NULL;

	}

	/* Make a shrouded key bag */
	if(!(p8 = EVP_PKEY2PKCS8 (pkey))) return NULL;
	if(keytype && !PKCS8_add_keyusage(p8, keytype)) return NULL;
PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags, EVP_PKEY *key,
						int key_usage, int iter,
						int nid_key, char *pass)
	{

	PKCS12_SAFEBAG *bag = NULL;
	PKCS8_PRIV_KEY_INFO *p8 = NULL;

	/* Make a PKCS#8 structure */
	if(!(p8 = EVP_PKEY2PKCS8(key)))
		goto err;
	if(key_usage && !PKCS8_add_keyusage(p8, key_usage))
		goto err;
	if (nid_key != -1)
		{
		bag = PKCS12_MAKE_SHKEYBAG(nid_key, pass, -1, NULL, 0, iter, p8);
	if(!bag) return NULL;
		PKCS8_PRIV_KEY_INFO_free(p8);
        if (name && !PKCS12_add_friendlyname (bag, name, -1)) return NULL;
	if(!PKCS12_add_localkeyid (bag, keyid, keyidlen)) return NULL;
	if(!(bags = sk_PKCS12_SAFEBAG_new_null())
	   || !sk_PKCS12_SAFEBAG_push (bags, bag)) {
		PKCS12err(PKCS12_F_PKCS12_CREATE,ERR_R_MALLOC_FAILURE);
		return NULL;
		}
	/* Turn it into unencrypted safe bag */
	if(!(authsafe = PKCS12_pack_p7data (bags))) return NULL;
	sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
	if(!sk_PKCS7_push(safes, authsafe)) {
		PKCS12err(PKCS12_F_PKCS12_CREATE,ERR_R_MALLOC_FAILURE);
	else
		bag = PKCS12_MAKE_KEYBAG(p8);

	if(!bag)
		goto err;

	if (!pkcs12_add_bag(pbags, bag))
		goto err;

	return bag;

	err:

	if (bag)
		PKCS12_SAFEBAG_free(bag);

	return NULL;

	}

	if(!(p12 = PKCS12_init (NID_pkcs7_data))) return NULL;
int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags,
						int nid_safe, int iter, char *pass)
	{
	PKCS7 *p7 = NULL;
	int free_safes = 0;

	if (!*psafes)
		{
		*psafes = sk_PKCS7_new_null();
		if (!*psafes)
			return 0;
		free_safes = 1;
		}
	else
		free_safes = 0;

	if(!PKCS12_pack_authsafes (p12, safes)) return NULL;
	if (nid_safe == 0)
		nid_safe = NID_pbe_WithSHA1And40BitRC2_CBC;

	sk_PKCS7_pop_free(safes, PKCS7_free);
	if (nid_safe == -1)
		p7 = PKCS12_pack_p7data(bags);
	else
		p7 = PKCS12_pack_p7encdata(nid_safe, pass, -1, NULL, 0,
					  iter, bags);
	if (!p7)
		goto err;

	if (!sk_PKCS7_push(*psafes, p7))
		goto err;

	return 1;

	err:
	if (free_safes)
		{
		sk_PKCS7_free(*psafes);
		*psafes = NULL;
		}

	if(!PKCS12_set_mac (p12, pass, -1, NULL, 0, mac_iter, NULL))
	if (p7)
		PKCS7_free(p7);

	return 0;

	}

static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags, PKCS12_SAFEBAG *bag)
	{
	int free_bags;
	if (!pbags)
		return 1;
	if (!*pbags)
		{
		*pbags = sk_PKCS12_SAFEBAG_new_null();
		if (!*pbags)
			return 0;
		free_bags = 1;
		}
	else 
		free_bags = 0;

	if (!sk_PKCS12_SAFEBAG_push(*pbags, bag))
		{
		if (free_bags)
			{
			sk_PKCS12_SAFEBAG_free(*pbags);
			*pbags = NULL;
			}
		return 0;
		}

	return 1;

	}
		

PKCS12 *PKCS12_add_safes(STACK_OF(PKCS7) *safes, int nid_p7)
	{
	PKCS12 *p12;
	if (nid_p7 <= 0)
		nid_p7 = NID_pkcs7_data;
	p12 = PKCS12_init(nid_p7);

	if (!p12)
		return NULL;

	if(!PKCS12_pack_authsafes(p12, safes))
		{
		PKCS12_free(p12);
		return NULL;
		}

	return p12;

+9 −0
Original line number Diff line number Diff line
@@ -249,6 +249,15 @@ int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert,
PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert,
			 STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter,
						 int mac_iter, int keytype);

PKCS12_SAFEBAG *PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert);
PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags, EVP_PKEY *key,
						int key_usage, int iter,
						int key_nid, char *pass);
int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags,
					int safe_nid, int iter, char *pass);
PKCS12 *PKCS12_add_safes(STACK_OF(PKCS7) *safes, int p7_nid);

int i2d_PKCS12_bio(BIO *bp, PKCS12 *p12);
int i2d_PKCS12_fp(FILE *fp, PKCS12 *p12);
PKCS12 *d2i_PKCS12_bio(BIO *bp, PKCS12 **p12);
Loading