From patchwork Thu Sep 13 23:14:18 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steffan Karger X-Patchwork-Id: 461 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director8.mail.ord1d.rsapps.net ([172.30.191.6]) by backend30.mail.ord1d.rsapps.net (Dovecot) with LMTP id S8tPGkl8m1tBeAAAIUCqbw for ; Fri, 14 Sep 2018 05:15:53 -0400 Received: from proxy18.mail.ord1d.rsapps.net ([172.30.191.6]) by director8.mail.ord1d.rsapps.net with LMTP id gBw6Gkl8m1u9EgAAfY0hYg ; Fri, 14 Sep 2018 05:15:53 -0400 Received: from smtp7.gate.ord1d ([172.30.191.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy18.mail.ord1d.rsapps.net with LMTP id YDsTGkl8m1umSAAATCaURg ; Fri, 14 Sep 2018 05:15:53 -0400 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.105.38.7] Authentication-Results: smtp7.gate.ord1d.rsapps.net; iprev=pass policy.iprev="216.105.38.7"; 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; dmarc=none (p=nil; dis=none) header.from=fox-it.com X-Suspicious-Flag: YES X-Classification-ID: c6f18760-b7fe-11e8-9907-525400d28ed9-1-1 Received: from [216.105.38.7] ([216.105.38.7:30150] helo=lists.sourceforge.net) by smtp7.gate.ord1d.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id 38/66-28849-84C7B9B5; Fri, 14 Sep 2018 05:15:52 -0400 Received: from [127.0.0.1] (helo=sfs-ml-2.v29.lw.sourceforge.com) by sfs-ml-2.v29.lw.sourceforge.com with esmtp (Exim 4.90_1) (envelope-from ) id 1g0kBh-0001Ol-CB; Fri, 14 Sep 2018 09:14:53 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-2.v29.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) (envelope-from ) id 1g0kBg-0001OX-ET for openvpn-devel@lists.sourceforge.net; Fri, 14 Sep 2018 09:14:52 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Type:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:CC:To:From:Sender:Reply-To: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=UbPn88KuEaGsVgUAf9Mhr/Gdbqts5m+T8rcrWTjpI5w=; b=blXmic1chfn2xI6AvlWEduEEyl fvb2OXtWygsoVCe8UT4OK+uwkPR8oQe6FguCsn1GXJ84nRcZ2edP790An8itDNsWugw00psLkNZ73 xJQ4xuG95+hRl0q/Ly4KxflTqfZrgGU2L/tPdQWeSYC7BmPHhRs+ievneZuDIWYRhSZs=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject: CC:To:From:Sender:Reply-To: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=UbPn88KuEaGsVgUAf9Mhr/Gdbqts5m+T8rcrWTjpI5w=; b=GTY6gb+qnk6lH/Fr/zvLCyp8ML mlRsiDOIP6pXotxbeUQete0/s6wlFOAYM4fRCWVLTLkzJEHjV8k+D4nB4vQrGoH+UfSH6uJnIjqBs edjdmKaumgo00WKOGJfPRrFzkNdXfDkypjNK8KHhRUCMuYZO3xVmP1raOeC5nAYlauXY=; Received: from ns2.fox-it.com ([178.250.144.131]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLSv1:ECDHE-RSA-AES256-SHA:256) (Exim 4.90_1) id 1g0kBe-001Zu1-HH for openvpn-devel@lists.sourceforge.net; Fri, 14 Sep 2018 09:14:52 +0000 Received: from FOXDFT52.FOX.local (unknown [10.0.0.129]) by ns2.fox-it.com (Postfix) with ESMTPS id 27FEF1AF876 for ; Fri, 14 Sep 2018 11:14:42 +0200 (CEST) Received: from steffan-fox.fox.local (172.16.5.172) by FOXDFT52.FOX.local (10.0.0.129) with Microsoft SMTP Server (TLS) id 15.0.1293.2; Fri, 14 Sep 2018 11:14:41 +0200 From: Steffan Karger To: Date: Fri, 14 Sep 2018 11:14:18 +0200 Message-ID: <1536916459-25900-2-git-send-email-steffan.karger@fox-it.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1536916459-25900-1-git-send-email-steffan.karger@fox-it.com> References: <1505166722-5409-1-git-send-email-steffan.karger@fox-it.com> <1536916459-25900-1-git-send-email-steffan.karger@fox-it.com> MIME-Version: 1.0 X-ClientProxiedBy: FOXDFT52.FOX.local (10.0.0.129) To FOXDFT52.FOX.local (10.0.0.129) X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. -0.0 SPF_PASS SPF: sender matches SPF record X-Headers-End: 1g0kBe-001Zu1-HH Subject: [Openvpn-devel] [PATCH v2 2/3] mbedtls: make external signing code generic 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: , Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox This prepares for reusing this code from the mbedtls pkcs11 implementation. The change itself should not have any functional impact. Signed-off-by: Steffan Karger Acked-By: Arne Schwabe --- v2: rebase onto current master src/openvpn/ssl_mbedtls.c | 115 ++++++++++++++++++++++++---------------------- src/openvpn/ssl_mbedtls.h | 41 +++++++++++++++-- 2 files changed, 98 insertions(+), 58 deletions(-) diff --git a/src/openvpn/ssl_mbedtls.c b/src/openvpn/ssl_mbedtls.c index 3c6d872..4c39cf3 100644 --- a/src/openvpn/ssl_mbedtls.c +++ b/src/openvpn/ssl_mbedtls.c @@ -173,12 +173,6 @@ tls_ctx_free(struct tls_root_ctx *ctx) free(ctx->priv_key_pkcs11); } #endif -#if defined(MANAGMENT_EXTERNAL_KEY) - if (ctx->external_key != NULL) - { - free(ctx->external_key); - } -#endif if (ctx->allowed_ciphers) { @@ -462,13 +456,6 @@ tls_ctx_load_priv_file(struct tls_root_ctx *ctx, const char *priv_key_file, return 0; } -#ifdef MANAGMENT_EXTERNAL_KEY - - -struct external_context { - size_t signature_length; -}; - /** * external_pkcs1_sign implements a mbed TLS rsa_sign_func callback, that uses * the management interface to request an RSA signature for the supplied hash. @@ -495,11 +482,9 @@ external_pkcs1_sign( void *ctx_voidptr, unsigned char *sig ) { struct external_context *const ctx = ctx_voidptr; - char *in_b64 = NULL; - char *out_b64 = NULL; int rv; - unsigned char *p = sig; - size_t asn_len = 0, oid_size = 0, sig_len = 0; + uint8_t *to_sign = NULL; + size_t asn_len = 0, oid_size = 0; const char *oid = NULL; if (NULL == ctx) @@ -535,12 +520,14 @@ external_pkcs1_sign( void *ctx_voidptr, asn_len = 10 + oid_size; } - sig_len = ctx->signature_length; - if ( (SIZE_MAX - hashlen) < asn_len || (hashlen + asn_len) > sig_len) + if ((SIZE_MAX - hashlen) < asn_len + || ctx->signature_length < (asn_len + hashlen)) { return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; } + ALLOC_ARRAY_CLEAR(to_sign, uint8_t, asn_len + hashlen); + uint8_t *p = to_sign; if (md_alg != MBEDTLS_MD_NONE) { /* @@ -565,34 +552,16 @@ external_pkcs1_sign( void *ctx_voidptr, *p++ = MBEDTLS_ASN1_OCTET_STRING; *p++ = hashlen; - /* Determine added ASN length */ - asn_len = p - sig; + /* Double-check ASN length */ + ASSERT(asn_len == p - to_sign); } /* Copy the hash to be signed */ - memcpy( p, hash, hashlen ); - - /* convert 'from' to base64 */ - if (openvpn_base64_encode(sig, asn_len + hashlen, &in_b64) <= 0) - { - rv = MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - goto done; - } + memcpy(p, hash, hashlen); - /* call MI for signature */ - if (management) - { - out_b64 = management_query_pk_sig(management, in_b64); - } - if (!out_b64) - { - rv = MBEDTLS_ERR_RSA_PRIVATE_FAILED; - goto done; - } - - /* decode base64 signature to binary and verify length */ - if (openvpn_base64_decode(out_b64, sig, ctx->signature_length) != - ctx->signature_length) + /* Call external signature function */ + if (!ctx->sign(ctx->sign_ctx, to_sign, asn_len + hashlen, sig, + ctx->signature_length)) { rv = MBEDTLS_ERR_RSA_PRIVATE_FAILED; goto done; @@ -601,14 +570,7 @@ external_pkcs1_sign( void *ctx_voidptr, rv = 0; done: - if (in_b64) - { - free(in_b64); - } - if (out_b64) - { - free(out_b64); - } + free(to_sign); return rv; } @@ -621,7 +583,8 @@ external_key_len(void *vctx) } int -tls_ctx_use_management_external_key(struct tls_root_ctx *ctx) +tls_ctx_use_external_signing_func(struct tls_root_ctx *ctx, + external_sign_func sign_func, void *sign_ctx) { ASSERT(NULL != ctx); @@ -631,11 +594,12 @@ tls_ctx_use_management_external_key(struct tls_root_ctx *ctx) return 1; } - ALLOC_OBJ_CLEAR(ctx->external_key, struct external_context); - ctx->external_key->signature_length = mbedtls_pk_get_len(&ctx->crt_chain->pk); + ctx->external_key.signature_length = mbedtls_pk_get_len(&ctx->crt_chain->pk); + ctx->external_key.sign = sign_func; + ctx->external_key.sign_ctx = sign_ctx; ALLOC_OBJ_CLEAR(ctx->priv_key, mbedtls_pk_context); - if (!mbed_ok(mbedtls_pk_setup_rsa_alt(ctx->priv_key, ctx->external_key, + if (!mbed_ok(mbedtls_pk_setup_rsa_alt(ctx->priv_key, &ctx->external_key, NULL, external_pkcs1_sign, external_key_len))) { return 1; @@ -643,6 +607,47 @@ tls_ctx_use_management_external_key(struct tls_root_ctx *ctx) return 0; } + +#ifdef MANAGMENT_EXTERNAL_KEY + +/** Query the management interface for a signature, see external_sign_func. */ +static bool +management_sign_func(void *sign_ctx, const void *src, size_t src_len, + void *dst, size_t dst_len) +{ + bool ret = false; + char *src_b64 = NULL; + char *dst_b64 = NULL; + + if (!management || (openvpn_base64_encode(src, src_len, &src_b64) <= 0)) + { + goto cleanup; + } + + if (!(dst_b64 = management_query_pk_sig(management, src_b64))) + { + goto cleanup; + } + + if (openvpn_base64_decode(dst_b64, dst, dst_len) != dst_len) + { + goto cleanup; + } + + ret = true; +cleanup: + free (src_b64); + free (dst_b64); + + return ret; +} + +int +tls_ctx_use_management_external_key(struct tls_root_ctx *ctx) +{ + return tls_ctx_use_external_signing_func(ctx, management_sign_func, NULL); +} + #endif /* ifdef MANAGMENT_EXTERNAL_KEY */ void diff --git a/src/openvpn/ssl_mbedtls.h b/src/openvpn/ssl_mbedtls.h index dd8ca75..73b4c1a 100644 --- a/src/openvpn/ssl_mbedtls.h +++ b/src/openvpn/ssl_mbedtls.h @@ -58,6 +58,30 @@ typedef struct { } bio_ctx; /** + * External signing function prototype. A function pointer to a function + * implementing this prototype is provided to + * tls_ctx_use_external_signing_func(). + * + * @param sign_ctx The context for the signing function. + * @param src The data to be signed, + * @param src_len The length of src, in bytes. + * @param dst The destination buffer for the signature. + * @param dst_len The length of the destination buffer. + * + * @return true if signing succeeded, false otherwise. + */ +typedef bool (*external_sign_func)( + void *sign_ctx, const void *src, size_t src_size, + void *dst, size_t dst_size); + +/** Context used by external_pkcs1_sign() */ +struct external_context { + size_t signature_length; + external_sign_func sign; + void *sign_ctx; +}; + +/** * Structure that wraps the TLS context. Contents differ depending on the * SSL library used. * @@ -78,9 +102,7 @@ struct tls_root_ctx { #if defined(ENABLE_PKCS11) mbedtls_pkcs11_context *priv_key_pkcs11; /**< PKCS11 private key */ #endif -#ifdef MANAGMENT_EXTERNAL_KEY - struct external_context *external_key; /**< Management external key */ -#endif + struct external_context external_key; /**< External key context */ int *allowed_ciphers; /**< List of allowed ciphers for this connection */ mbedtls_x509_crt_profile cert_profile; /**< Allowed certificate types */ }; @@ -91,5 +113,18 @@ struct key_state_ssl { bio_ctx bio_ctx; }; +/** + * Call the supplied signing function to create a TLS signature during the + * TLS handshake. + * + * @param ctx TLS context to use. + * @param sign_func Signing function to call. + * @param sign_ctx Context for the sign function. + * + * @return 0 if successful, 1 if an error occurred. + */ +int tls_ctx_use_external_signing_func(struct tls_root_ctx *ctx, + external_sign_func sign_func, + void *sign_ctx); #endif /* SSL_MBEDTLS_H_ */