static int dh_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) { const unsigned char *p, *pm; int pklen, pmlen; int ptype; const void *pval; const ASN1_STRING *pstr; X509_ALGOR *palg; ASN1_INTEGER *public_key = NULL; DH *dh = NULL; if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) return 0; X509_ALGOR_get0(NULL, &ptype, &pval, palg); if (ptype != V_ASN1_SEQUENCE) { DHerror(DH_R_PARAMETER_ENCODING_ERROR); goto err; } pstr = pval; pm = pstr->data; pmlen = pstr->length; if (!(dh = d2i_DHparams(NULL, &pm, pmlen))) { DHerror(DH_R_DECODE_ERROR); goto err; } if (!(public_key=d2i_ASN1_INTEGER(NULL, &p, pklen))) { DHerror(DH_R_DECODE_ERROR); goto err; } /* We have parameters now set public key */ if (!(dh->pub_key = ASN1_INTEGER_to_BN(public_key, NULL))) { DHerror(DH_R_BN_DECODE_ERROR); goto err; } ASN1_INTEGER_free(public_key); EVP_PKEY_assign_DH(pkey, dh); return 1; err: if (public_key) ASN1_INTEGER_free(public_key); DH_free(dh); return 0; }
static int dh_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) { const unsigned char *p, *pm; int pklen, pmlen; int ptype; const void *pval; const 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))) { DHerror(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: DHerror(EVP_R_DECODE_ERROR); dherr: DH_free(dh); return 0; }
static int dh_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) { DH *dh; int ptype; unsigned char *penc = NULL; int penclen; ASN1_STRING *str; ASN1_INTEGER *pub_key = NULL; dh=pkey->pkey.dh; str = ASN1_STRING_new(); if (str == NULL) { DHerror(ERR_R_MALLOC_FAILURE); goto err; } str->length = i2d_DHparams(dh, &str->data); if (str->length <= 0) { DHerror(ERR_R_MALLOC_FAILURE); goto err; } ptype = V_ASN1_SEQUENCE; pub_key = BN_to_ASN1_INTEGER(dh->pub_key, NULL); if (!pub_key) goto err; penclen = i2d_ASN1_INTEGER(pub_key, &penc); ASN1_INTEGER_free(pub_key); if (penclen <= 0) { DHerror(ERR_R_MALLOC_FAILURE); goto err; } if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_DH), ptype, (void *)str, penc, penclen)) return 1; err: free(penc); ASN1_STRING_free(str); 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) { DHerror(ERR_R_MALLOC_FAILURE); goto err; } params->length = i2d_DHparams(pkey->pkey.dh, ¶ms->data); if (params->length <= 0) { DHerror(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) { DHerror(DH_R_BN_ERROR); goto err; } dplen = i2d_ASN1_INTEGER(prkey, &dp); ASN1_INTEGER_free(prkey); prkey = NULL; if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_dhKeyAgreement), 0, V_ASN1_SEQUENCE, params, dp, dplen)) goto err; return 1; err: free(dp); ASN1_STRING_free(params); ASN1_INTEGER_free(prkey); return 0; }
static int dh_param_decode(EVP_PKEY *pkey, const unsigned char **pder, int derlen) { DH *dh; if (!(dh = d2i_DHparams(NULL, pder, derlen))) { DHerror(ERR_R_DH_LIB); return 0; } EVP_PKEY_assign_DH(pkey, dh); return 1; }
int DHparams_print_fp(FILE *fp, const DH *x) { BIO *b; int ret; if ((b = BIO_new(BIO_s_file())) == NULL) { DHerror(ERR_R_BUF_LIB); return 0; } BIO_set_fp(b,fp,BIO_NOCLOSE); ret = DHparams_print(b, x); BIO_free(b); return ret; }
static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen) { int ret; if (!ctx->pkey || !ctx->peerkey) { DHerror(DH_R_KEYS_NOT_SET); return 0; } ret = DH_compute_key(key, ctx->peerkey->pkey.dh->pub_key, ctx->pkey->pkey.dh); if (ret < 0) return ret; *keylen = ret; return 1; }
static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { DH *dh = NULL; if (ctx->pkey == NULL) { DHerror(DH_R_NO_PARAMETERS_SET); return 0; } dh = DH_new(); if (!dh) return 0; EVP_PKEY_assign_DH(pkey, dh); /* Note: if error return, pkey is freed by parent routine */ if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey)) return 0; return DH_generate_key(pkey->pkey.dh); }
static int do_dh_print(BIO *bp, const DH *x, int indent, ASN1_PCTX *ctx, int ptype) { unsigned char *m = NULL; int reason = ERR_R_BUF_LIB, ret = 0; size_t buf_len = 0; const char *ktype = NULL; BIGNUM *priv_key, *pub_key; if (ptype == 2) priv_key = x->priv_key; else priv_key = NULL; if (ptype > 0) pub_key = x->pub_key; else pub_key = NULL; update_buflen(x->p, &buf_len); if (buf_len == 0) { reason = ERR_R_PASSED_NULL_PARAMETER; goto err; } update_buflen(x->g, &buf_len); update_buflen(pub_key, &buf_len); update_buflen(priv_key, &buf_len); if (ptype == 2) ktype = "PKCS#3 DH Private-Key"; else if (ptype == 1) ktype = "PKCS#3 DH Public-Key"; else ktype = "PKCS#3 DH Parameters"; m= malloc(buf_len + 10); if (m == NULL) { reason = ERR_R_MALLOC_FAILURE; goto err; } BIO_indent(bp, indent, 128); if (BIO_printf(bp, "%s: (%d bit)\n", ktype, BN_num_bits(x->p)) <= 0) goto err; indent += 4; if (!ASN1_bn_print(bp, "private-key:", priv_key, m, indent)) goto err; if (!ASN1_bn_print(bp, "public-key:", pub_key, m, indent)) goto err; if (!ASN1_bn_print(bp, "prime:", x->p, m, indent)) goto err; if (!ASN1_bn_print(bp, "generator:", x->g, m, indent)) goto err; if (x->length != 0) { BIO_indent(bp, indent, 128); if (BIO_printf(bp, "recommended-private-length: %d bits\n", (int)x->length) <= 0) goto err; } ret = 1; if (0) { err: DHerror(reason); } free(m); return(ret); }