Re: [Openvpn-devel] [PATCH 2/2 v2] Handle PSS padding in cryptoapicert
On Wed, Jan 30, 2019 at 8:09 AM Arne Schwabe wrote: > Am 23.01.19 um 18:48 schrieb selva.n...@gmail.com: > > From: Selva Nair > > > > For PSS padding, CNG requires the digest to be signed > > and the digest algorithm in use, which are not accessible > > via the rsa_sign and rsa_priv_enc callbacks of OpenSSL. > > This patch uses the EVP_KEY interface to hook to > > evp_pkey_sign callback if OpenSSL version is > 1.1.0. > > > > To test this code path, both the server and client should > > be built with OpenSSL 1.1.1 and use TLS version >= 1.2 > > > > Tested on Windows 7 client against a Linux server. > > > > Normally, I not always expect patches to always cleanly apply but in > this case I cannot get git to apply this thing. > > git am <~/dl/Openvpn-devel-2-2-v2-Handle-PSS-padding-in-cryptoapicert.patch > Applying: Handle PSS padding in cryptoapicert > error: patch failed: src/openvpn/cryptoapi.c:320 > error: src/openvpn/cryptoapi.c: patch does not apply > Patch failed at 0001 Handle PSS padding in cryptoapicert > hint: Use 'git am --show-current-patch' to see the failed patch > When you have resolved this problem, run "git am --continue". > If you prefer to skip this patch, run "git am --skip" instead. > To restore the original branch and stop patching, run "git am --abort". > > > git am --3way > Applying: Handle PSS padding in cryptoapicert > error: sha1 information is lacking or useless (src/openvpn/cryptoapi.c). > error: could not build fake ancestor > Patch failed at 0001 Handle PSS padding in cryptoapicert > hint: Use 'git am --show-current-patch' to see the failed patch > When you have resolved this problem, run "git am --continue". > If you prefer to skip this patch, run "git am --skip" instead. > To restore the original branch and stop patching, run "git am --abort". > > > Since Gert/David will also face the same problems later it might be > easier to resend this patch in a form that applies to master without > manually resolving conflicts. > > It seems I had second guessed uncrustify in a context --- a space before "?" added by uncrustify and a space in "(BYTE *) from" which is a sin in our books, but uncrustify doesn't care. I would have though "git am --ignore-whitespace" would have worked around that, but it doesn't when the mismatch is in the context? What happens twice happens thrice -- v3 is in the mail.. Selva ___ Openvpn-devel mailing list Openvpn-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/openvpn-devel
Re: [Openvpn-devel] [PATCH 2/2 v2] Handle PSS padding in cryptoapicert
Am 23.01.19 um 18:48 schrieb selva.n...@gmail.com: > From: Selva Nair > > For PSS padding, CNG requires the digest to be signed > and the digest algorithm in use, which are not accessible > via the rsa_sign and rsa_priv_enc callbacks of OpenSSL. > This patch uses the EVP_KEY interface to hook to > evp_pkey_sign callback if OpenSSL version is > 1.1.0. > > To test this code path, both the server and client should > be built with OpenSSL 1.1.1 and use TLS version >= 1.2 > > Tested on Windows 7 client against a Linux server. > Normally, I not always expect patches to always cleanly apply but in this case I cannot get git to apply this thing. git am <~/dl/Openvpn-devel-2-2-v2-Handle-PSS-padding-in-cryptoapicert.patch Applying: Handle PSS padding in cryptoapicert error: patch failed: src/openvpn/cryptoapi.c:320 error: src/openvpn/cryptoapi.c: patch does not apply Patch failed at 0001 Handle PSS padding in cryptoapicert hint: Use 'git am --show-current-patch' to see the failed patch When you have resolved this problem, run "git am --continue". If you prefer to skip this patch, run "git am --skip" instead. To restore the original branch and stop patching, run "git am --abort". git am --3way Applying: Handle PSS padding in cryptoapicert error: sha1 information is lacking or useless (src/openvpn/cryptoapi.c). error: could not build fake ancestor Patch failed at 0001 Handle PSS padding in cryptoapicert hint: Use 'git am --show-current-patch' to see the failed patch When you have resolved this problem, run "git am --continue". If you prefer to skip this patch, run "git am --skip" instead. To restore the original branch and stop patching, run "git am --abort". Since Gert/David will also face the same problems later it might be easier to resend this patch in a form that applies to master without manually resolving conflicts. Arne signature.asc Description: OpenPGP digital signature ___ Openvpn-devel mailing list Openvpn-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/openvpn-devel
[Openvpn-devel] [PATCH 2/2 v2] Handle PSS padding in cryptoapicert
From: Selva Nair For PSS padding, CNG requires the digest to be signed and the digest algorithm in use, which are not accessible via the rsa_sign and rsa_priv_enc callbacks of OpenSSL. This patch uses the EVP_KEY interface to hook to evp_pkey_sign callback if OpenSSL version is > 1.1.0. To test this code path, both the server and client should be built with OpenSSL 1.1.1 and use TLS version >= 1.2 Tested on Windows 7 client against a Linux server. Signed-off-by: Selva Nair --- v2: Changes: - Meaningless call to EVP_MD_size() removed. - /** for function doc strings - Multiline comments: beginning /* and ending */ left blank - White space in cast as (TYPE)foo and (TYPE *)bar - Some extra white-space changes suggested by uncrustify src/openvpn/cryptoapi.c | 267 +--- 1 file changed, 252 insertions(+), 15 deletions(-) diff --git a/src/openvpn/cryptoapi.c b/src/openvpn/cryptoapi.c index 139845b..0c11712 100644 --- a/src/openvpn/cryptoapi.c +++ b/src/openvpn/cryptoapi.c @@ -40,6 +40,7 @@ #ifdef ENABLE_CRYPTOAPI #include +#include #include #include #include @@ -105,6 +106,12 @@ static ERR_STRING_DATA CRYPTOAPI_str_functs[] = { /* index for storing external data in EC_KEY: < 0 means uninitialized */ static int ec_data_idx = -1; +/* Global EVP_PKEY_METHOD used to override the sign operation */ +static EVP_PKEY_METHOD *pmethod; +static int (*default_pkey_sign_init) (EVP_PKEY_CTX *ctx); +static int (*default_pkey_sign) (EVP_PKEY_CTX *ctx, unsigned char *sig, + size_t *siglen, const unsigned char *tbs, size_t tbslen); + typedef struct _CAPI_DATA { const CERT_CONTEXT *cert_context; HCRYPTPROV_OR_NCRYPT_KEY_HANDLE crypt_prov; @@ -177,6 +184,7 @@ cng_hash_algo(int md_type) case 0: alg = NULL; break; + default: msg(M_WARN|M_INFO, "cryptoapicert: Unknown hash type NID=0x%x", md_type); break; @@ -320,28 +328,44 @@ rsa_pub_dec(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, in * Sign the hash in 'from' using NCryptSignHash(). This requires an NCRYPT * key handle in cd->crypt_prov. On return the signature is in 'to'. Returns * the length of the signature or 0 on error. + * This is used only for RSA and padding should be BCRYPT_PAD_PKCS1 or + * BCRYPT_PAD_PSS. * If the hash_algo is not NULL, PKCS #1 DigestInfo header gets added - * to 'from', else it is signed as is. - * For now we support only RSA and the padding is assumed to be PKCS1 v1.5 + * to |from|, else it is signed as is. Use NULL for MD5 + SHA1 hash used + * in TLS 1.1 and earlier. + * In case of PSS padding, |saltlen| should specify the size of salt to use. + * If |to| is NULL returns the required buffer size. */ static int priv_enc_CNG(const CAPI_DATA *cd, const wchar_t *hash_algo, const unsigned char *from, - int flen, unsigned char *to, int tlen, DWORD padding) + int flen, unsigned char *to, int tlen, DWORD padding, DWORD saltlen) { NCRYPT_KEY_HANDLE hkey = cd->crypt_prov; DWORD len = 0; ASSERT(cd->key_spec == CERT_NCRYPT_KEY_SPEC); -msg(D_LOW, "Signing hash using CNG: data size = %d", flen); - -/* The hash OID is already in 'from'. So set the hash algorithm - * in the padding info struct to NULL. - */ -BCRYPT_PKCS1_PADDING_INFO padinfo = {hash_algo}; DWORD status; -status = NCryptSignHash(hkey, padding? : NULL, (BYTE *)from, flen, -to, tlen, , padding); +msg(D_LOW, "Signing hash using CNG: data size = %d padding = %lu", flen, padding); + +if (padding == BCRYPT_PAD_PKCS1) +{ +BCRYPT_PKCS1_PADDING_INFO padinfo = {hash_algo}; +status = NCryptSignHash(hkey, , (BYTE *)from, flen, +to, tlen, , padding); +} +else if (padding == BCRYPT_PAD_PSS) +{ +BCRYPT_PSS_PADDING_INFO padinfo = {hash_algo, saltlen}; +status = NCryptSignHash(hkey, , (BYTE *)from, flen, +to, tlen, , padding); +} +else +{ +RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE); +return 0; +} + if (status != ERROR_SUCCESS) { SetLastError(status); @@ -367,16 +391,18 @@ rsa_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, i 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_OSSL_PRIVATE_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE); return 0; } + if (cd->key_spec == CERT_NCRYPT_KEY_SPEC) { return priv_enc_CNG(cd, NULL, from, flen, to, RSA_size(rsa), -cng_padding_type(padding)); +cng_padding_type(padding), 0);