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

Submitted by: "Victor B. Wagner" <vitus@cryptocom.ru>

Make {d2i,i2d}_PrivateKey() fall back to PKCS#8 format if no legacy format
supported. Add support in d2i_AutoPrivateKey().
parent f6707389
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1185,6 +1185,7 @@ void ERR_load_ASN1_strings(void);
#define ASN1_F_D2I_ASN1_TYPE_BYTES			 149
#define ASN1_F_D2I_ASN1_UINTEGER			 150
#define ASN1_F_D2I_ASN1_UTCTIME				 151
#define ASN1_F_D2I_AUTOPRIVATEKEY			 207
#define ASN1_F_D2I_NETSCAPE_RSA				 152
#define ASN1_F_D2I_NETSCAPE_RSA_2			 153
#define ASN1_F_D2I_PRIVATEKEY				 154
+2 −1
Original line number Diff line number Diff line
/* crypto/asn1/asn1_err.c */
/* ====================================================================
 * Copyright (c) 1999-2006 The OpenSSL Project.  All rights reserved.
 * Copyright (c) 1999-2007 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
@@ -147,6 +147,7 @@ static ERR_STRING_DATA ASN1_str_functs[]=
{ERR_FUNC(ASN1_F_D2I_ASN1_TYPE_BYTES),	"d2i_ASN1_type_bytes"},
{ERR_FUNC(ASN1_F_D2I_ASN1_UINTEGER),	"d2i_ASN1_UINTEGER"},
{ERR_FUNC(ASN1_F_D2I_ASN1_UTCTIME),	"D2I_ASN1_UTCTIME"},
{ERR_FUNC(ASN1_F_D2I_AUTOPRIVATEKEY),	"d2i_AutoPrivateKey"},
{ERR_FUNC(ASN1_F_D2I_NETSCAPE_RSA),	"d2i_Netscape_RSA"},
{ERR_FUNC(ASN1_F_D2I_NETSCAPE_RSA_2),	"D2I_NETSCAPE_RSA_2"},
{ERR_FUNC(ASN1_F_D2I_PRIVATEKEY),	"d2i_PrivateKey"},
+35 −3
Original line number Diff line number Diff line
@@ -64,6 +64,7 @@
#ifndef OPENSSL_NO_ENGINE
#include <openssl/engine.h>
#endif
#include <openssl/x509.h>
#include <openssl/asn1.h>
#include "asn1_locl.h"

@@ -101,9 +102,22 @@ EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp,
	if (!ret->ameth->old_priv_decode ||
			!ret->ameth->old_priv_decode(ret, pp, length))
		{
		if (ret->ameth->priv_decode) 
			{
			PKCS8_PRIV_KEY_INFO *p8=NULL;
			p8=d2i_PKCS8_PRIV_KEY_INFO(NULL,pp,length);
			if (!p8) goto err;
			EVP_PKEY_free(ret);
			ret = EVP_PKCS82PKEY(p8);
			PKCS8_PRIV_KEY_INFO_free(p8);

			} 
		else 
			{
			ASN1err(ASN1_F_D2I_PRIVATEKEY,ERR_R_ASN1_LIB);
			goto err;
			}
		}	
	if (a != NULL) (*a)=ret;
	return(ret);
err:
@@ -132,6 +146,24 @@ EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp,
		keytype = EVP_PKEY_DSA;
	else if (sk_ASN1_TYPE_num(inkey) == 4)
		keytype = EVP_PKEY_EC;
	else if (sk_ASN1_TYPE_num(inkey) == 3)  
		{ /* This seems to be PKCS8, not traditional format */
			PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL,pp,length);
			EVP_PKEY *ret;

			sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free);
			if (!p8) 
				{
				ASN1err(ASN1_F_D2I_AUTOPRIVATEKEY,ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
				return NULL;
				}
			ret = EVP_PKCS82PKEY(p8);
			PKCS8_PRIV_KEY_INFO_free(p8);
			if (a) {
				*a = ret;
			}	
			return ret;
		}
	else keytype = EVP_PKEY_RSA;
	sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free);
	return d2i_PrivateKey(keytype, a, pp, length);
+7 −0
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/evp.h>
#include <openssl/x509.h>
#include "asn1_locl.h"

int i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp)
@@ -67,6 +68,12 @@ int i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp)
		{
		return a->ameth->old_priv_encode(a, pp);
		}
	if (a->ameth && a->ameth->priv_encode) {
		PKCS8_PRIV_KEY_INFO *p8 = EVP_PKEY2PKCS8(a);
		int ret = i2d_PKCS8_PRIV_KEY_INFO(p8,pp);
		PKCS8_PRIV_KEY_INFO_free(p8);
		return ret;
	}	
	ASN1err(ASN1_F_I2D_PRIVATEKEY,ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
	return(-1);
	}