Re: [Openvpn-devel] [PATCH 2/2 v2] Handle PSS padding in cryptoapicert

2019-01-30 Thread Selva Nair
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

2019-01-30 Thread Arne Schwabe
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

2019-01-23 Thread selva . nair
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);