From 08c24fdd6abd7a4c82cb96d2b3e6778a0ffceb07 Mon Sep 17 00:00:00 2001 From: tobhe Date: Thu, 4 Feb 2021 19:59:15 +0000 Subject: [PATCH] Upgrade to OpenSSL 1.1 compatible crypto API. Add additional checks where needed. ok markus@ patrick@ --- sbin/iked/ca.c | 146 +++++++++++++++++++++++++++++--------------- sbin/iked/chap_ms.c | 117 +++++++++++++++++++++-------------- sbin/iked/crypto.c | 56 ++++++++--------- sbin/iked/dh.c | 28 ++++++--- sbin/iked/ikev2.c | 28 +++++---- 5 files changed, 231 insertions(+), 144 deletions(-) diff --git a/sbin/iked/ca.c b/sbin/iked/ca.c index cbf75c7d5d2..38c0e70ed19 100644 --- a/sbin/iked/ca.c +++ b/sbin/iked/ca.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ca.c,v 1.75 2020/12/05 19:10:47 tobhe Exp $ */ +/* $OpenBSD: ca.c,v 1.76 2021/02/04 19:59:15 tobhe Exp $ */ /* * Copyright (c) 2010-2013 Reyk Floeter @@ -511,6 +511,8 @@ ca_getreq(struct iked *env, struct imsg *imsg) struct ibuf *buf; struct iked_static_id id; char idstr[IKED_ID_SIZE]; + X509_NAME *subj; + char *subj_name; ptr = (uint8_t *)imsg->data; len = IMSG_DATA_SIZE(imsg); @@ -558,11 +560,16 @@ ca_getreq(struct iked *env, struct imsg *imsg) if ((ca = ca_by_subjectpubkey(store->ca_cas, ptr + i, SHA_DIGEST_LENGTH)) == NULL) continue; - - log_debug("%s: found CA %s", __func__, ca->name); + subj = X509_get_subject_name(ca); + if (subj == NULL) + return (-1); + subj_name = X509_NAME_oneline(subj, NULL, 0); + if (subj_name == NULL) + return (-1); + log_debug("%s: found CA %s", __func__, subj_name); if ((cert = ca_by_issuer(store->ca_certs, - X509_get_subject_name(ca), &id)) != NULL) { + subj, &id)) != NULL) { /* XXX * should we re-validate our own cert here? */ @@ -605,8 +612,14 @@ ca_getreq(struct iked *env, struct imsg *imsg) break; } + subj = X509_get_subject_name(cert); + if (subj == NULL) + return (-1); + subj_name = X509_NAME_oneline(subj, NULL, 0); + if (subj_name == NULL) + return (-1); log_debug("%s: found local certificate %s", __func__, - cert->name); + subj_name); if ((buf = ca_x509_serialize(cert)) == NULL) return (-1); @@ -699,6 +712,8 @@ ca_reload(struct iked *env) DIR *dir; int i, iovcnt = 0; unsigned int len; + X509_NAME *subj; + char *subj_name; /* * Load CAs @@ -763,16 +778,22 @@ ca_reload(struct iked *env) if ((env->sc_certreq = ibuf_new(NULL, 0)) == NULL) return (-1); - h = store->ca_cas->objs; + h = X509_STORE_get0_objects(store->ca_cas); for (i = 0; i < sk_X509_OBJECT_num(h); i++) { xo = sk_X509_OBJECT_value(h, i); - if (xo->type != X509_LU_X509) + if (X509_OBJECT_get_type(xo) != X509_LU_X509) continue; - x509 = xo->data.x509; + x509 = X509_OBJECT_get0_X509(xo); len = sizeof(md); ca_subjectpubkey_digest(x509, md, &len); - log_debug("%s: %s", __func__, x509->name); + subj = X509_get_subject_name(x509); + if (subj == NULL) + return (-1); + subj_name = X509_NAME_oneline(subj, NULL, 0); + if (subj_name == NULL) + return (-1); + log_debug("%s: %s", __func__, subj_name); if (ibuf_add(env->sc_certreq, md, len) != 0) { ibuf_release(env->sc_certreq); @@ -825,13 +846,13 @@ ca_reload(struct iked *env) } closedir(dir); - h = store->ca_certs->objs; + h = X509_STORE_get0_objects(store->ca_certs); for (i = 0; i < sk_X509_OBJECT_num(h); i++) { xo = sk_X509_OBJECT_value(h, i); - if (xo->type != X509_LU_X509) + if (X509_OBJECT_get_type(xo) != X509_LU_X509) continue; - x509 = xo->data.x509; + x509 = X509_OBJECT_get0_X509(xo); (void)ca_validate_cert(env, NULL, x509, 0, NULL); } @@ -861,14 +882,14 @@ ca_by_subjectpubkey(X509_STORE *ctx, uint8_t *sig, size_t siglen) unsigned int len; uint8_t md[EVP_MAX_MD_SIZE]; - h = ctx->objs; + h = X509_STORE_get0_objects(ctx); for (i = 0; i < sk_X509_OBJECT_num(h); i++) { xo = sk_X509_OBJECT_value(h, i); - if (xo->type != X509_LU_X509) + if (X509_OBJECT_get_type(xo) != X509_LU_X509) continue; - ca = xo->data.x509; + ca = X509_OBJECT_get0_X509(xo); len = sizeof(md); ca_subjectpubkey_digest(ca, md, &len); @@ -891,13 +912,13 @@ ca_by_issuer(X509_STORE *ctx, X509_NAME *subject, struct iked_static_id *id) if (subject == NULL) return (NULL); - h = ctx->objs; + h = X509_STORE_get0_objects(ctx); for (i = 0; i < sk_X509_OBJECT_num(h); i++) { xo = sk_X509_OBJECT_value(h, i); - if (xo->type != X509_LU_X509) + if (X509_OBJECT_get_type(xo) != X509_LU_X509) continue; - cert = xo->data.x509; + cert = X509_OBJECT_get0_X509(xo); if ((issuer = X509_get_issuer_name(cert)) == NULL) continue; else if (X509_NAME_cmp(subject, issuer) == 0) { @@ -925,13 +946,13 @@ ca_by_subjectaltname(X509_STORE *ctx, struct iked_static_id *id) X509 *cert; int i; - h = ctx->objs; + h = X509_STORE_get0_objects(ctx); for (i = 0; i < sk_X509_OBJECT_num(h); i++) { xo = sk_X509_OBJECT_value(h, i); - if (xo->type != X509_LU_X509) + if (X509_OBJECT_get_type(xo) != X509_LU_X509) continue; - cert = xo->data.x509; + cert = X509_OBJECT_get0_X509(xo); switch (id->id_type) { case IKEV2_ID_ASN1_DN: if (ca_x509_subject_cmp(cert, id) == 0) @@ -955,12 +976,12 @@ ca_store_certs_info(const char *msg, X509_STORE *ctx) X509 *cert; int i; - h = ctx->objs; + h = X509_STORE_get0_objects(ctx); for (i = 0; i < sk_X509_OBJECT_num(h); i++) { xo = sk_X509_OBJECT_value(h, i); - if (xo->type != X509_LU_X509) + if (X509_OBJECT_get_type(xo) != X509_LU_X509) continue; - cert = xo->data.x509; + cert = X509_OBJECT_get0_X509(xo); ca_cert_info(msg, cert); } } @@ -972,18 +993,24 @@ ca_cert_info(const char *msg, X509 *cert) BUF_MEM *memptr; BIO *rawserial = NULL; char buf[BUFSIZ]; + X509_NAME *name; if ((asn1_serial = X509_get_serialNumber(cert)) == NULL || (rawserial = BIO_new(BIO_s_mem())) == NULL || i2a_ASN1_INTEGER(rawserial, asn1_serial) <= 0) goto out; - if (X509_NAME_oneline(X509_get_issuer_name(cert), buf, sizeof(buf))) + + name = X509_get_issuer_name(cert); + if (name != NULL && + X509_NAME_oneline(name, buf, sizeof(buf))) log_info("%s: issuer: %s", msg, buf); BIO_get_mem_ptr(rawserial, &memptr); if (memptr->data != NULL && memptr->length < INT32_MAX) log_info("%s: serial: %.*s", msg, (int)memptr->length, memptr->data); - if (X509_NAME_oneline(X509_get_subject_name(cert), buf, sizeof(buf))) + name = X509_get_subject_name(cert); + if (name != NULL && + X509_NAME_oneline(name, buf, sizeof(buf))) log_info("%s: subject: %s", msg, buf); ca_x509_subjectaltname_log(cert, msg); out: @@ -1053,7 +1080,7 @@ ca_pubkey_serialize(EVP_PKEY *key, struct iked_id *id) int len = 0; int ret = -1; - switch (key->type) { + switch (EVP_PKEY_id(key)) { case EVP_PKEY_RSA: id->id_type = 0; id->id_offset = 0; @@ -1099,7 +1126,8 @@ ca_pubkey_serialize(EVP_PKEY *key, struct iked_id *id) id->id_type = IKEV2_CERT_ECDSA; break; default: - log_debug("%s: unsupported key type %d", __func__, key->type); + log_debug("%s: unsupported key type %d", __func__, + EVP_PKEY_id(key)); return (-1); } @@ -1124,7 +1152,7 @@ ca_privkey_serialize(EVP_PKEY *key, struct iked_id *id) int len = 0; int ret = -1; - switch (key->type) { + switch (EVP_PKEY_id(key)) { case EVP_PKEY_RSA: id->id_type = 0; id->id_offset = 0; @@ -1170,7 +1198,8 @@ ca_privkey_serialize(EVP_PKEY *key, struct iked_id *id) id->id_type = IKEV2_CERT_ECDSA; break; default: - log_debug("%s: unsupported key type %d", __func__, key->type); + log_debug("%s: unsupported key type %d", __func__, + EVP_PKEY_id(key)); return (-1); } @@ -1472,13 +1501,16 @@ int ca_validate_cert(struct iked *env, struct iked_static_id *id, void *data, size_t len, X509 **issuerp) { - struct ca_store *store = env->sc_priv; - X509_STORE_CTX csc; - BIO *rawcert = NULL; - X509 *cert = NULL; - EVP_PKEY *pkey; - int ret = -1, result, error; - const char *errstr = "failed"; + struct ca_store *store = env->sc_priv; + X509_STORE_CTX *csc = NULL; + X509_VERIFY_PARAM *param; + BIO *rawcert = NULL; + X509 *cert = NULL; + EVP_PKEY *pkey; + int ret = -1, result, error; + const char *errstr = "failed"; + X509_NAME *subj; + char *subj_name; if (issuerp) *issuerp = NULL; @@ -1527,24 +1559,29 @@ ca_validate_cert(struct iked *env, struct iked_static_id *id, } } - bzero(&csc, sizeof(csc)); - X509_STORE_CTX_init(&csc, store->ca_cas, cert, NULL); - if (store->ca_cas->param->flags & X509_V_FLAG_CRL_CHECK) { - X509_STORE_CTX_set_flags(&csc, X509_V_FLAG_CRL_CHECK); - X509_STORE_CTX_set_flags(&csc, X509_V_FLAG_CRL_CHECK_ALL); + csc = X509_STORE_CTX_new(); + if (csc == NULL) { + errstr = "failed to alloc csc"; + goto done; + } + X509_STORE_CTX_init(csc, store->ca_cas, cert, NULL); + param = X509_STORE_get0_param(store->ca_cas); + if (X509_VERIFY_PARAM_get_flags(param) & X509_V_FLAG_CRL_CHECK) { + X509_STORE_CTX_set_flags(csc, X509_V_FLAG_CRL_CHECK); + X509_STORE_CTX_set_flags(csc, X509_V_FLAG_CRL_CHECK_ALL); } if (env->sc_cert_partial_chain) - X509_STORE_CTX_set_flags(&csc, X509_V_FLAG_PARTIAL_CHAIN); + X509_STORE_CTX_set_flags(csc, X509_V_FLAG_PARTIAL_CHAIN); - result = X509_verify_cert(&csc); - error = csc.error; + result = X509_verify_cert(csc); + error = X509_STORE_CTX_get_error(csc); if (error == 0 && issuerp) { - if (X509_STORE_CTX_get1_issuer(issuerp, &csc, cert) != 1) { + if (X509_STORE_CTX_get1_issuer(issuerp, csc, cert) != 1) { log_debug("%s: cannot get issuer", __func__); *issuerp = NULL; } } - X509_STORE_CTX_cleanup(&csc); + X509_STORE_CTX_cleanup(csc); if (error != 0) { errstr = X509_verify_cert_error_string(error); goto done; @@ -1561,8 +1598,16 @@ ca_validate_cert(struct iked *env, struct iked_static_id *id, errstr = "ok"; done: - if (cert != NULL) - log_debug("%s: %s %.100s", __func__, cert->name, errstr); + if (cert != NULL) { + subj = X509_get_subject_name(cert); + if (subj == NULL) + goto err; + subj_name = X509_NAME_oneline(subj, NULL, 0); + if (subj_name == NULL) + goto err; + log_debug("%s: %s %.100s", __func__, subj_name, errstr); + } + err: if (rawcert != NULL) { BIO_free(rawcert); @@ -1570,6 +1615,9 @@ ca_validate_cert(struct iked *env, struct iked_static_id *id, X509_free(cert); } + if (csc != NULL) + X509_STORE_CTX_free(csc); + return (ret); } diff --git a/sbin/iked/chap_ms.c b/sbin/iked/chap_ms.c index 1e03f1de01d..b87d0bdb088 100644 --- a/sbin/iked/chap_ms.c +++ b/sbin/iked/chap_ms.c @@ -1,4 +1,4 @@ -/* $OpenBSD: chap_ms.c,v 1.9 2015/08/21 11:59:27 reyk Exp $ */ +/* $OpenBSD: chap_ms.c,v 1.10 2021/02/04 19:59:15 tobhe Exp $ */ /* * Copyright (c) 2010-2013 Reyk Floeter @@ -44,6 +44,9 @@ #include "chap_ms.h" +extern __dead void fatalx(const char *, ...) + __attribute__((__format__ (printf, 1, 2))); + /* * Documentation & specifications: * @@ -134,19 +137,23 @@ mschap_challenge_response(uint8_t *challenge, uint8_t *pwhash, void mschap_ntpassword_hash(uint8_t *in, int inlen, uint8_t *hash) { - EVP_MD_CTX ctx; + EVP_MD_CTX *ctx; unsigned int mdlen; - EVP_DigestInit(&ctx, EVP_md4()); - EVP_DigestUpdate(&ctx, in, inlen); - EVP_DigestFinal(&ctx, hash, &mdlen); + ctx = EVP_MD_CTX_new(); + if (ctx == NULL) + fatalx("%s: EVP_MD_CTX_NEW()", __func__); + EVP_DigestInit(ctx, EVP_md4()); + EVP_DigestUpdate(ctx, in, inlen); + EVP_DigestFinal(ctx, hash, &mdlen); + EVP_MD_CTX_free(ctx); } void mschap_challenge_hash(uint8_t *peer_challenge, uint8_t *auth_challenge, uint8_t *username, int usernamelen, uint8_t *challenge) { - EVP_MD_CTX ctx; + EVP_MD_CTX *ctx; uint8_t md[SHA_DIGEST_LENGTH]; unsigned int mdlen; uint8_t *name; @@ -156,11 +163,15 @@ mschap_challenge_hash(uint8_t *peer_challenge, uint8_t *auth_challenge, else name++; - EVP_DigestInit(&ctx, EVP_sha1()); - EVP_DigestUpdate(&ctx, peer_challenge, MSCHAPV2_CHALLENGE_SZ); - EVP_DigestUpdate(&ctx, auth_challenge, MSCHAPV2_CHALLENGE_SZ); - EVP_DigestUpdate(&ctx, name, strlen(name)); - EVP_DigestFinal(&ctx, md, &mdlen); + ctx = EVP_MD_CTX_new(); + if (ctx == NULL) + fatalx("%s: EVP_MD_CTX_NEW()", __func__); + EVP_DigestInit(ctx, EVP_sha1()); + EVP_DigestUpdate(ctx, peer_challenge, MSCHAPV2_CHALLENGE_SZ); + EVP_DigestUpdate(ctx, auth_challenge, MSCHAPV2_CHALLENGE_SZ); + EVP_DigestUpdate(ctx, name, strlen(name)); + EVP_DigestFinal(ctx, md, &mdlen); + EVP_MD_CTX_free(ctx); memcpy(challenge, md, MSCHAP_CHALLENGE_SZ); } @@ -185,7 +196,7 @@ mschap_auth_response(uint8_t *password, int passwordlen, uint8_t *ntresponse, uint8_t *auth_challenge, uint8_t *peer_challenge, uint8_t *username, int usernamelen, uint8_t *auth_response) { - EVP_MD_CTX ctx; + EVP_MD_CTX *ctx; uint8_t password_hash[MSCHAP_HASH_SZ]; uint8_t password_hash2[MSCHAP_HASH_SZ]; uint8_t challenge[MSCHAP_CHALLENGE_SZ]; @@ -207,23 +218,27 @@ mschap_auth_response(uint8_t *password, int passwordlen, 0x6E }; + ctx = EVP_MD_CTX_new(); + if (ctx == NULL) + fatalx("%s: EVP_MD_CTX_NEW()", __func__); mschap_ntpassword_hash(password, passwordlen, password_hash); mschap_ntpassword_hash(password_hash, MSCHAP_HASH_SZ, password_hash2); - EVP_DigestInit(&ctx, EVP_sha1()); - EVP_DigestUpdate(&ctx, password_hash2, sizeof(password_hash2)); - EVP_DigestUpdate(&ctx, ntresponse, 24); - EVP_DigestUpdate(&ctx, magic1, 39); - EVP_DigestFinal(&ctx, md, &mdlen); + EVP_DigestInit(ctx, EVP_sha1()); + EVP_DigestUpdate(ctx, password_hash2, sizeof(password_hash2)); + EVP_DigestUpdate(ctx, ntresponse, 24); + EVP_DigestUpdate(ctx, magic1, 39); + EVP_DigestFinal(ctx, md, &mdlen); mschap_challenge_hash(peer_challenge, auth_challenge, username, usernamelen, challenge); - EVP_DigestInit(&ctx, EVP_sha1()); - EVP_DigestUpdate(&ctx, md, sizeof(md)); - EVP_DigestUpdate(&ctx, challenge, sizeof(challenge)); - EVP_DigestUpdate(&ctx, magic2, 41); - EVP_DigestFinal(&ctx, md, &mdlen); + EVP_DigestInit(ctx, EVP_sha1()); + EVP_DigestUpdate(ctx, md, sizeof(md)); + EVP_DigestUpdate(ctx, challenge, sizeof(challenge)); + EVP_DigestUpdate(ctx, magic2, 41); + EVP_DigestFinal(ctx, md, &mdlen); + EVP_MD_CTX_free(ctx); /* * Encode the value of 'Digest' as "S=" followed by @@ -247,18 +262,22 @@ mschap_masterkey(uint8_t *password_hash2, uint8_t *ntresponse, { uint8_t md[SHA_DIGEST_LENGTH]; unsigned int mdlen; - EVP_MD_CTX ctx; + EVP_MD_CTX *ctx; static uint8_t magic1[27] = { 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x4d, 0x50, 0x50, 0x45, 0x20, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x4b, 0x65, 0x79 }; - EVP_DigestInit(&ctx, EVP_sha1()); - EVP_DigestUpdate(&ctx, password_hash2, MSCHAP_HASH_SZ); - EVP_DigestUpdate(&ctx, ntresponse, 24); - EVP_DigestUpdate(&ctx, magic1, 27); - EVP_DigestFinal(&ctx, md, &mdlen); + ctx = EVP_MD_CTX_new(); + if (ctx == NULL) + fatalx("%s: EVP_MD_CTX_NEW()", __func__); + EVP_DigestInit(ctx, EVP_sha1()); + EVP_DigestUpdate(ctx, password_hash2, MSCHAP_HASH_SZ); + EVP_DigestUpdate(ctx, ntresponse, 24); + EVP_DigestUpdate(ctx, magic1, 27); + EVP_DigestFinal(ctx, md, &mdlen); + EVP_MD_CTX_free(ctx); memcpy(masterkey, md, 16); } @@ -267,7 +286,7 @@ void mschap_asymetric_startkey(uint8_t *masterkey, uint8_t *sessionkey, int sessionkeylen, int issend, int isserver) { - EVP_MD_CTX ctx; + EVP_MD_CTX *ctx; uint8_t md[SHA_DIGEST_LENGTH]; unsigned int mdlen; uint8_t *s; @@ -299,12 +318,16 @@ mschap_asymetric_startkey(uint8_t *masterkey, uint8_t *sessionkey, else s = isserver ? magic2 : magic3; - EVP_DigestInit(&ctx, EVP_sha1()); - EVP_DigestUpdate(&ctx, masterkey, 16); - EVP_DigestUpdate(&ctx, sha1_pad1, 40); - EVP_DigestUpdate(&ctx, s, 84); - EVP_DigestUpdate(&ctx, sha1_pad2, 40); - EVP_DigestFinal(&ctx, md, &mdlen); + ctx = EVP_MD_CTX_new(); + if (ctx == NULL) + fatalx("%s: EVP_MD_CTX_NEW()", __func__); + EVP_DigestInit(ctx, EVP_sha1()); + EVP_DigestUpdate(ctx, masterkey, 16); + EVP_DigestUpdate(ctx, sha1_pad1, 40); + EVP_DigestUpdate(ctx, s, 84); + EVP_DigestUpdate(ctx, sha1_pad2, 40); + EVP_DigestFinal(ctx, md, &mdlen); + EVP_MD_CTX_free(ctx); memcpy(sessionkey, md, sessionkeylen); } @@ -336,24 +359,28 @@ void mschap_radiuskey(uint8_t *plain, const uint8_t *crypted, const uint8_t *authenticator, const uint8_t *secret) { - EVP_MD_CTX ctx; + EVP_MD_CTX *ctx; uint8_t b[MD5_DIGEST_LENGTH], p[32]; unsigned int i, mdlen; - EVP_DigestInit(&ctx, EVP_md5()); - EVP_DigestUpdate(&ctx, secret, strlen(secret)); - EVP_DigestUpdate(&ctx, authenticator, 16); - EVP_DigestUpdate(&ctx, crypted, 2); - EVP_DigestFinal(&ctx, b, &mdlen); + ctx = EVP_MD_CTX_new(); + if (ctx == NULL) + fatalx("%s: EVP_MD_CTX_NEW()", __func__); + EVP_DigestInit(ctx, EVP_md5()); + EVP_DigestUpdate(ctx, secret, strlen(secret)); + EVP_DigestUpdate(ctx, authenticator, 16); + EVP_DigestUpdate(ctx, crypted, 2); + EVP_DigestFinal(ctx, b, &mdlen); for (i = 0; i < mdlen; i++) { p[i] = b[i] ^ crypted[i+2]; } - EVP_DigestInit(&ctx, EVP_md5()); - EVP_DigestUpdate(&ctx, secret, strlen(secret)); - EVP_DigestUpdate(&ctx, crypted + 2, mdlen); - EVP_DigestFinal(&ctx, b, &mdlen); + EVP_DigestInit(ctx, EVP_md5()); + EVP_DigestUpdate(ctx, secret, strlen(secret)); + EVP_DigestUpdate(ctx, crypted + 2, mdlen); + EVP_DigestFinal(ctx, b, &mdlen); + EVP_MD_CTX_free(ctx); for (i = 0; i < mdlen; i++) { p[i+16] = b[i] ^ crypted[i+18]; diff --git a/sbin/iked/crypto.c b/sbin/iked/crypto.c index 88cea383b37..3115baa607b 100644 --- a/sbin/iked/crypto.c +++ b/sbin/iked/crypto.c @@ -1,4 +1,4 @@ -/* $OpenBSD: crypto.c,v 1.32 2021/01/26 23:06:23 tobhe Exp $ */ +/* $OpenBSD: crypto.c,v 1.33 2021/02/04 19:59:15 tobhe Exp $ */ /* * Copyright (c) 2010-2013 Reyk Floeter @@ -29,6 +29,7 @@ #include #include +#include #include #include #include @@ -179,7 +180,6 @@ hash_new(uint8_t type, uint16_t id) { struct iked_hash *hash; const EVP_MD *md = NULL; - HMAC_CTX *ctx = NULL; int length = 0, fixedkey = 0, trunc = 0, isaead = 0; switch (type) { @@ -293,15 +293,13 @@ hash_new(uint8_t type, uint16_t id) if (isaead) return (hash); - if ((ctx = calloc(1, sizeof(*ctx))) == NULL) { + hash->hash_ctx = HMAC_CTX_new(); + if (hash->hash_ctx == NULL) { log_debug("%s: alloc hash ctx", __func__); hash_free(hash); return (NULL); } - HMAC_CTX_init(ctx); - hash->hash_ctx = ctx; - return (hash); } @@ -321,10 +319,8 @@ hash_free(struct iked_hash *hash) { if (hash == NULL) return; - if (hash->hash_ctx != NULL) { - HMAC_CTX_cleanup(hash->hash_ctx); - free(hash->hash_ctx); - } + if (hash->hash_ctx != NULL) + HMAC_CTX_free(hash->hash_ctx); ibuf_release(hash->hash_key); free(hash); } @@ -374,7 +370,6 @@ cipher_new(uint8_t type, uint16_t id, uint16_t id_length) { struct iked_cipher *encr; const EVP_CIPHER *cipher = NULL; - EVP_CIPHER_CTX *ctx = NULL; int length = 0, fixedkey = 0, ivlength = 0; int saltlength = 0, authid = 0; @@ -480,15 +475,13 @@ cipher_new(uint8_t type, uint16_t id, uint16_t id_length) encr->encr_saltlength = saltlength; encr->encr_authid = authid; - if ((ctx = calloc(1, sizeof(*ctx))) == NULL) { + encr->encr_ctx = EVP_CIPHER_CTX_new(); + if (encr->encr_ctx == NULL) { log_debug("%s: alloc cipher ctx", __func__); cipher_free(encr); return (NULL); } - EVP_CIPHER_CTX_init(ctx); - encr->encr_ctx = ctx; - return (encr); } @@ -710,7 +703,7 @@ dsa_new(uint8_t id, struct iked_hash *prf, int sign) dsa.dsa_hmac = 1; break; case IKEV2_AUTH_DSS_SIG: - dsa.dsa_priv = EVP_dss1(); + dsa.dsa_priv = EVP_sha1(); break; case IKEV2_AUTH_ECDSA_256: dsa.dsa_priv = EVP_sha256(); @@ -738,12 +731,11 @@ dsa_new(uint8_t id, struct iked_hash *prf, int sign) dsap->dsa_sign = sign; if (dsap->dsa_hmac) { - if ((dsap->dsa_ctx = calloc(1, sizeof(HMAC_CTX))) == NULL) { + if ((dsap->dsa_ctx = HMAC_CTX_new()) == NULL) { log_debug("%s: alloc hash ctx", __func__); dsa_free(dsap); return (NULL); } - HMAC_CTX_init((HMAC_CTX *)dsap->dsa_ctx); } else { if ((dsap->dsa_ctx = EVP_MD_CTX_create()) == NULL) { log_debug("%s: alloc digest ctx", __func__); @@ -773,8 +765,7 @@ dsa_free(struct iked_dsa *dsa) if (dsa == NULL) return; if (dsa->dsa_hmac) { - HMAC_CTX_cleanup((HMAC_CTX *)dsa->dsa_ctx); - free(dsa->dsa_ctx); + HMAC_CTX_free((HMAC_CTX *)dsa->dsa_ctx); } else { EVP_MD_CTX_destroy((EVP_MD_CTX *)dsa->dsa_ctx); if (dsa->dsa_key) @@ -903,7 +894,7 @@ _dsa_verify_init(struct iked_dsa *dsa, const uint8_t *sig, size_t len) print_map(dsa->dsa_method, ikev2_auth_map)); return (-1); } - keytype = EVP_PKEY_type(((EVP_PKEY *)dsa->dsa_key)->type); + keytype = EVP_PKEY_type(EVP_PKEY_id(((EVP_PKEY *)dsa->dsa_key))); if (sig == NULL) { log_debug("%s: signature missing", __func__); return (-1); @@ -999,7 +990,7 @@ _dsa_sign_encode(struct iked_dsa *dsa, uint8_t *ptr, size_t len, size_t *offp) return (0); if (dsa->dsa_key == NULL) return (-1); - keytype = EVP_PKEY_type(((EVP_PKEY *)dsa->dsa_key)->type); + keytype = EVP_PKEY_type(EVP_PKEY_id(((EVP_PKEY *)dsa->dsa_key))); for (i = 0; i < nitems(schemes); i++) { /* XXX should avoid calling sc_md() each time... */ if (keytype == schemes[i].sc_keytype && @@ -1058,6 +1049,7 @@ _dsa_sign_ecdsa(struct iked_dsa *dsa, uint8_t *ptr, size_t len) size_t tmplen; int ret = -1; int bnlen, off; + const BIGNUM *r, *s; if (len % 2) goto done; /* must be even */ @@ -1076,13 +1068,14 @@ _dsa_sign_ecdsa(struct iked_dsa *dsa, uint8_t *ptr, size_t len) p = tmp; if (d2i_ECDSA_SIG(&obj, &p, tmplen) == NULL) goto done; - if (BN_num_bytes(obj->r) > bnlen || BN_num_bytes(obj->s) > bnlen) + ECDSA_SIG_get0(obj, &r, &s); + if (BN_num_bytes(r) > bnlen || BN_num_bytes(s) > bnlen) goto done; memset(ptr, 0, len); - off = bnlen - BN_num_bytes(obj->r); - BN_bn2bin(obj->r, ptr + off); - off = 2 * bnlen - BN_num_bytes(obj->s); - BN_bn2bin(obj->s, ptr + off); + off = bnlen - BN_num_bytes(r); + BN_bn2bin(r, ptr + off); + off = 2 * bnlen - BN_num_bytes(s); + BN_bn2bin(s, ptr + off); ret = 0; done: free(tmp); @@ -1138,6 +1131,7 @@ _dsa_verify_prepare(struct iked_dsa *dsa, uint8_t **sigp, size_t *lenp, uint8_t *ptr = NULL; size_t bnlen, len, off; int ret = -1; + BIGNUM *r = NULL, *s = NULL; *freemep = NULL; /* don't return garbage in case of an error */ @@ -1168,10 +1162,12 @@ _dsa_verify_prepare(struct iked_dsa *dsa, uint8_t **sigp, size_t *lenp, bnlen = (*lenp)/2; /* sigp points to concatenation: r|s */ if ((obj = ECDSA_SIG_new()) == NULL || - BN_bin2bn(*sigp, bnlen, obj->r) == NULL || - BN_bin2bn(*sigp+bnlen, bnlen, obj->s) == NULL || + (r = BN_bin2bn(*sigp, bnlen, NULL)) == NULL || + (s = BN_bin2bn(*sigp+bnlen, bnlen, NULL)) == NULL || + ECDSA_SIG_set0(obj, r, s) == 0 || (len = i2d_ECDSA_SIG(obj, &ptr)) == 0) goto done; + r = s = NULL; *lenp = len; *sigp = ptr; *freemep = ptr; @@ -1182,6 +1178,8 @@ _dsa_verify_prepare(struct iked_dsa *dsa, uint8_t **sigp, size_t *lenp, return (0); } done: + BN_clear_free(r); + BN_clear_free(s); free(ptr); if (obj) ECDSA_SIG_free(obj); diff --git a/sbin/iked/dh.c b/sbin/iked/dh.c index 9a762c61e32..96b888d1518 100644 --- a/sbin/iked/dh.c +++ b/sbin/iked/dh.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dh.c,v 1.24 2020/10/28 20:54:13 tobhe Exp $ */ +/* $OpenBSD: dh.c,v 1.25 2021/02/04 19:59:15 tobhe Exp $ */ /* * Copyright (c) 2010-2014 Reyk Floeter @@ -394,17 +394,27 @@ dh_create_shared(struct group *group, struct ibuf **secretp, struct ibuf *exchan int modp_init(struct group *group) { + BIGNUM *g = NULL, *p = NULL; DH *dh; + int ret = -1; if ((dh = DH_new()) == NULL) return (-1); + + if (!BN_hex2bn(&p, group->spec->prime) || + !BN_hex2bn(&g, group->spec->generator) || + DH_set0_pqg(dh, p, NULL, g) == 0) + goto done; + + p = g = NULL; group->dh = dh; - if (!BN_hex2bn(&dh->p, group->spec->prime) || - !BN_hex2bn(&dh->g, group->spec->generator)) - return (-1); + ret = 0; + done: + BN_clear_free(g); + BN_clear_free(p); - return (0); + return (ret); } int @@ -418,12 +428,14 @@ modp_getlen(struct group *group) int modp_create_exchange(struct group *group, uint8_t *buf) { - DH *dh = group->dh; - int len, ret; + const BIGNUM *pub; + DH *dh = group->dh; + int len, ret; if (!DH_generate_key(dh)) return (-1); - ret = BN_bn2bin(dh->pub_key, buf); + DH_get0_key(group->dh, &pub, NULL); + ret = BN_bn2bin(pub, buf); if (!ret) return (-1); diff --git a/sbin/iked/ikev2.c b/sbin/iked/ikev2.c index 8d2af278da2..f98a273bedc 100644 --- a/sbin/iked/ikev2.c +++ b/sbin/iked/ikev2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ikev2.c,v 1.301 2021/02/01 16:37:48 tobhe Exp $ */ +/* $OpenBSD: ikev2.c,v 1.302 2021/02/04 19:59:15 tobhe Exp $ */ /* * Copyright (c) 2019 Tobias Heider @@ -2119,7 +2119,7 @@ ssize_t ikev2_nat_detection(struct iked *env, struct iked_message *msg, void *ptr, size_t len, unsigned int type, int frompeer) { - EVP_MD_CTX ctx; + EVP_MD_CTX *ctx; struct ike_header *hdr; uint8_t md[SHA_DIGEST_LENGTH]; unsigned int mdlen = sizeof(md); @@ -2150,8 +2150,10 @@ ikev2_nat_detection(struct iked *env, struct iked_message *msg, dst = (struct sockaddr *)&msg->msg_peer; } - EVP_MD_CTX_init(&ctx); - EVP_DigestInit_ex(&ctx, EVP_sha1(), NULL); + ctx = EVP_MD_CTX_new(); + if (ctx == NULL) + return (-1); + EVP_DigestInit_ex(ctx, EVP_sha1(), NULL); switch (type) { case IKEV2_N_NAT_DETECTION_SOURCE_IP: @@ -2174,22 +2176,22 @@ ikev2_nat_detection(struct iked *env, struct iked_message *msg, goto done; } - EVP_DigestUpdate(&ctx, &ispi, sizeof(ispi)); - EVP_DigestUpdate(&ctx, &rspi, sizeof(rspi)); + EVP_DigestUpdate(ctx, &ispi, sizeof(ispi)); + EVP_DigestUpdate(ctx, &rspi, sizeof(rspi)); switch (ss->sa_family) { case AF_INET: in4 = (struct sockaddr_in *)ss; - EVP_DigestUpdate(&ctx, &in4->sin_addr.s_addr, + EVP_DigestUpdate(ctx, &in4->sin_addr.s_addr, sizeof(in4->sin_addr.s_addr)); - EVP_DigestUpdate(&ctx, &in4->sin_port, + EVP_DigestUpdate(ctx, &in4->sin_port, sizeof(in4->sin_port)); break; case AF_INET6: in6 = (struct sockaddr_in6 *)ss; - EVP_DigestUpdate(&ctx, &in6->sin6_addr.s6_addr, + EVP_DigestUpdate(ctx, &in6->sin6_addr.s6_addr, sizeof(in6->sin6_addr.s6_addr)); - EVP_DigestUpdate(&ctx, &in6->sin6_port, + EVP_DigestUpdate(ctx, &in6->sin6_port, sizeof(in6->sin6_port)); break; default: @@ -2199,10 +2201,10 @@ ikev2_nat_detection(struct iked *env, struct iked_message *msg, if (env->sc_nattmode == NATT_FORCE) { /* Enforce NAT-T/UDP-encapsulation by distorting the digest */ rnd = arc4random(); - EVP_DigestUpdate(&ctx, &rnd, sizeof(rnd)); + EVP_DigestUpdate(ctx, &rnd, sizeof(rnd)); } - EVP_DigestFinal_ex(&ctx, md, &mdlen); + EVP_DigestFinal_ex(ctx, md, &mdlen); if (len < mdlen) goto done; @@ -2210,7 +2212,7 @@ ikev2_nat_detection(struct iked *env, struct iked_message *msg, memcpy(ptr, md, mdlen); ret = mdlen; done: - EVP_MD_CTX_cleanup(&ctx); + EVP_MD_CTX_free(ctx); return (ret); } -- 2.20.1