DH_free(s->s3->peer_dh_tmp);
#endif
#ifndef OPENSSL_NO_EC
- EC_KEY_free(s->s3->tmp.ecdh);
- EC_KEY_free(s->s3->peer_ecdh_tmp);
+ EVP_PKEY_free(s->s3->tmp.pkey);
+ s->s3->tmp.pkey = NULL;
+ EVP_PKEY_free(s->s3->peer_tmp);
+ s->s3->peer_tmp = NULL;
#endif
sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free);
s->s3->peer_dh_tmp = NULL;
#endif
#ifndef OPENSSL_NO_EC
- EC_KEY_free(s->s3->tmp.ecdh);
- s->s3->tmp.ecdh = NULL;
- EC_KEY_free(s->s3->peer_ecdh_tmp);
- s->s3->peer_ecdh_tmp = NULL;
+ EVP_PKEY_free(s->s3->tmp.pkey);
+ s->s3->tmp.pkey = NULL;
+ EVP_PKEY_free(s->s3->peer_tmp);
+ s->s3->peer_tmp = NULL;
s->s3->is_probably_safari = 0;
#endif /* !OPENSSL_NO_EC */
#ifndef OPENSSL_NO_SRP
static char *srp_password_from_info_cb(SSL *s, void *arg)
{
- return BUF_strdup(s->srp_ctx.info);
+ return OPENSSL_strdup(s->srp_ctx.info);
}
#endif
SSLerr(SSL_F_SSL3_CTRL, SSL_R_SSL3_EXT_INVALID_SERVERNAME);
return 0;
}
- if ((s->tlsext_hostname = BUF_strdup((char *)parg)) == NULL) {
+ if ((s->tlsext_hostname = OPENSSL_strdup((char *)parg)) == NULL) {
SSLerr(SSL_F_SSL3_CTRL, ERR_R_INTERNAL_ERROR);
return 0;
}
EVP_PKEY *ptmp;
int rv = 0;
#if !defined(OPENSSL_NO_DH) && !defined(OPENSSL_NO_EC)
- if (!s->s3->peer_dh_tmp && !s->s3->peer_ecdh_tmp)
+ if (s->s3->peer_dh_tmp == NULL && s->s3->peer_tmp == NULL)
return 0;
#endif
ptmp = EVP_PKEY_new();
if (ptmp == NULL)
return 0;
#ifndef OPENSSL_NO_DH
- else if (s->s3->peer_dh_tmp)
+ else if (s->s3->peer_dh_tmp != NULL)
rv = EVP_PKEY_set1_DH(ptmp, s->s3->peer_dh_tmp);
#endif
#ifndef OPENSSL_NO_EC
- else if (s->s3->peer_ecdh_tmp)
- rv = EVP_PKEY_set1_EC_KEY(ptmp, s->s3->peer_ecdh_tmp);
+ else if (s->s3->peer_tmp != NULL)
+ rv = EVP_PKEY_set1_EC_KEY(ptmp,
+ EVP_PKEY_get0_EC_KEY(s->s3->peer_tmp));
#endif
if (rv) {
*(EVP_PKEY **)parg = ptmp;
SSLerr(SSL_F_SSL3_CTX_CTRL, SSL_R_INVALID_SRP_USERNAME);
return 0;
}
- if ((ctx->srp_ctx.login = BUF_strdup((char *)parg)) == NULL) {
+ if ((ctx->srp_ctx.login = OPENSSL_strdup((char *)parg)) == NULL) {
SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_INTERNAL_ERROR);
return 0;
}
p[ret++] = SSL3_CT_DSS_SIGN;
#endif
#ifndef OPENSSL_NO_EC
- if ((alg_k & (SSL_kECDHr | SSL_kECDHe)) && (s->version >= TLS1_VERSION)) {
- if (nostrict || !(alg_a & SSL_aRSA))
- p[ret++] = TLS_CT_RSA_FIXED_ECDH;
- if (nostrict || !(alg_a & SSL_aECDSA))
- p[ret++] = TLS_CT_ECDSA_FIXED_ECDH;
- }
/*
- * ECDSA certs can be used with RSA cipher suites as well so we don't
+ * ECDSA certs can be used with RSA cipher suites too so we don't
* need to check for SSL_kECDH or SSL_kECDHE
*/
if (s->version >= TLS1_VERSION) {
s->s3->tmp.pms = NULL;
return s->session->master_key_length >= 0;
}
+
+/* Generate a private key from parameters or a curve NID */
+EVP_PKEY *ssl_generate_pkey(EVP_PKEY *pm, int nid)
+{
+ EVP_PKEY_CTX *pctx = NULL;
+ EVP_PKEY *pkey = NULL;
+ if (pm != NULL) {
+ pctx = EVP_PKEY_CTX_new(pm, NULL);
+ } else {
+ /*
+ * Generate a new key for this curve.
+ * Should not be called if EC is disabled: if it is it will
+ * fail with an unknown algorithm error.
+ */
+ pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL);
+ }
+ if (pctx == NULL)
+ goto err;
+ if (EVP_PKEY_keygen_init(pctx) <= 0)
+ goto err;
+#ifndef OPENSSL_NO_EC
+ if (pm == NULL && EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, nid) <= 0)
+ goto err;
+#endif
+
+ if (EVP_PKEY_keygen(pctx, &pkey) <= 0) {
+ EVP_PKEY_free(pkey);
+ pkey = NULL;
+ }
+
+ err:
+ EVP_PKEY_CTX_free(pctx);
+ return pkey;
+}
+/* Derive premaster or master secret for ECDH/DH */
+int ssl_derive(SSL *s, EVP_PKEY *privkey, EVP_PKEY *pubkey)
+{
+ int rv = 0;
+ unsigned char *pms = NULL;
+ size_t pmslen = 0;
+ EVP_PKEY_CTX *pctx;
+
+ if (privkey == NULL || pubkey == NULL)
+ return 0;
+
+ pctx = EVP_PKEY_CTX_new(privkey, NULL);
+
+ if (EVP_PKEY_derive_init(pctx) <= 0
+ || EVP_PKEY_derive_set_peer(pctx, pubkey) <= 0
+ || EVP_PKEY_derive(pctx, NULL, &pmslen) <= 0) {
+ goto err;
+ }
+
+ pms = OPENSSL_malloc(pmslen);
+ if (pms == NULL)
+ goto err;
+
+ if (EVP_PKEY_derive(pctx, pms, &pmslen) <= 0)
+ goto err;
+
+ if (s->server) {
+ /* For server generate master secret and discard premaster */
+ rv = ssl_generate_master_secret(s, pms, pmslen, 1);
+ pms = NULL;
+ } else {
+ /* For client just save premaster secret */
+ s->s3->tmp.pms = pms;
+ s->s3->tmp.pmslen = pmslen;
+ pms = NULL;
+ rv = 1;
+ }
+
+ err:
+ OPENSSL_clear_free(pms, pmslen);
+ EVP_PKEY_CTX_free(pctx);
+ return rv;
+}