Re: [Openvpn-devel] [PATCH 1/2] Move OpenSSL vs CNG signature digest type mapping to a function

2019-01-23 Thread Arne Schwabe
Am 07.12.18 um 20:17 schrieb selva.n...@gmail.com:
> From: Selva Nair 
> 
> Also add a function to map  OpenSSL padding identifier to
> corresponding CNG constant.
> 
> This is to help add support for additional padding
> types: only refactoring, no functional changes.
> 

I have no compile and used tested it but the code looks good.

Acked-By: Arne Schwabe 

Arne


___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH 1/2] Move OpenSSL vs CNG signature digest type mapping to a function

2018-12-07 Thread selva . nair
From: Selva Nair 

Also add a function to map  OpenSSL padding identifier to
corresponding CNG constant.

This is to help add support for additional padding
types: only refactoring, no functional changes.

Signed-off-by: Selva Nair 
---
 src/openvpn/cryptoapi.c | 120 +---
 1 file changed, 82 insertions(+), 38 deletions(-)

diff --git a/src/openvpn/cryptoapi.c b/src/openvpn/cryptoapi.c
index fa057cb..1ce97f5 100644
--- a/src/openvpn/cryptoapi.c
+++ b/src/openvpn/cryptoapi.c
@@ -113,6 +113,77 @@ typedef struct _CAPI_DATA {
 int ref_count;
 } CAPI_DATA;
 
+/* Translate OpenSSL padding type to CNG padding type
+ * Returns 0 for unknown/unsupported padding.
+ */
+static DWORD
+cng_padding_type(int padding)
+{
+DWORD pad = 0;
+
+switch (padding)
+{
+case RSA_NO_PADDING:
+break;
+
+case RSA_PKCS1_PADDING:
+pad = BCRYPT_PAD_PKCS1;
+break;
+
+case RSA_PKCS1_PSS_PADDING:
+pad = BCRYPT_PAD_PSS;
+break;
+
+default:
+msg(M_WARN|M_INFO, "cryptoapicert: unknown OpenSSL padding type 
%d.",
+padding);
+}
+
+return pad;
+}
+
+/*
+ * Translate OpenSSL hash OID to CNG algorithm name. Returns
+ * "UNKNOWN" for unsupported algorithms and NULL for MD5+SHA1
+ * mixed hash used in TLS 1.1 and earlier.
+ */
+static const wchar_t *
+cng_hash_algo(int md_type)
+{
+const wchar_t *alg = L"UNKNOWN";
+switch (md_type)
+{
+case NID_md5:
+alg = BCRYPT_MD5_ALGORITHM;
+break;
+
+case NID_sha1:
+alg = BCRYPT_SHA1_ALGORITHM;
+break;
+
+case NID_sha256:
+alg = BCRYPT_SHA256_ALGORITHM;
+break;
+
+case NID_sha384:
+alg = BCRYPT_SHA384_ALGORITHM;
+break;
+
+case NID_sha512:
+alg = BCRYPT_SHA512_ALGORITHM;
+break;
+
+case NID_md5_sha1:
+case 0:
+alg = NULL;
+break;
+default:
+msg(M_WARN|M_INFO, "cryptoapicert: Unknown hash type NID=0x%x", 
md_type);
+break;
+}
+return alg;
+}
+
 static void
 CAPI_DATA_free(CAPI_DATA *cd)
 {
@@ -253,7 +324,7 @@ rsa_pub_dec(int flen, const unsigned char *from, unsigned 
char *to, RSA *rsa, in
  */
 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, int padding)
+ int flen, unsigned char *to, int tlen, DWORD padding)
 {
 NCRYPT_KEY_HANDLE hkey = cd->crypt_prov;
 DWORD len = 0;
@@ -268,7 +339,7 @@ priv_enc_CNG(const CAPI_DATA *cd, const wchar_t *hash_algo, 
const unsigned char
 DWORD status;
 
 status = NCryptSignHash(hkey, padding?  : NULL, (BYTE*) from, flen,
-to, tlen, , padding? BCRYPT_PAD_PKCS1 : 0);
+to, tlen, , padding);
 if (status != ERROR_SUCCESS)
 {
 SetLastError(status);
@@ -302,7 +373,8 @@ rsa_priv_enc(int flen, const unsigned char *from, unsigned 
char *to, RSA *rsa, i
 }
 if (cd->key_spec == CERT_NCRYPT_KEY_SPEC)
 {
-return priv_enc_CNG(cd, NULL, from, flen, to, RSA_size(rsa), padding);
+return priv_enc_CNG(cd, NULL, from, flen, to, RSA_size(rsa),
+cng_padding_type(padding));
 }
 
 /* Unfortunately, there is no "CryptSign()" function in CryptoAPI, that 
would
@@ -388,44 +460,16 @@ rsa_sign_CNG(int type, const unsigned char *m, unsigned 
int m_len,
 return 0;
 }
 
-switch (type)
+alg = cng_hash_algo(type);
+if (alg && wcscmp(alg, L"UNKNOWN") == 0)
 {
-case NID_md5:
-alg = BCRYPT_MD5_ALGORITHM;
-break;
-
-case NID_sha1:
-alg = BCRYPT_SHA1_ALGORITHM;
-break;
-
-case NID_sha256:
-alg = BCRYPT_SHA256_ALGORITHM;
-break;
-
-case NID_sha384:
-alg = BCRYPT_SHA384_ALGORITHM;
-break;
-
-case NID_sha512:
-alg = BCRYPT_SHA512_ALGORITHM;
-break;
-
-case NID_md5_sha1:
-if (m_len != SSL_SIG_LENGTH)
-{
-RSAerr(RSA_F_RSA_SIGN, RSA_R_INVALID_MESSAGE_LENGTH);
-return 0;
-}
-/* No DigestInfo header is required -- set alg-name to NULL */
-alg = NULL;
-break;
-default:
-msg(M_WARN, "cryptoapicert: Unknown hash type NID=0x%x", type);
-RSAerr(RSA_F_RSA_SIGN, RSA_R_UNKNOWN_ALGORITHM_TYPE);
-return 0;
+RSAerr(RSA_F_RSA_SIGN, RSA_R_UNKNOWN_ALGORITHM_TYPE);
+return 0;
 }
 
-*siglen = priv_enc_CNG(cd, alg, m, (int)m_len, sig, RSA_size(rsa), 
padding);
+*siglen = priv_enc_CNG(cd, alg, m, (int)m_len, sig, RSA_size(rsa),
+   cng_padding_type(padding));
+