static DH *d2i_dhp(const EVP_PKEY *pkey, const unsigned char **pp, long length) { if (pkey->ameth == &dhx_asn1_meth) return d2i_DHxparams(NULL, pp, length); return d2i_DHparams(NULL, pp, length); }
DH *PEM_read_bio_DHparams(BIO *bp, DH **x, pem_password_cb *cb, void *u) { char *nm=NULL; const unsigned char *p=NULL; unsigned char *data=NULL; long len; DH *ret=NULL; if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_DHPARAMS, bp, cb, u)) return NULL; p = data; /* TODO(fork): remove? */ /*if (!strcmp(nm, PEM_STRING_DHXPARAMS)) ret = d2i_DHxparams(x, &p, len); else */ ret = d2i_DHparams(x, &p, len); if (ret == NULL) OPENSSL_PUT_ERROR(PEM, PEM_read_bio_DHparams, ERR_R_ASN1_LIB); OPENSSL_free(nm); OPENSSL_free(data); return ret; }
static int dh_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) { const unsigned char *p, *pm; int pklen, pmlen; int ptype; void *pval; 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) { DHerr(DH_F_DH_PUB_DECODE, DH_R_PARAMETER_ENCODING_ERROR); goto err; } pstr = pval; pm = pstr->data; pmlen = pstr->length; if (!(dh = d2i_DHparams(NULL, &pm, pmlen))) { DHerr(DH_F_DH_PUB_DECODE, DH_R_DECODE_ERROR); goto err; } if (!(public_key=d2i_ASN1_INTEGER(NULL, &p, pklen))) { DHerr(DH_F_DH_PUB_DECODE, DH_R_DECODE_ERROR); goto err; } /* We have parameters now set public key */ if (!(dh->pub_key = ASN1_INTEGER_to_BN(public_key, NULL))) { DHerr(DH_F_DH_PUB_DECODE, 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); if (dh) 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; 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; }
// Construct from raw DH params // explicit ScopedDHPointer (std::string const& params) { auto const* p ( reinterpret_cast <std::uint8_t const*>(¶ms [0])); m_dh = d2i_DHparams (nullptr, &p, params.size ()); if (m_dh == nullptr) beast::FatalError ("d2i_DHparams returned nullptr.", __FILE__, __LINE__); }
static int dh_param_decode(EVP_PKEY *pkey, const unsigned char **pder, int derlen) { DH *dh; if (!(dh = d2i_DHparams(NULL, pder, derlen))) { DHerr(DH_F_DH_PARAM_DECODE, ERR_R_DH_LIB); return 0; } EVP_PKEY_assign_DH(pkey, dh); return 1; }
static DH *tls_get_dh(const unsigned char *p, size_t plen) { const unsigned char *endp = p; DH *dh = 0; if (d2i_DHparams(&dh, &endp, plen) && plen == endp - p) return (dh); msg_warn("cannot load compiled-in DH parameters"); if (dh) DH_free(dh); return (0); }
int s2n_pkcs3_to_dh_params(struct s2n_dh_params *dh_params, struct s2n_blob *pkcs3) { uint8_t *original_ptr = pkcs3->data; dh_params->dh = d2i_DHparams(NULL, (const unsigned char **)(void *)&pkcs3->data, pkcs3->size); GUARD(s2n_check_p_g_dh_params(dh_params)); if (pkcs3->data - original_ptr != pkcs3->size) { DH_free(dh_params->dh); S2N_ERROR(S2N_ERR_INVALID_PKCS3); } pkcs3->data = original_ptr; /* Require at least 2048 bits for the DH size */ if (DH_size(dh_params->dh) < S2N_MIN_DH_PRIME_SIZE_BYTES) { DH_free(dh_params->dh); S2N_ERROR(S2N_ERR_DH_TOO_SMALL); } /* Check the generator and prime */ GUARD(s2n_dh_params_check(dh_params)); return 0; }
DH *PEM_read_bio_DHparams(BIO *bp, DH **x, pem_password_cb *cb, void *u) { char *nm = NULL; const unsigned char *p = NULL; unsigned char *data = NULL; long len; DH *ret = NULL; if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_DHPARAMS, bp, cb, u)) return NULL; p = data; if (strcmp(nm, PEM_STRING_DHXPARAMS) == 0) ret = d2i_DHxparams(x, &p, len); else ret = d2i_DHparams(x, &p, len); if (ret == NULL) PEMerr(PEM_F_PEM_READ_BIO_DHPARAMS, ERR_R_ASN1_LIB); OPENSSL_free(nm); OPENSSL_free(data); return ret; }
static int read_dh_parameters_next(struct ssl_iostream_context *ctx, const unsigned char **data, const unsigned char *end) { const unsigned char *dbuf; DH *dh; int bits, len, ret = 1; /* get bit size. 0 ends the DH parameters list. */ if ((bits = read_int(data, end)) <= 0) return bits; /* get data size */ if ((len = read_int(data, end)) <= 0 || end - *data < len) return -1; dbuf = *data; dh = d2i_DHparams(NULL, &dbuf, len); *data += len; if (dh == NULL) return -1; switch (bits) { case 512: ctx->dh_512 = dh; break; case 1024: ctx->dh_1024 = dh; break; default: ret = -1; break; } return ret; }
int get_USM_DH_key(netsnmp_variable_list *vars, netsnmp_variable_list *dhvar, size_t outkey_len, netsnmp_pdu *pdu, const char *keyname, oid *keyoid, size_t keyoid_len) { u_char *dhkeychange; DH *dh; const BIGNUM *p, *g, *pub_key; BIGNUM *other_pub; u_char *key; size_t key_len; dhkeychange = (u_char *) malloc(2 * vars->val_len * sizeof(char)); if (!dhkeychange) return SNMPERR_GENERR; memcpy(dhkeychange, vars->val.string, vars->val_len); { const unsigned char *cp = dhvar->val.string; dh = d2i_DHparams(NULL, &cp, dhvar->val_len); } if (dh) DH_get0_pqg(dh, &p, NULL, &g); if (!dh || !g || !p) { SNMP_FREE(dhkeychange); return SNMPERR_GENERR; } if (!DH_generate_key(dh)) { SNMP_FREE(dhkeychange); return SNMPERR_GENERR; } DH_get0_key(dh, &pub_key, NULL); if (vars->val_len != (unsigned int)BN_num_bytes(pub_key)) { SNMP_FREE(dhkeychange); fprintf(stderr,"incorrect diffie-helman lengths (%lu != %d)\n", (unsigned long)vars->val_len, BN_num_bytes(pub_key)); return SNMPERR_GENERR; } BN_bn2bin(pub_key, dhkeychange + vars->val_len); key_len = DH_size(dh); if (!key_len) { SNMP_FREE(dhkeychange); return SNMPERR_GENERR; } key = (u_char *) malloc(key_len * sizeof(u_char)); if (!key) { SNMP_FREE(dhkeychange); return SNMPERR_GENERR; } other_pub = BN_bin2bn(vars->val.string, vars->val_len, NULL); if (!other_pub) { SNMP_FREE(dhkeychange); SNMP_FREE(key); return SNMPERR_GENERR; } if (DH_compute_key(key, other_pub, dh)) { u_char *kp; printf("new %s key: 0x", keyname); for(kp = key + key_len - outkey_len; kp - key < (int)key_len; kp++) { printf("%02x", (unsigned char) *kp); } printf("\n"); } snmp_pdu_add_variable(pdu, keyoid, keyoid_len, ASN_OCTET_STR, dhkeychange, 2 * vars->val_len); SNMP_FREE(dhkeychange); SNMP_FREE(other_pub); SNMP_FREE(key); return SNMPERR_SUCCESS; }
int handle_usmDHParameters (netsnmp_mib_handler * handler, netsnmp_handler_registration * reginfo, netsnmp_agent_request_info * reqinfo, netsnmp_request_info * requests) { /* * We are never called for a GETNEXT if it's registered as a * "instance", as it's "magically" handled for us. */ static unsigned char *cp = NULL; static DH *dh_tmpp = NULL; int cp_len; /* * a instance handler also only hands us one request at a time, so * we don't need to loop over a list of requests; we'll only get one. */ switch (reqinfo->mode) { case MODE_GET: if (cp) { free (cp); cp = NULL; } cp_len = i2d_DHparams (dh_params, &cp); if (cp_len > 0) snmp_set_var_typed_value (requests->requestvb, ASN_OCTET_STR, (u_char *) cp, cp_len); break; /* * SET REQUEST * * multiple states in the transaction. See: * http://www.net-snmp.org/tutorial-5/toolkit/mib_module/set-actions.jpg */ case MODE_SET_RESERVE1: break; case MODE_SET_RESERVE2: cp = requests->requestvb->val.string; dh_tmpp = d2i_DHparams (NULL, (const unsigned char **) (void *) &cp, requests->requestvb->val_len); if (!dh_tmpp) { netsnmp_set_request_error (reqinfo, requests, SNMP_ERR_WRONGVALUE); } if (cp - requests->requestvb->val.string != requests->requestvb->val_len) { /* value too long; we didn't parse the whole thing */ netsnmp_set_request_error (reqinfo, requests, SNMP_ERR_WRONGVALUE); DH_free (dh_tmpp); dh_tmpp = NULL; } break; case MODE_SET_FREE: case MODE_SET_COMMIT: DH_free (dh_tmpp); dh_tmpp = NULL; break; case MODE_SET_ACTION: { DH *tmpp; tmpp = dh_params; dh_params = dh_tmpp; dh_tmpp = tmpp; break; } case MODE_SET_UNDO: { DH_free (dh_params); /* free new value */ dh_params = dh_tmpp; /* restore old value */ dh_tmpp = NULL; break; } default: /* * we should never get here, so this is a really bad error */ return SNMP_ERR_GENERR; } return SNMP_ERR_NOERROR; }