From patchwork Mon Sep 11 11:52:01 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steffan Karger X-Patchwork-Id: 83 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director1.mail.ord1d.rsapps.net ([172.27.255.55]) by backend31.mail.ord1d.rsapps.net (Dovecot) with LMTP id 6wiyOZzGClpdbgAAgoeIoA for ; Tue, 14 Nov 2017 05:34:05 -0500 Received: from proxy7.mail.iad3a.rsapps.net ([172.27.255.55]) by director1.mail.ord1d.rsapps.net (Dovecot) with LMTP id 0XKcAJzGClrtbwAANGzteQ ; Tue, 14 Nov 2017 05:34:04 -0500 Received: from smtp51.gate.iad3a ([172.27.255.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy7.mail.iad3a.rsapps.net (Dovecot) with LMTP id MgtFL5zGCloJIgAAnPvY+A ; Tue, 14 Nov 2017 05:34:04 -0500 X-Spam-Threshold: 95 X-Spam-Score: 0 X-Spam-Flag: NO Authentication-Results: smtp51.gate.iad3a.rsapps.net x-tls.subject="/OU=GT58646928/OU=See www.geotrust.com/resources/cps (c)14/OU=Domain Control Validated - QuickSSL(R) Premium/CN=ns2.fox-it.com"; auth=pass (cipher=DHE-RSA-AES256-SHA) X-Virus-Scanned: OK X-Orig-To: patchwork@openvpn.net X-Originating-Ip: [178.250.144.131] Authentication-Results: smtp51.gate.iad3a.rsapps.net; iprev=pass policy.iprev="178.250.144.131"; spf=pass smtp.mailfrom="steffan.karger@fox-it.com" smtp.helo="ns2.fox-it.com"; dkim=none (message not signed) header.d=none; dmarc=none (p=nil; dis=none) header.from=fox-it.com X-Classification-ID: 558ada20-c927-11e7-a88c-525400aaff7b-1-1 Received: from [178.250.144.131] ([178.250.144.131:40324] helo=ns2.fox-it.com) by smtp51.gate.iad3a.rsapps.net (envelope-from ) (ecelerity 4.2.1.56364 r(Core:4.2.1.14)) with ESMTPS (cipher=DHE-RSA-AES256-SHA subject="/OU=GT58646928/OU=See www.geotrust.com/resources/cps (c)14/OU=Domain Control Validated - QuickSSL(R) Premium/CN=ns2.fox-it.com") id BA/84-14371-C96CA0A5; Tue, 14 Nov 2017 05:34:04 -0500 Received: from FOXDFT52.FOX.local (unknown [10.0.0.129]) by ns2.fox-it.com (Postfix) with ESMTPS id 3A2121C465E for ; Tue, 14 Nov 2017 11:34:03 +0100 (CET) Received: from steffan-fox (10.0.3.167) by FOXDFT52.FOX.local (10.0.0.129) with Microsoft SMTP Server (TLS) id 15.0.1293.2; Tue, 14 Nov 2017 11:34:02 +0100 Resent-From: Steffan Karger Resent-Date: Tue, 14 Nov 2017 11:34:01 +0100 Resent-Message-ID: <20171114103401.GD7627@steffan-fox> Resent-To: Received: from FOXDFT52.FOX.local (10.0.0.129) by FOXDFT52.FOX.local (10.0.0.129) with Microsoft SMTP Server (TLS) id 15.0.1293.2 via Mailbox Transport; Mon, 11 Sep 2017 23:53:56 +0200 Received: from steffan-fox.fox.local (172.16.5.169) by FOXDFT52.FOX.local (10.0.0.129) with Microsoft SMTP Server (TLS) id 15.0.1293.2; Mon, 11 Sep 2017 23:53:55 +0200 From: Steffan Karger To: CC: Steffan Karger Subject: [PATCH 2/3] mbedtls: make external signing code generic Date: Mon, 11 Sep 2017 23:52:01 +0200 Message-ID: <1505166722-5409-3-git-send-email-steffan.karger@fox-it.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1505166722-5409-1-git-send-email-steffan.karger@fox-it.com> References: <1505166722-5409-1-git-send-email-steffan.karger@fox-it.com> X-ClientProxiedBy: FOXDFT52.FOX.local (10.0.0.129) To FOXDFT52.FOX.local (10.0.0.129) MIME-Version: 1.0 X-ClientProxiedBy: FOXDFT52.FOX.local (10.0.0.129) To FOXDFT52.FOX.local (10.0.0.129) 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 --- 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 6d023af..0cf89a8 100644 --- a/src/openvpn/ssl_mbedtls.c +++ b/src/openvpn/ssl_mbedtls.c @@ -146,12 +146,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) { @@ -413,13 +407,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. @@ -446,11 +433,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) @@ -486,12 +471,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) { /* @@ -516,34 +503,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_rsa_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; @@ -552,14 +521,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; } @@ -572,7 +534,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); @@ -582,11 +545,12 @@ tls_ctx_use_management_external_key(struct tls_root_ctx *ctx) return 0; } - 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 0; @@ -594,6 +558,47 @@ tls_ctx_use_management_external_key(struct tls_root_ctx *ctx) return 1; } + +#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_rsa_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 f69b610..2b76cc6 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 */ }; @@ -90,5 +112,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_ */