Add ECDH/DH utility functions.
Reviewed-by: Richard Levitte <levitte@openssl.org>
This commit is contained in:
parent
44d4f8f2d7
commit
3f3504bdaf
2 changed files with 73 additions and 0 deletions
71
ssl/s3_lib.c
71
ssl/s3_lib.c
|
@ -4985,3 +4985,74 @@ int ssl_generate_master_secret(SSL *s, unsigned char *pms, size_t pmslen,
|
|||
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 */
|
||||
pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL);
|
||||
}
|
||||
if (pctx == NULL)
|
||||
goto err;
|
||||
if (EVP_PKEY_keygen_init(pctx) <= 0)
|
||||
goto err;
|
||||
if (pm == NULL && EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, nid) <= 0)
|
||||
goto err;
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -1870,6 +1870,8 @@ void ssl_load_ciphers(void);
|
|||
__owur int ssl_fill_hello_random(SSL *s, int server, unsigned char *field, int len);
|
||||
__owur int ssl_generate_master_secret(SSL *s, unsigned char *pms, size_t pmslen,
|
||||
int free_pms);
|
||||
__owur EVP_PKEY *ssl_generate_pkey(EVP_PKEY *pm, int nid);
|
||||
__owur int ssl_derive(SSL *s, EVP_PKEY *privkey, EVP_PKEY *pubkey);
|
||||
|
||||
__owur const SSL_CIPHER *ssl3_get_cipher_by_char(const unsigned char *p);
|
||||
__owur int ssl3_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p);
|
||||
|
|
Loading…
Reference in a new issue