summaryrefslogtreecommitdiff
path: root/crypto/dh
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2006-04-12 23:06:10 +0000
committerDr. Stephen Henson <steve@openssl.org>2006-04-12 23:06:10 +0000
commit4c97a04e2e799ecc1a0fffa4b6f6b012ec41071f (patch)
tree3e6d66265e3051f388195871e7f6fabc2794b242 /crypto/dh
parentfb05e1cdf6263a0a429ccb095902ae786a54f56d (diff)
downloadopenssl-new-4c97a04e2e799ecc1a0fffa4b6f6b012ec41071f.tar.gz
PKCS#3 DH PKCS#8 ASN1 support.
Diffstat (limited to 'crypto/dh')
-rw-r--r--crypto/dh/dh.h4
-rw-r--r--crypto/dh/dh_ameth.c115
-rw-r--r--crypto/dh/dh_err.c4
3 files changed, 121 insertions, 2 deletions
diff --git a/crypto/dh/dh.h b/crypto/dh/dh.h
index ef918b63cf..f81bad1811 100644
--- a/crypto/dh/dh.h
+++ b/crypto/dh/dh.h
@@ -216,14 +216,18 @@ void ERR_load_DH_strings(void);
#define DH_F_DH_BUILTIN_GENPARAMS 106
#define DH_F_DH_NEW_METHOD 105
#define DH_F_DH_PARAM_DECODE 107
+#define DH_F_DH_PRIV_DECODE 110
+#define DH_F_DH_PRIV_ENCODE 111
#define DH_F_DH_PUB_DECODE 108
#define DH_F_DH_PUB_ENCODE 109
+#define DH_F_DSA_PRIV_ENCODE 112
#define DH_F_GENERATE_KEY 103
#define DH_F_GENERATE_PARAMETERS 104
/* Reason codes. */
#define DH_R_BAD_GENERATOR 101
#define DH_R_BN_DECODE_ERROR 103
+#define DH_R_BN_ERROR 106
#define DH_R_DECODE_ERROR 104
#define DH_R_INVALID_PUBKEY 102
#define DH_R_NO_PRIVATE_VALUE 100
diff --git a/crypto/dh/dh_ameth.c b/crypto/dh/dh_ameth.c
index ba22f34d40..3a5600cf34 100644
--- a/crypto/dh/dh_ameth.c
+++ b/crypto/dh/dh_ameth.c
@@ -174,6 +174,117 @@ static int dh_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
return 0;
}
+
+/* PKCS#8 DH is defined in PKCS#11 of all places. It is similar to DH in
+ * that the AlgorithmIdentifier contains the paramaters, the private key
+ * is explcitly included and the pubkey must be recalculated.
+ */
+
+static int dh_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
+ {
+ const unsigned char *p, *pm;
+ int pklen, pmlen;
+ int ptype;
+ void *pval;
+ ASN1_STRING *pstr;
+ X509_ALGOR *palg;
+ ASN1_INTEGER *privkey = NULL;
+
+ DH *dh = NULL;
+
+ if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
+ return 0;
+
+ X509_ALGOR_get0(NULL, &ptype, &pval, palg);
+
+ if (ptype != V_ASN1_SEQUENCE)
+ goto decerr;
+
+ if (!(privkey=d2i_ASN1_INTEGER(NULL, &p, pklen)))
+ goto decerr;
+
+
+ pstr = pval;
+ pm = pstr->data;
+ pmlen = pstr->length;
+ if (!(dh = d2i_DHparams(NULL, &pm, pmlen)))
+ goto decerr;
+ /* We have parameters now set private key */
+ if (!(dh->priv_key = ASN1_INTEGER_to_BN(privkey, NULL)))
+ {
+ DHerr(DH_F_DH_PRIV_DECODE,DH_R_BN_ERROR);
+ goto dherr;
+ }
+ /* Calculate public key */
+ if (!DH_generate_key(dh))
+ goto dherr;
+
+ EVP_PKEY_assign_DH(pkey, dh);
+
+ ASN1_INTEGER_free(privkey);
+
+ return 1;
+
+ decerr:
+ DHerr(DH_F_DH_PRIV_DECODE, EVP_R_DECODE_ERROR);
+ dherr:
+ DH_free(dh);
+ return 0;
+ }
+
+static int dh_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
+{
+ ASN1_STRING *params = NULL;
+ ASN1_INTEGER *prkey = NULL;
+ unsigned char *dp = NULL;
+ int dplen;
+
+ params = ASN1_STRING_new();
+
+ if (!params)
+ {
+ DHerr(DH_F_DH_PRIV_ENCODE,ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ params->length = i2d_DHparams(pkey->pkey.dh, &params->data);
+ if (params->length <= 0)
+ {
+ DHerr(DH_F_DH_PRIV_ENCODE,ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ params->type = V_ASN1_SEQUENCE;
+
+ /* Get private key into integer */
+ prkey = BN_to_ASN1_INTEGER(pkey->pkey.dh->priv_key, NULL);
+
+ if (!prkey)
+ {
+ DHerr(DH_F_DSA_PRIV_ENCODE,DH_R_BN_ERROR);
+ goto err;
+ }
+
+ dplen = i2d_ASN1_INTEGER(prkey, &dp);
+
+ ASN1_INTEGER_free(prkey);
+
+ if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_dsa), 0,
+ V_ASN1_SEQUENCE, params, dp, dplen))
+ goto err;
+
+ return 1;
+
+err:
+ if (dp != NULL)
+ OPENSSL_free(dp);
+ if (params != NULL)
+ ASN1_STRING_free(params);
+ if (prkey != NULL)
+ ASN1_INTEGER_free(prkey);
+ return 0;
+}
+
+
static void update_buflen(const BIGNUM *b, size_t *pbuflen)
{
int i;
@@ -361,8 +472,8 @@ const EVP_PKEY_ASN1_METHOD dh_asn1_meth =
dh_pub_cmp,
dh_public_print,
- 0,
- 0,
+ dh_priv_decode,
+ dh_priv_encode,
dh_private_print,
int_dh_size,
diff --git a/crypto/dh/dh_err.c b/crypto/dh/dh_err.c
index 2a44f1cc11..8f2c8f8e47 100644
--- a/crypto/dh/dh_err.c
+++ b/crypto/dh/dh_err.c
@@ -76,8 +76,11 @@ static ERR_STRING_DATA DH_str_functs[]=
{ERR_FUNC(DH_F_DH_BUILTIN_GENPARAMS), "DH_BUILTIN_GENPARAMS"},
{ERR_FUNC(DH_F_DH_NEW_METHOD), "DH_new_method"},
{ERR_FUNC(DH_F_DH_PARAM_DECODE), "DH_PARAM_DECODE"},
+{ERR_FUNC(DH_F_DH_PRIV_DECODE), "DH_PRIV_DECODE"},
+{ERR_FUNC(DH_F_DH_PRIV_ENCODE), "DH_PRIV_ENCODE"},
{ERR_FUNC(DH_F_DH_PUB_DECODE), "DH_PUB_DECODE"},
{ERR_FUNC(DH_F_DH_PUB_ENCODE), "DH_PUB_ENCODE"},
+{ERR_FUNC(DH_F_DSA_PRIV_ENCODE), "DSA_PRIV_ENCODE"},
{ERR_FUNC(DH_F_GENERATE_KEY), "GENERATE_KEY"},
{ERR_FUNC(DH_F_GENERATE_PARAMETERS), "GENERATE_PARAMETERS"},
{0,NULL}
@@ -87,6 +90,7 @@ static ERR_STRING_DATA DH_str_reasons[]=
{
{ERR_REASON(DH_R_BAD_GENERATOR) ,"bad generator"},
{ERR_REASON(DH_R_BN_DECODE_ERROR) ,"bn decode error"},
+{ERR_REASON(DH_R_BN_ERROR) ,"bn error"},
{ERR_REASON(DH_R_DECODE_ERROR) ,"decode error"},
{ERR_REASON(DH_R_INVALID_PUBKEY) ,"invalid public key"},
{ERR_REASON(DH_R_NO_PRIVATE_VALUE) ,"no private value"},