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

Fix a memory leak in PKCS12_parse.

Don't copy private key to X509 etc public key structures.
Fix for warning.
parent d12cd419
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -4,6 +4,13 @@

 Changes between 0.9.5 and 0.9.5a  [XX XXX 2000]

  *) Modernise PKCS12_parse() so it uses STACK_OF(X509) for its ca argument
     fix a leak when the ca argument was passed as NULL. Stop X509_PUBKEY_set()
     using the passed key: if the passed key was a private key the result
     of X509_print(), for example, would be to print out all the private key
     components.
     [Steve Henson]

  *) des_quad_cksum() byte order bug fix.
     [Ulf Möller, using the problem description in krb4-0.9.7, where
      the solution is attributed to Derrick J Brashear <shadow@DEMENTIA.ORG>]
+2 −0
Original line number Diff line number Diff line
@@ -183,8 +183,10 @@ int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)

	Free(s);

#if 0
	CRYPTO_add(&pkey->references,1,CRYPTO_LOCK_EVP_PKEY);
	pk->pkey=pkey;
#endif

	if (*x != NULL)
		X509_PUBKEY_free(*x);
+1 −1
Original line number Diff line number Diff line
@@ -709,7 +709,7 @@ plain[8+4], plain[8+5], plain[8+6], plain[8+7]);

	printf("Doing quad_cksum\n");
	cs=quad_cksum(cbc_data,(des_cblock *)lqret,
		(long)strlen(cbc_data),2,(des_cblock *)cbc_iv);
		(long)strlen((char *)cbc_data),2,(des_cblock *)cbc_iv);
	if (cs != 0x70d7a63aL)
		{
		printf("quad_cksum error, ret %08lx should be 70d7a63a\n",
+3 −3
Original line number Diff line number Diff line
@@ -61,7 +61,7 @@
#include <openssl/pkcs12.h>

PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert,
	     STACK *ca, int nid_key, int nid_cert, int iter, int mac_iter,
	     STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter, int mac_iter,
	     int keytype)
{
	PKCS12 *p12;
@@ -103,8 +103,8 @@ PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert,
	
	/* Add all other certificates */
	if(ca) {
		for(i = 0; i < sk_num(ca); i++) {
			tcert = (X509 *)sk_value(ca, i);
		for(i = 0; i < sk_X509_num(ca); i++) {
			tcert = sk_X509_value(ca, i);
			if(!(bag = M_PKCS12_x5092certbag(tcert))) return NULL;
			if(!sk_push(bags, (char *)bag)) {
				PKCS12err(PKCS12_F_PKCS12_CREATE,ERR_R_MALLOC_FAILURE);
+21 −10
Original line number Diff line number Diff line
@@ -62,9 +62,17 @@

/* Simplified PKCS#12 routines */

static int parse_pk12( PKCS12 *p12, const char *pass, int passlen, EVP_PKEY **pkey, X509 **cert, STACK **ca);
static int parse_bags( STACK *bags, const char *pass, int passlen, EVP_PKEY **pkey, X509 **cert, STACK **ca, ASN1_OCTET_STRING **keyid, char *keymatch);
static int parse_bag( PKCS12_SAFEBAG *bag, const char *pass, int passlen, EVP_PKEY **pkey, X509 **cert, STACK **ca, ASN1_OCTET_STRING **keyid, char *keymatch);
static int parse_pk12( PKCS12 *p12, const char *pass, int passlen,
		EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca);

static int parse_bags( STACK *bags, const char *pass, int passlen,
		EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca,
		ASN1_OCTET_STRING **keyid, char *keymatch);

static int parse_bag( PKCS12_SAFEBAG *bag, const char *pass, int passlen,
			EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca,
			ASN1_OCTET_STRING **keyid, char *keymatch);

/* Parse and decrypt a PKCS#12 structure returning user key, user cert
 * and other (CA) certs. Note either ca should be NULL, *ca should be NULL,
 * or it should point to a valid STACK structure. pkey and cert can be
@@ -72,7 +80,7 @@ static int parse_bag( PKCS12_SAFEBAG *bag, const char *pass, int passlen, EVP_PK
 */

int PKCS12_parse (PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert,
	     STACK **ca)
	     STACK_OF(X509) **ca)
{

	/* Check for NULL PKCS12 structure */
@@ -86,7 +94,7 @@ int PKCS12_parse (PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert,
	/* Allocate stack for ca certificates if needed */
	if ((ca != NULL) && (*ca == NULL))
		{
		if (!(*ca = sk_new(NULL)))
		if (!(*ca = sk_X509_new(NULL)))
			{
			PKCS12err(PKCS12_F_PKCS12_PARSE,ERR_R_MALLOC_FAILURE);
			return 0;
@@ -116,7 +124,7 @@ int PKCS12_parse (PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert,

	if (pkey && *pkey) EVP_PKEY_free (*pkey);
	if (cert && *cert) X509_free (*cert);
	if (ca) sk_pop_free (*ca, X509_free);
	if (ca) sk_X509_pop_free (*ca, X509_free);
	return 0;

}
@@ -124,7 +132,7 @@ int PKCS12_parse (PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert,
/* Parse the outer PKCS#12 structure */

static int parse_pk12 (PKCS12 *p12, const char *pass, int passlen,
	     EVP_PKEY **pkey, X509 **cert, STACK **ca)
	     EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca)
{
	STACK *asafes, *bags;
	int i, bagnid;
@@ -159,7 +167,7 @@ static int parse_pk12 (PKCS12 *p12, const char *pass, int passlen,


static int parse_bags (STACK *bags, const char *pass, int passlen,
		       EVP_PKEY **pkey, X509 **cert, STACK **ca,
		       EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca,
		       ASN1_OCTET_STRING **keyid, char *keymatch)
{
	int i;
@@ -176,7 +184,7 @@ static int parse_bags (STACK *bags, const char *pass, int passlen,
#define MATCH_ALL  0x3

static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen,
		      EVP_PKEY **pkey, X509 **cert, STACK **ca,
		      EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca,
		      ASN1_OCTET_STRING **keyid,
	     char *keymatch)
{
@@ -226,7 +234,10 @@ static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen,
		if (lkey) {
			*keymatch |= MATCH_CERT;
			if (cert) *cert = x509;
		} else if (ca) sk_push (*ca, (char *)x509);
		} else {
			if(ca) sk_X509_push (*ca, x509);
			else X509_free(x509);
		}
	break;

	case NID_safeContentsBag:
Loading