From patchwork Sun Jan 14 08:04:22 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Selva Nair X-Patchwork-Id: 183 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director3.mail.ord1d.rsapps.net ([172.28.255.1]) by backend31.mail.ord1d.rsapps.net (Dovecot) with LMTP id awsMA/KpW1oDOAAAgoeIoA for ; Sun, 14 Jan 2018 14:05:22 -0500 Received: from proxy1.mail.ord1c.rsapps.net ([172.28.255.1]) by director3.mail.ord1d.rsapps.net (Dovecot) with LMTP id E9vQAvKpW1pCdQAAkXNnRw ; Sun, 14 Jan 2018 14:05:22 -0500 Received: from smtp52.gate.ord1c ([172.28.255.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy1.mail.ord1c.rsapps.net (Dovecot) with LMTP id MU45AvKpW1qISAAA2VeTtA ; Sun, 14 Jan 2018 14:05:22 -0500 X-Spam-Threshold: 95 X-Spam-Score: 0 X-Spam-Flag: NO X-Virus-Scanned: OK X-Orig-To: openvpnslackdevel@openvpn.net X-Originating-Ip: [216.34.181.88] Authentication-Results: smtp52.gate.ord1c.rsapps.net; iprev=pass policy.iprev="216.34.181.88"; spf=pass smtp.mailfrom="openvpn-devel-bounces@lists.sourceforge.net" smtp.helo="lists.sourceforge.net"; dkim=fail (signature verification failed) header.d=sourceforge.net; dkim=fail (signature verification failed) header.d=sf.net; dkim=fail (signature verification failed) header.d=gmail.com; dmarc=fail (p=none; dis=none) header.from=gmail.com X-Classification-ID: de6effcc-f95d-11e7-83b8-b8ca3a5c9d28-1-1 Received: from [216.34.181.88] ([216.34.181.88:30128] helo=lists.sourceforge.net) by smtp52.gate.ord1c.rsapps.net (envelope-from ) (ecelerity 4.2.1.56364 r(Core:4.2.1.14)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id EE/B5-09760-1F9AB5A5; Sun, 14 Jan 2018 14:05:21 -0500 Received: from localhost ([127.0.0.1] helo=sfs-ml-4.v29.ch3.sourceforge.com) by sfs-ml-4.v29.ch3.sourceforge.com with esmtp (Exim 4.89) (envelope-from ) id 1eanaC-0005b7-C7; Sun, 14 Jan 2018 19:04:40 +0000 Received: from sfi-mx-3.v28.ch3.sourceforge.com ([172.29.28.193] helo=mx.sourceforge.net) by sfs-ml-4.v29.ch3.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.89) (envelope-from ) id 1eanaA-0005ay-P6 for openvpn-devel@lists.sourceforge.net; Sun, 14 Jan 2018 19:04:38 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=References:In-Reply-To:Message-Id:Date:Subject:Cc: To:From:Sender:Reply-To:MIME-Version:Content-Type:Content-Transfer-Encoding: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=Pv9Mif9BTbamgg0jRVV7jCYtaOv6Op5aBdRw5Om5Cb8=; b=JMpb+hJHkyRg213ajeydmZ0Mpe Ef+1UdhiML2FgXyszRYkcwzAclrFaBUEjZe4aBA1L7V8iS9w9l8Xq/O+E5/sLOELo8yaYy1oRLgbB V+N8GHUWc4ooMqWwqfhLwm2BNmkGfbQpAfz7eGLjUXM8cRqijRB+kYHY0iMB+obQEjuk=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To :MIME-Version:Content-Type:Content-Transfer-Encoding:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=Pv9Mif9BTbamgg0jRVV7jCYtaOv6Op5aBdRw5Om5Cb8=; b=WuMJwvJIKbjD0x7V9KiRh8pevV qBHTYUMpj+XAITF8qYeFU3YmF4xjaDeSQlk8XjMDDUrVCbHx1vVSAHCorfG61U6qIsdNfa0g7avDK 1sxJ7k46EY2PP9yRqhrpPfganPFFaQaSxdf8zjSaEPFo8dwj0YiDkaijJbJFVenjKTbM=; Received: from mail-io0-f193.google.com ([209.85.223.193]) by sfi-mx-3.v28.ch3.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim 4.89) id 1eana6-0008HH-Qj for openvpn-devel@lists.sourceforge.net; Sun, 14 Jan 2018 19:04:38 +0000 Received: by mail-io0-f193.google.com with SMTP id w188so10951228iod.10 for ; Sun, 14 Jan 2018 11:04:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Pv9Mif9BTbamgg0jRVV7jCYtaOv6Op5aBdRw5Om5Cb8=; b=sgJBQ/n2jGqd2WqNGbIEooe2JFcEeE1OxUKiVz+vuxL+E/+qDzPgYyij3qOCpW61fl a4PoRf637PhEzF3rBOaOVOte9zy2E1r///0qbqRgnXOkMaWguVH9JLCu47Ys4k8t0+qB p9jMPSLToduOvovvTGcH6oAHO6p1ayQlKR3nVtk7KVSuFed3MjXBLTKlhRiyqmVor51G weXr3IXip9tHcZnrwYwWP96GX5JcCa1HkSnN08o9JNsg6J+M92sL8t92NiMhJGY1zwxp DH/1LRAdO0vMzdnjRvr1QJxe6wJuffVcRqfriGOYxJwxfVKURThgeKIyoxnyymbW2YhX m3+g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Pv9Mif9BTbamgg0jRVV7jCYtaOv6Op5aBdRw5Om5Cb8=; b=Pz7S765pgxUaN7xX//E6ZqRlIkg8MSxmbOKgvtC+BP6liPddFQiMV90SQplQLAv2Yl gLJaAOZxDDq630Oeu2DkInh2ni/K3Es2lJawwaiXdB0CZvAD8WztYZvVa8tbBl7H2iDr pGYKK5LE+zdKDRoXbA4irU1VGQYDvMfQGatx1ugH6S0mNp8ji7xU7vK7ZoOI5owDrUOq jofjorrVvbO3ucn6VucI292aS2EXiuFW5jJXeqxoq3hYuMLiq3LkSmBus5puId3NmuIm GxZM0yz3pqckMer3xfoi8nP27pLQGJ0xN1ii0e7eN+QW1BDuRJjfL+mIrkk5/DSNJBhh +lDg== X-Gm-Message-State: AKGB3mJhpp95Lo9szFruoHhk8k1RcWnXTRdqCI9AGRlo8BiD7NmnrGnB gB3NN9M8QCkG+WgfLxL5MMI3l5yv X-Google-Smtp-Source: ACJfBotwCOCF0B+syyp9shEB/m/kWGGF7NTUR9HbTDlRE/1lGSCGq+sqX+dPDDOkGRQbPvC1tk0PFw== X-Received: by 10.107.142.201 with SMTP id q192mr32480310iod.293.1515956669252; Sun, 14 Jan 2018 11:04:29 -0800 (PST) Received: from saturn.home.sansel.ca (CPE40167ea0e1c2-CM788df74daaa0.cpe.net.cable.rogers.com. [99.228.215.92]) by smtp.gmail.com with ESMTPSA id 137sm4333454itl.36.2018.01.14.11.04.27 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 14 Jan 2018 11:04:28 -0800 (PST) From: selva.nair@gmail.com To: openvpn-devel@lists.sourceforge.net Date: Sun, 14 Jan 2018 14:04:22 -0500 Message-Id: <1515956662-30572-1-git-send-email-selva.nair@gmail.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: References: X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider (selva.nair[at]gmail.com) -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at http://www.dnswl.org/, no trust [209.85.223.193 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature X-Headers-End: 1eana6-0008HH-Qj Subject: [Openvpn-devel] [PATCH v2 1/2] Bring cryptoapi.c upto speed with openssl 1.1 X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox From: Selva Nair - Replace direct access to internals of openssl structs by corresponding methods. v2: Remove the call to EVP_PKEY_id() as its slated for removal from the compat layer (see also review by Stefan) Signed-off-by: Selva Nair Acked-by: Steffan Karger --- Freeing rsa_method in this code path requires more fixup than just use of RSA_meth_free (not freed at in n some errors etc.), so will be addressed in a separate patch. configure.ac | 1 + src/openvpn/cryptoapi.c | 68 ++++++++++++++++++++++++++------------------ src/openvpn/openssl_compat.h | 14 +++++++++ 3 files changed, 56 insertions(+), 27 deletions(-) diff --git a/configure.ac b/configure.ac index b4fd1b3..2c1937e 100644 --- a/configure.ac +++ b/configure.ac @@ -944,6 +944,7 @@ if test "${with_crypto_library}" = "openssl"; then RSA_meth_set_init \ RSA_meth_set_finish \ RSA_meth_set0_app_data \ + RSA_meth_get0_app_data \ EC_GROUP_order_bits ] ) diff --git a/src/openvpn/cryptoapi.c b/src/openvpn/cryptoapi.c index d90cc5d..4f2c636 100644 --- a/src/openvpn/cryptoapi.c +++ b/src/openvpn/cryptoapi.c @@ -47,6 +47,7 @@ #include #include "buffer.h" +#include "openssl_compat.h" /* MinGW w32api 3.17 is still incomplete when it comes to CryptoAPI while * MinGW32-w64 defines all macros used. This is a hack around that problem. @@ -213,20 +214,20 @@ rsa_pub_dec(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, in static int rsa_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { - CAPI_DATA *cd = (CAPI_DATA *) rsa->meth->app_data; + CAPI_DATA *cd = (CAPI_DATA *) RSA_meth_get0_app_data(RSA_get_method(rsa)); HCRYPTHASH hash; DWORD hash_size, len, i; unsigned char *buf; if (cd == NULL) { - RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_PASSED_NULL_PARAMETER); + RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, ERR_R_PASSED_NULL_PARAMETER); return 0; } if (padding != RSA_PKCS1_PADDING) { /* AFAICS, CryptSignHash() *always* uses PKCS1 padding. */ - RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE); + RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE); return 0; } /* Unfortunately, there is no "CryptSign()" function in CryptoAPI, that would @@ -236,7 +237,7 @@ rsa_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, i /* For now, we only support NID_md5_sha1 */ if (flen != SSL_SIG_LENGTH) { - RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, RSA_R_INVALID_MESSAGE_LENGTH); + RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, RSA_R_INVALID_MESSAGE_LENGTH); return 0; } if (!CryptCreateHash(cd->crypt_prov, CALG_SSL3_SHAMD5, 0, 0, &hash)) @@ -253,7 +254,7 @@ rsa_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, i } if ((int) hash_size != flen) { - RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, RSA_R_INVALID_MESSAGE_LENGTH); + RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, RSA_R_INVALID_MESSAGE_LENGTH); CryptDestroyHash(hash); return 0; } @@ -268,7 +269,7 @@ rsa_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, i buf = malloc(len); if (buf == NULL) { - RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE); + RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE); CryptDestroyHash(hash); return 0; } @@ -312,7 +313,8 @@ init(RSA *rsa) static int finish(RSA *rsa) { - CAPI_DATA *cd = (CAPI_DATA *) rsa->meth->app_data; + const RSA_METHOD *rsa_meth = RSA_get_method(rsa); + CAPI_DATA *cd = (CAPI_DATA *) RSA_meth_get0_app_data(rsa_meth); if (cd == NULL) { @@ -326,9 +328,8 @@ finish(RSA *rsa) { CertFreeCertificateContext(cd->cert_context); } - free(rsa->meth->app_data); - free((char *) rsa->meth); - rsa->meth = NULL; + free(cd); + RSA_meth_free((RSA_METHOD*) rsa_meth); return 1; } @@ -412,9 +413,9 @@ SSL_CTX_use_CryptoAPI_certificate(SSL_CTX *ssl_ctx, const char *cert_prop) X509 *cert = NULL; RSA *rsa = NULL, *pub_rsa; CAPI_DATA *cd = calloc(1, sizeof(*cd)); - RSA_METHOD *my_rsa_method = calloc(1, sizeof(*my_rsa_method)); + RSA_METHOD *my_rsa_method = NULL; - if (cd == NULL || my_rsa_method == NULL) + if (cd == NULL) { SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_MALLOC_FAILURE); goto err; @@ -469,15 +470,16 @@ SSL_CTX_use_CryptoAPI_certificate(SSL_CTX *ssl_ctx, const char *cert_prop) /* here we don't need to do CryptGetUserKey() or anything; all necessary key * info is in cd->cert_context, and then, in cd->crypt_prov. */ - my_rsa_method->name = "Microsoft CryptoAPI RSA Method"; - my_rsa_method->rsa_pub_enc = rsa_pub_enc; - my_rsa_method->rsa_pub_dec = rsa_pub_dec; - my_rsa_method->rsa_priv_enc = rsa_priv_enc; - my_rsa_method->rsa_priv_dec = rsa_priv_dec; - /* my_rsa_method->init = init; */ - my_rsa_method->finish = finish; - my_rsa_method->flags = RSA_METHOD_FLAG_NO_CHECK; - my_rsa_method->app_data = (char *) cd; + my_rsa_method = RSA_meth_new("Microsoft Cryptography API RSA Method", + RSA_METHOD_FLAG_NO_CHECK); + check_malloc_return(my_rsa_method); + RSA_meth_set_pub_enc(my_rsa_method, rsa_pub_enc); + RSA_meth_set_pub_dec(my_rsa_method, rsa_pub_dec); + RSA_meth_set_priv_enc(my_rsa_method, rsa_priv_enc); + RSA_meth_set_priv_dec(my_rsa_method, rsa_priv_dec); + RSA_meth_set_init(my_rsa_method, NULL); + RSA_meth_set_finish(my_rsa_method, finish); + RSA_meth_set0_app_data(my_rsa_method, cd); rsa = RSA_new(); if (rsa == NULL) @@ -486,23 +488,35 @@ SSL_CTX_use_CryptoAPI_certificate(SSL_CTX *ssl_ctx, const char *cert_prop) goto err; } - /* cert->cert_info->key->pkey is NULL until we call SSL_CTX_use_certificate(), + /* Public key in cert is NULL until we call SSL_CTX_use_certificate(), * so we do it here then... */ if (!SSL_CTX_use_certificate(ssl_ctx, cert)) { goto err; } /* the public key */ - pub_rsa = cert->cert_info->key->pkey->pkey.rsa; + EVP_PKEY *pkey = X509_get0_pubkey(cert); + /* SSL_CTX_use_certificate() increased the reference count in 'cert', so * we decrease it here with X509_free(), or it will never be cleaned up. */ X509_free(cert); cert = NULL; - /* I'm not sure about what we have to fill in in the RSA, trying out stuff... */ - /* rsa->n indicates the key size */ - rsa->n = BN_dup(pub_rsa->n); - rsa->flags |= RSA_FLAG_EXT_PKEY; + if (!(pub_rsa = EVP_PKEY_get0_RSA(pkey))) + { + msg(M_WARN, "cryptoapicert requires an RSA certificate"); + goto err; + } + + /* Our private key is external, so we fill in only n and e from the public key */ + const BIGNUM *n = NULL; + const BIGNUM *e = NULL; + RSA_get0_key(pub_rsa, &n, &e, NULL); + if (!RSA_set0_key(rsa, BN_dup(n), BN_dup(e), NULL)) + { + goto err; + } + RSA_set_flags(rsa, RSA_flags(rsa) | RSA_FLAG_EXT_PKEY); if (!RSA_set_method(rsa, my_rsa_method)) { goto err; diff --git a/src/openvpn/openssl_compat.h b/src/openvpn/openssl_compat.h index 70b19ae..bc7dbdd 100644 --- a/src/openvpn/openssl_compat.h +++ b/src/openvpn/openssl_compat.h @@ -624,6 +624,20 @@ RSA_meth_set0_app_data(RSA_METHOD *meth, void *app_data) } #endif +#if !defined(HAVE_RSA_METH_GET0_APP_DATA) +/** + * Get the application data of an RSA_METHOD object + * + * @param meth The RSA_METHOD object + * @return pointer to application data, may be NULL + */ +static inline void * +RSA_meth_get0_app_data(const RSA_METHOD *meth) +{ + return meth ? meth->app_data : NULL; +} +#endif + #if !defined(HAVE_EC_GROUP_ORDER_BITS) && !defined(OPENSSL_NO_EC) /** * Gets the number of bits of the order of an EC_GROUP