mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-11-21 16:46:54 -08:00
Added patch to implement BCrypt RSA provider.
This commit is contained in:
parent
5e03e4422d
commit
fd2221cfd9
@ -0,0 +1,296 @@
|
||||
From 72f7ded1f27e7d14b7efb7200b43e320f3e245d4 Mon Sep 17 00:00:00 2001
|
||||
From: Kimmo Myllyvirta <kimmo.myllyvirta@gmail.com>
|
||||
Date: Tue, 10 Oct 2017 16:40:41 +0300
|
||||
Subject: bcrypt: Initial implementation for RSA key import and signature
|
||||
verification.
|
||||
|
||||
---
|
||||
dlls/bcrypt/bcrypt_main.c | 128 ++++++++++++++++++++++++++++++++++++++++++----
|
||||
include/bcrypt.h | 17 ++++++
|
||||
2 files changed, 135 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c
|
||||
index 881f6f7eb0c..3356364a6dc 100644
|
||||
--- a/dlls/bcrypt/bcrypt_main.c
|
||||
+++ b/dlls/bcrypt/bcrypt_main.c
|
||||
@@ -71,6 +71,9 @@ static int (*pgnutls_pubkey_verify_hash2)(gnutls_pubkey_t key, gnutls_sign_algor
|
||||
unsigned int flags, const gnutls_datum_t *hash,
|
||||
const gnutls_datum_t *signature);
|
||||
|
||||
+/* Not present in gnutls version < 2.11.0 */
|
||||
+static int (*pgnutls_pubkey_import_rsa_raw)(gnutls_pubkey_t key, const gnutls_datum_t *m, const gnutls_datum_t *e);
|
||||
+
|
||||
static void *libgnutls_handle;
|
||||
#define MAKE_FUNCPTR(f) static typeof(f) * p##f
|
||||
MAKE_FUNCPTR(gnutls_cipher_decrypt2);
|
||||
@@ -121,6 +124,11 @@ static int compat_gnutls_pubkey_verify_hash2(gnutls_pubkey_t key, gnutls_sign_al
|
||||
return GNUTLS_E_UNKNOWN_CIPHER_TYPE;
|
||||
}
|
||||
|
||||
+static int compat_gnutls_pubkey_import_rsa_raw(gnutls_pubkey_t key, const gnutls_datum_t *m, const gnutls_datum_t *e)
|
||||
+{
|
||||
+ return GNUTLS_E_UNKNOWN_CIPHER_TYPE;
|
||||
+}
|
||||
+
|
||||
static void gnutls_log( int level, const char *msg )
|
||||
{
|
||||
TRACE( "<%d> %s", level, msg );
|
||||
@@ -181,6 +189,11 @@ static BOOL gnutls_initialize(void)
|
||||
WARN("gnutls_pubkey_verify_hash2 not found\n");
|
||||
pgnutls_pubkey_verify_hash2 = compat_gnutls_pubkey_verify_hash2;
|
||||
}
|
||||
+ if (!(pgnutls_pubkey_import_rsa_raw = wine_dlsym( libgnutls_handle, "gnutls_pubkey_import_rsa_raw", NULL, 0 )))
|
||||
+ {
|
||||
+ WARN("gnutls_pubkey_import_rsa_raw not found\n");
|
||||
+ pgnutls_pubkey_import_rsa_raw = compat_gnutls_pubkey_import_rsa_raw;
|
||||
+ }
|
||||
|
||||
if ((ret = pgnutls_global_init()) != GNUTLS_E_SUCCESS)
|
||||
{
|
||||
@@ -234,6 +247,7 @@ enum alg_id
|
||||
ALG_ID_AES,
|
||||
ALG_ID_MD5,
|
||||
ALG_ID_RNG,
|
||||
+ ALG_ID_RSA,
|
||||
ALG_ID_SHA1,
|
||||
ALG_ID_SHA256,
|
||||
ALG_ID_SHA384,
|
||||
@@ -262,6 +276,7 @@ static const struct {
|
||||
/* ALG_ID_AES */ { 654, 0, 0, BCRYPT_AES_ALGORITHM, TRUE },
|
||||
/* ALG_ID_MD5 */ { 274, 16, 512, BCRYPT_MD5_ALGORITHM, FALSE },
|
||||
/* ALG_ID_RNG */ { 0, 0, 0, BCRYPT_RNG_ALGORITHM, FALSE },
|
||||
+ /* ALG_ID_RSA */ { 0, 0, 0, BCRYPT_RSA_ALGORITHM, FALSE },
|
||||
/* ALG_ID_SHA1 */ { 278, 20, 512, BCRYPT_SHA1_ALGORITHM, FALSE },
|
||||
/* ALG_ID_SHA256 */ { 286, 32, 512, BCRYPT_SHA256_ALGORITHM, FALSE },
|
||||
/* ALG_ID_SHA384 */ { 382, 48, 1024, BCRYPT_SHA384_ALGORITHM, FALSE },
|
||||
@@ -340,6 +355,7 @@ NTSTATUS WINAPI BCryptOpenAlgorithmProvider( BCRYPT_ALG_HANDLE *handle, LPCWSTR
|
||||
if (!strcmpW( id, BCRYPT_AES_ALGORITHM )) alg_id = ALG_ID_AES;
|
||||
else if (!strcmpW( id, BCRYPT_MD5_ALGORITHM )) alg_id = ALG_ID_MD5;
|
||||
else if (!strcmpW( id, BCRYPT_RNG_ALGORITHM )) alg_id = ALG_ID_RNG;
|
||||
+ else if (!strcmpW( id, BCRYPT_RSA_ALGORITHM )) alg_id = ALG_ID_RSA;
|
||||
else if (!strcmpW( id, BCRYPT_SHA1_ALGORITHM )) alg_id = ALG_ID_SHA1;
|
||||
else if (!strcmpW( id, BCRYPT_SHA256_ALGORITHM )) alg_id = ALG_ID_SHA256;
|
||||
else if (!strcmpW( id, BCRYPT_SHA384_ALGORITHM )) alg_id = ALG_ID_SHA384;
|
||||
@@ -950,6 +966,7 @@ static NTSTATUS key_asymmetric_init( struct key *key, struct algorithm *alg, con
|
||||
{
|
||||
case ALG_ID_ECDSA_P256:
|
||||
case ALG_ID_ECDSA_P384:
|
||||
+ case ALG_ID_RSA:
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -1326,6 +1343,34 @@ static NTSTATUS import_gnutls_pubkey_ecc( struct key *key, gnutls_pubkey_t *gnut
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
+static NTSTATUS import_gnutls_pubkey_rsa( struct key *key, gnutls_pubkey_t *gnutls_key )
|
||||
+{
|
||||
+ BCRYPT_RSAKEY_BLOB *rsa_blob;
|
||||
+ gnutls_datum_t m, e;
|
||||
+ int ret;
|
||||
+
|
||||
+ if ((ret = pgnutls_pubkey_init( gnutls_key )))
|
||||
+ {
|
||||
+ pgnutls_perror( ret );
|
||||
+ return STATUS_INTERNAL_ERROR;
|
||||
+ }
|
||||
+
|
||||
+ rsa_blob = (BCRYPT_RSAKEY_BLOB *)key->u.a.pubkey;
|
||||
+ e.data = key->u.a.pubkey + sizeof(*rsa_blob);
|
||||
+ e.size = rsa_blob->cbPublicExp;
|
||||
+ m.data = key->u.a.pubkey + sizeof(*rsa_blob) + rsa_blob->cbPublicExp;
|
||||
+ m.size = rsa_blob->cbModulus;
|
||||
+
|
||||
+ if ((ret = pgnutls_pubkey_import_rsa_raw( *gnutls_key, &m, &e )))
|
||||
+ {
|
||||
+ pgnutls_perror( ret );
|
||||
+ pgnutls_pubkey_deinit( *gnutls_key );
|
||||
+ return STATUS_INTERNAL_ERROR;
|
||||
+ }
|
||||
+
|
||||
+ return STATUS_SUCCESS;
|
||||
+}
|
||||
+
|
||||
static NTSTATUS import_gnutls_pubkey( struct key *key, gnutls_pubkey_t *gnutls_key)
|
||||
{
|
||||
switch (key->alg_id)
|
||||
@@ -1333,6 +1378,8 @@ static NTSTATUS import_gnutls_pubkey( struct key *key, gnutls_pubkey_t *gnutls_
|
||||
case ALG_ID_ECDSA_P256:
|
||||
case ALG_ID_ECDSA_P384:
|
||||
return import_gnutls_pubkey_ecc( key, gnutls_key );
|
||||
+ case ALG_ID_RSA:
|
||||
+ return import_gnutls_pubkey_rsa( key, gnutls_key );
|
||||
|
||||
default:
|
||||
FIXME("Algorithm %d not yet supported\n", key->alg_id);
|
||||
@@ -1362,6 +1409,14 @@ static NTSTATUS prepare_gnutls_signature_ecc( struct key *key, UCHAR *signature,
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
+static NTSTATUS prepare_gnutls_signature_rsa( struct key *key, UCHAR *signature, ULONG signature_len,
|
||||
+ gnutls_datum_t *gnutls_signature )
|
||||
+{
|
||||
+ gnutls_signature->data = signature;
|
||||
+ gnutls_signature->size = signature_len;
|
||||
+ return STATUS_SUCCESS;
|
||||
+}
|
||||
+
|
||||
static NTSTATUS prepare_gnutls_signature( struct key *key, UCHAR *signature, ULONG signature_len,
|
||||
gnutls_datum_t *gnutls_signature )
|
||||
{
|
||||
@@ -1370,6 +1425,8 @@ static NTSTATUS prepare_gnutls_signature( struct key *key, UCHAR *signature, ULO
|
||||
case ALG_ID_ECDSA_P256:
|
||||
case ALG_ID_ECDSA_P384:
|
||||
return prepare_gnutls_signature_ecc( key, signature, signature_len, gnutls_signature );
|
||||
+ case ALG_ID_RSA:
|
||||
+ return prepare_gnutls_signature_rsa( key, signature, signature_len, gnutls_signature );
|
||||
|
||||
default:
|
||||
FIXME( "Algorithm %d not yet supported\n", key->alg_id );
|
||||
@@ -1388,18 +1445,38 @@ static NTSTATUS key_asymmetric_verify( struct key *key, void *padding, UCHAR *ha
|
||||
NTSTATUS status;
|
||||
int ret;
|
||||
|
||||
- if (flags)
|
||||
- FIXME( "Flags %08x not supported\n", flags );
|
||||
+ if (key->alg_id == ALG_ID_RSA)
|
||||
+ {
|
||||
+ BCRYPT_PKCS1_PADDING_INFO *pinfo = (BCRYPT_PKCS1_PADDING_INFO *)padding;
|
||||
|
||||
- /* only the hash size must match, not the actual hash function */
|
||||
- switch (hash_len)
|
||||
+ if (!(flags & BCRYPT_PAD_PKCS1) || !pinfo) return STATUS_INVALID_PARAMETER;
|
||||
+ if (!pinfo->pszAlgId) return STATUS_INVALID_SIGNATURE;
|
||||
+
|
||||
+ if (!strcmpW( pinfo->pszAlgId, BCRYPT_SHA1_ALGORITHM )) hash_algo = GNUTLS_DIG_SHA1;
|
||||
+ else if (!strcmpW( pinfo->pszAlgId, BCRYPT_SHA256_ALGORITHM )) hash_algo = GNUTLS_DIG_SHA256;
|
||||
+ else if (!strcmpW( pinfo->pszAlgId, BCRYPT_SHA384_ALGORITHM )) hash_algo = GNUTLS_DIG_SHA384;
|
||||
+ else if (!strcmpW( pinfo->pszAlgId, BCRYPT_SHA512_ALGORITHM )) hash_algo = GNUTLS_DIG_SHA512;
|
||||
+ else
|
||||
+ {
|
||||
+ FIXME( "Hash algorithm %s not supported\n", debugstr_w(pinfo->pszAlgId) );
|
||||
+ return STATUS_NOT_SUPPORTED;
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
{
|
||||
- case 32: hash_algo = GNUTLS_DIG_SHA256; break;
|
||||
- case 48: hash_algo = GNUTLS_DIG_SHA384; break;
|
||||
+ if (flags)
|
||||
+ FIXME( "Flags %08x not supported\n", flags );
|
||||
|
||||
- default:
|
||||
- FIXME( "Hash size %u not yet supported\n", hash_len );
|
||||
- return STATUS_INVALID_SIGNATURE;
|
||||
+ /* only the hash size must match, not the actual hash function */
|
||||
+ switch (hash_len)
|
||||
+ {
|
||||
+ case 32: hash_algo = GNUTLS_DIG_SHA256; break;
|
||||
+ case 48: hash_algo = GNUTLS_DIG_SHA384; break;
|
||||
+
|
||||
+ default:
|
||||
+ FIXME( "Hash size %u not yet supported\n", hash_len );
|
||||
+ return STATUS_INVALID_SIGNATURE;
|
||||
+ }
|
||||
}
|
||||
|
||||
switch (key->alg_id)
|
||||
@@ -1408,6 +1485,9 @@ static NTSTATUS key_asymmetric_verify( struct key *key, void *padding, UCHAR *ha
|
||||
case ALG_ID_ECDSA_P384:
|
||||
pk_algo = GNUTLS_PK_ECC;
|
||||
break;
|
||||
+ case ALG_ID_RSA:
|
||||
+ pk_algo = GNUTLS_PK_RSA;
|
||||
+ break;
|
||||
|
||||
default:
|
||||
FIXME( "Algorithm %d not yet supported\n", key->alg_id );
|
||||
@@ -1433,7 +1513,8 @@ static NTSTATUS key_asymmetric_verify( struct key *key, void *padding, UCHAR *ha
|
||||
gnutls_hash.size = hash_len;
|
||||
ret = pgnutls_pubkey_verify_hash2( gnutls_key, sign_algo, 0, &gnutls_hash, &gnutls_signature );
|
||||
|
||||
- HeapFree( GetProcessHeap(), 0, gnutls_signature.data );
|
||||
+ if (gnutls_signature.data != signature)
|
||||
+ HeapFree( GetProcessHeap(), 0, gnutls_signature.data );
|
||||
pgnutls_pubkey_deinit( gnutls_key );
|
||||
return (ret < 0) ? STATUS_INVALID_SIGNATURE : STATUS_SUCCESS;
|
||||
}
|
||||
@@ -1774,6 +1855,33 @@ NTSTATUS WINAPI BCryptImportKeyPair( BCRYPT_ALG_HANDLE algorithm, BCRYPT_KEY_HAN
|
||||
*ret_key = key;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
+ else if (!strcmpW( type, BCRYPT_RSAPUBLIC_BLOB ))
|
||||
+ {
|
||||
+ BCRYPT_RSAKEY_BLOB *rsa_blob = (BCRYPT_RSAKEY_BLOB *)input;
|
||||
+
|
||||
+ if (input_len < sizeof(*rsa_blob))
|
||||
+ return STATUS_INVALID_PARAMETER;
|
||||
+
|
||||
+ if (alg->id != ALG_ID_RSA)
|
||||
+ return STATUS_NOT_SUPPORTED;
|
||||
+
|
||||
+ if (rsa_blob->Magic != BCRYPT_RSAPUBLIC_MAGIC)
|
||||
+ return STATUS_NOT_SUPPORTED;
|
||||
+
|
||||
+ if (!(key = HeapAlloc( GetProcessHeap(), 0, sizeof(*key) )))
|
||||
+ return STATUS_NO_MEMORY;
|
||||
+
|
||||
+ key->hdr.magic = MAGIC_KEY;
|
||||
+ if ((status = key_asymmetric_init( key, alg, (BYTE *)rsa_blob,
|
||||
+ sizeof(*rsa_blob) + rsa_blob->cbPublicExp + rsa_blob->cbModulus )))
|
||||
+ {
|
||||
+ HeapFree( GetProcessHeap(), 0, key );
|
||||
+ return status;
|
||||
+ }
|
||||
+
|
||||
+ *ret_key = key;
|
||||
+ return STATUS_SUCCESS;
|
||||
+ }
|
||||
|
||||
FIXME( "unsupported key type %s\n", debugstr_w(type) );
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
diff --git a/include/bcrypt.h b/include/bcrypt.h
|
||||
index 3dcc953e9ed..944796024bf 100644
|
||||
--- a/include/bcrypt.h
|
||||
+++ b/include/bcrypt.h
|
||||
@@ -63,6 +63,8 @@ typedef LONG NTSTATUS;
|
||||
#define BCRYPT_AES_WRAP_KEY_BLOB (const WCHAR []){'R','f','c','3','5','6','5','K','e','y','W','r','a','p','B','l','o','b',0}
|
||||
#define BCRYPT_ECCPUBLIC_BLOB (const WCHAR []){'E','C','C','P','U','B','L','I','C','B','L','O','B',0}
|
||||
#define BCRYPT_ECCPRIVATE_BLOB (const WCHAR []){'E','C','C','P','R','I','V','A','T','E','B','L','O','B',0}
|
||||
+#define BCRYPT_RSAPUBLIC_BLOB (const WCHAR []){'R','S','A','P','U','B','L','I','C','B','L','O','B',0}
|
||||
+#define BCRYPT_RSAPRIVATE_BLOB (const WCHAR []){'R','S','A','P','R','I','V','A','T','E','B','L','O','B',0}
|
||||
|
||||
#define MS_PRIMITIVE_PROVIDER (const WCHAR [])\
|
||||
{'M','i','c','r','o','s','o','f','t',' ','P','r','i','m','i','t','i','v','e',' ','P','r','o','v','i','d','e','r',0}
|
||||
@@ -72,6 +74,7 @@ typedef LONG NTSTATUS;
|
||||
#define BCRYPT_AES_ALGORITHM (const WCHAR []){'A','E','S',0}
|
||||
#define BCRYPT_MD5_ALGORITHM (const WCHAR []){'M','D','5',0}
|
||||
#define BCRYPT_RNG_ALGORITHM (const WCHAR []){'R','N','G',0}
|
||||
+#define BCRYPT_RSA_ALGORITHM (const WCHAR []){'R','S','A',0}
|
||||
#define BCRYPT_SHA1_ALGORITHM (const WCHAR []){'S','H','A','1',0}
|
||||
#define BCRYPT_SHA256_ALGORITHM (const WCHAR []){'S','H','A','2','5','6',0}
|
||||
#define BCRYPT_SHA384_ALGORITHM (const WCHAR []){'S','H','A','3','8','4',0}
|
||||
@@ -138,6 +141,20 @@ typedef struct _BCRYPT_ECCKEY_BLOB
|
||||
ULONG cbKey;
|
||||
} BCRYPT_ECCKEY_BLOB, *PBCRYPT_ECCKEY_BLOB;
|
||||
|
||||
+#define BCRYPT_RSAPUBLIC_MAGIC 0x31415352
|
||||
+#define BCRYPT_RSAPRIVATE_MAGIC 0x32415352
|
||||
+#define BCRYPT_RSAFULLPRIVATE_MAGIC 0x33415352
|
||||
+
|
||||
+typedef struct _BCRYPT_RSAKEY_BLOB
|
||||
+{
|
||||
+ ULONG Magic;
|
||||
+ ULONG BitLength;
|
||||
+ ULONG cbPublicExp;
|
||||
+ ULONG cbModulus;
|
||||
+ ULONG cbPrime1;
|
||||
+ ULONG cbPrime2;
|
||||
+} BCRYPT_RSAKEY_BLOB;
|
||||
+
|
||||
typedef struct _BCRYPT_PKCS1_PADDING_INFO
|
||||
{
|
||||
LPCWSTR pszAlgId;
|
||||
--
|
||||
2.14.1
|
||||
|
@ -0,0 +1,129 @@
|
||||
From 1ac61b565db2204b247603ee7ad1124ad79bf50f Mon Sep 17 00:00:00 2001
|
||||
From: Kimmo Myllyvirta <kimmo.myllyvirta@gmail.com>
|
||||
Date: Tue, 10 Oct 2017 16:41:09 +0300
|
||||
Subject: bcrypt/tests: Add simple test for RSA.
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Based on patch from Bernhard Übelacker.
|
||||
---
|
||||
dlls/bcrypt/tests/bcrypt.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 95 insertions(+)
|
||||
|
||||
diff --git a/dlls/bcrypt/tests/bcrypt.c b/dlls/bcrypt/tests/bcrypt.c
|
||||
index 73bd4d69a5b..56e3440b545 100644
|
||||
--- a/dlls/bcrypt/tests/bcrypt.c
|
||||
+++ b/dlls/bcrypt/tests/bcrypt.c
|
||||
@@ -1697,6 +1697,100 @@ static void test_ECDSA(void)
|
||||
pBCryptCloseAlgorithmProvider(alg, 0);
|
||||
}
|
||||
|
||||
+static UCHAR rsaPublicBlob[] =
|
||||
+{
|
||||
+ 0x52, 0x53, 0x41, 0x31, 0x00, 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0xad, 0x41, 0x09, 0xa2, 0x56,
|
||||
+ 0x3a, 0x7b, 0x75, 0x4b, 0x72, 0x9b, 0x28, 0x72, 0x3b, 0xae, 0x9f, 0xd8, 0xa8, 0x25, 0x4a, 0x4c,
|
||||
+ 0x19, 0xf5, 0xa6, 0xd0, 0x05, 0x1c, 0x59, 0x8f, 0xe3, 0xf3, 0x2d, 0x29, 0x47, 0xf8, 0x80, 0x25,
|
||||
+ 0x25, 0x21, 0x58, 0xc2, 0xac, 0xa1, 0x9e, 0x93, 0x8e, 0x82, 0x6d, 0xd7, 0xf3, 0xe7, 0x8f, 0x0b,
|
||||
+ 0xc0, 0x41, 0x85, 0x29, 0x3c, 0xf1, 0x0b, 0x2c, 0x5d, 0x49, 0xed, 0xb4, 0x30, 0x6e, 0x02, 0x15,
|
||||
+ 0x4b, 0x9a, 0x08, 0x0d, 0xe1, 0x6f, 0xa8, 0xd3, 0x12, 0xab, 0x66, 0x48, 0x4d, 0xd9, 0x28, 0x03,
|
||||
+ 0x6c, 0x9d, 0x44, 0x7a, 0xed, 0xc9, 0x43, 0x4f, 0x9d, 0x4e, 0x3c, 0x7d, 0x0e, 0xff, 0x07, 0x87,
|
||||
+ 0xeb, 0xca, 0xca, 0x65, 0x6d, 0xbe, 0xc5, 0x31, 0x8b, 0xcc, 0x7e, 0x0a, 0x71, 0x4a, 0x4d, 0x9d,
|
||||
+ 0x3d, 0xfd, 0x7a, 0x56, 0x32, 0x8a, 0x6c, 0x6d, 0x9d, 0x2a, 0xd9, 0x8e, 0x68, 0x89, 0x63, 0xc6,
|
||||
+ 0x4f, 0x24, 0xd1, 0x2a, 0x72, 0x69, 0x08, 0x77, 0xa0, 0x7f, 0xfe, 0xc6, 0x33, 0x8d, 0xb4, 0x7d,
|
||||
+ 0x73, 0x91, 0x13, 0x9c, 0x47, 0x53, 0x6a, 0x13, 0xdf, 0x19, 0xc7, 0xed, 0x48, 0x81, 0xed, 0xd8,
|
||||
+ 0x1f, 0x11, 0x11, 0xbb, 0x41, 0x15, 0x5b, 0xa4, 0xf5, 0xc9, 0x2b, 0x48, 0x5e, 0xd8, 0x4b, 0x52,
|
||||
+ 0x1f, 0xf7, 0x87, 0xf2, 0x68, 0x25, 0x28, 0x79, 0xee, 0x39, 0x41, 0xc9, 0x0e, 0xc8, 0xf9, 0xf2,
|
||||
+ 0xd8, 0x24, 0x09, 0xb4, 0xd4, 0xb7, 0x90, 0xba, 0x26, 0xe8, 0x1d, 0xb4, 0xd7, 0x09, 0x00, 0xc4,
|
||||
+ 0xa0, 0xb6, 0x14, 0xe8, 0x4c, 0x29, 0x60, 0x54, 0x2e, 0x01, 0xde, 0x54, 0x66, 0x40, 0x22, 0x50,
|
||||
+ 0x27, 0xf1, 0xe7, 0x62, 0xa9, 0x00, 0x5a, 0x61, 0x2e, 0xfa, 0xfe, 0x16, 0xd8, 0xe0, 0xe7, 0x66,
|
||||
+ 0x17, 0xda, 0xb8, 0x0c, 0xa6, 0x04, 0x8d, 0xf8, 0x21, 0x68, 0x39
|
||||
+};
|
||||
+
|
||||
+static UCHAR rsaHash[] =
|
||||
+{
|
||||
+ 0x96, 0x1f, 0xa6, 0x49, 0x58, 0x81, 0x8f, 0x76, 0x77, 0x07, 0x07, 0x27, 0x55, 0xd7, 0x01, 0x8d,
|
||||
+ 0xcd, 0x27, 0x8e, 0x94
|
||||
+};
|
||||
+
|
||||
+static UCHAR rsaSignature[] =
|
||||
+{
|
||||
+ 0xa8, 0x3a, 0x9d, 0xaf, 0x92, 0x94, 0xa4, 0x4d, 0x34, 0xba, 0x41, 0x0c, 0xc1, 0x23, 0x91, 0xc7,
|
||||
+ 0x91, 0xa8, 0xf8, 0xfc, 0x94, 0x87, 0x4d, 0x05, 0x85, 0x63, 0xe8, 0x7d, 0xea, 0x7f, 0x6b, 0x8d,
|
||||
+ 0xbb, 0x9a, 0xd4, 0x46, 0xa6, 0xc0, 0xd6, 0xdc, 0x91, 0xba, 0xd3, 0x1a, 0xbf, 0xf4, 0x52, 0xa0,
|
||||
+ 0xc7, 0x15, 0x87, 0xe9, 0x1e, 0x60, 0x49, 0x9c, 0xee, 0x5a, 0x9c, 0x6c, 0xbd, 0x7a, 0x3e, 0xc3,
|
||||
+ 0x48, 0xb3, 0xee, 0xca, 0x68, 0x40, 0x9b, 0xa1, 0x4c, 0x6e, 0x20, 0xd6, 0xca, 0x6c, 0x72, 0xaf,
|
||||
+ 0x2b, 0x6b, 0x62, 0x7c, 0x78, 0x06, 0x94, 0x4c, 0x02, 0xf3, 0x8d, 0x49, 0xe0, 0x11, 0xc4, 0x9b,
|
||||
+ 0x62, 0x5b, 0xc2, 0xfd, 0x68, 0xf4, 0x07, 0x15, 0x71, 0x11, 0x4c, 0x35, 0x97, 0x5d, 0xc0, 0xe6,
|
||||
+ 0x22, 0xc9, 0x8a, 0x7b, 0x96, 0xc9, 0xc3, 0xe4, 0x2b, 0x1e, 0x88, 0x17, 0x4f, 0x98, 0x9b, 0xf3,
|
||||
+ 0x42, 0x23, 0x0c, 0xa0, 0xfa, 0x19, 0x03, 0x2a, 0xf7, 0x13, 0x2d, 0x27, 0xac, 0x9f, 0xaf, 0x2d,
|
||||
+ 0xa3, 0xce, 0xf7, 0x63, 0xbb, 0x39, 0x9f, 0x72, 0x80, 0xdd, 0x6c, 0x73, 0x00, 0x85, 0x70, 0xf2,
|
||||
+ 0xed, 0x50, 0xed, 0xa0, 0x74, 0x42, 0xd7, 0x22, 0x46, 0x24, 0xee, 0x67, 0xdf, 0xb5, 0x45, 0xe8,
|
||||
+ 0x49, 0xf4, 0x9c, 0xe4, 0x00, 0x83, 0xf2, 0x27, 0x8e, 0xa2, 0xb1, 0xc3, 0xc2, 0x01, 0xd7, 0x59,
|
||||
+ 0x2e, 0x4d, 0xac, 0x49, 0xa2, 0xc1, 0x8d, 0x88, 0x4b, 0xfe, 0x28, 0xe5, 0xac, 0xa6, 0x85, 0xc4,
|
||||
+ 0x1f, 0xf8, 0xc5, 0xc5, 0x14, 0x4e, 0xa3, 0xcb, 0x17, 0xb7, 0x64, 0xb3, 0xc2, 0x12, 0xf8, 0xf8,
|
||||
+ 0x36, 0x99, 0x1c, 0x91, 0x9b, 0xbd, 0xed, 0x55, 0x0f, 0xfd, 0x49, 0x85, 0xbb, 0x32, 0xad, 0x78,
|
||||
+ 0xc1, 0x74, 0xe6, 0x7c, 0x18, 0x0f, 0x2b, 0x3b, 0xaa, 0xd1, 0x9d, 0x40, 0x71, 0x1d, 0x19, 0x53
|
||||
+};
|
||||
+
|
||||
+static void test_RSA(void)
|
||||
+{
|
||||
+ BCRYPT_PKCS1_PADDING_INFO pad;
|
||||
+ BCRYPT_ALG_HANDLE alg = NULL;
|
||||
+ BCRYPT_KEY_HANDLE key = NULL;
|
||||
+ NTSTATUS ret;
|
||||
+
|
||||
+ ret = pBCryptOpenAlgorithmProvider(&alg, BCRYPT_RSA_ALGORITHM, NULL, 0);
|
||||
+ if (ret)
|
||||
+ {
|
||||
+ win_skip("Failed to open RSA provider: %08x, skipping test\n", ret);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ ret = pBCryptImportKeyPair(alg, NULL, BCRYPT_RSAPUBLIC_BLOB, &key, rsaPublicBlob, sizeof(rsaPublicBlob), 0);
|
||||
+ ok(!ret, "pBCryptImportKeyPair failed: %08x\n", ret);
|
||||
+
|
||||
+ pad.pszAlgId = BCRYPT_SHA1_ALGORITHM;
|
||||
+ ret = pBCryptVerifySignature(key, &pad, rsaHash, sizeof(rsaHash), rsaSignature, sizeof(rsaSignature), BCRYPT_PAD_PKCS1);
|
||||
+ ok(!ret, "pBCryptVerifySignature failed: %08x\n", ret);
|
||||
+
|
||||
+ ret = pBCryptVerifySignature(key, NULL, rsaHash, sizeof(rsaHash), rsaSignature, sizeof(rsaSignature), BCRYPT_PAD_PKCS1);
|
||||
+ ok(ret == STATUS_INVALID_PARAMETER, "Expected STATUS_INVALID_PARAMETER, got %08x\n", ret);
|
||||
+
|
||||
+ pad.pszAlgId = BCRYPT_SHA1_ALGORITHM;
|
||||
+ ret = pBCryptVerifySignature(key, &pad, rsaHash, sizeof(rsaHash), rsaSignature, sizeof(rsaSignature), 0);
|
||||
+ ok(ret == STATUS_INVALID_PARAMETER, "Expected STATUS_INVALID_PARAMETER, got %08x\n", ret);
|
||||
+
|
||||
+ ret = pBCryptVerifySignature(key, NULL, rsaHash, sizeof(rsaHash), rsaSignature, sizeof(rsaSignature), 0);
|
||||
+ ok(ret == STATUS_INVALID_PARAMETER, "Expected STATUS_INVALID_PARAMETER, got %08x\n", ret);
|
||||
+
|
||||
+ pad.pszAlgId = BCRYPT_AES_ALGORITHM;
|
||||
+ ret = pBCryptVerifySignature(key, &pad, rsaHash, sizeof(rsaHash), rsaSignature, sizeof(rsaSignature), BCRYPT_PAD_PKCS1);
|
||||
+ ok(ret == STATUS_NOT_SUPPORTED, "Expected STATUS_NOT_SUPPORTED, got %08x\n", ret);
|
||||
+
|
||||
+ pad.pszAlgId = NULL;
|
||||
+ ret = pBCryptVerifySignature(key, &pad, rsaHash, sizeof(rsaHash), rsaSignature, sizeof(rsaSignature), BCRYPT_PAD_PKCS1);
|
||||
+ ok(ret == STATUS_INVALID_SIGNATURE, "Expected STATUS_INVALID_SIGNATURE, got %08x\n", ret);
|
||||
+
|
||||
+ ret = pBCryptDestroyKey(key);
|
||||
+ ok(!ret, "pBCryptDestroyKey failed: %08x\n", ret);
|
||||
+
|
||||
+ ret = pBCryptCloseAlgorithmProvider(alg, 0);
|
||||
+ ok(!ret, "pBCryptCloseAlgorithmProvider failed: %08x\n", ret);
|
||||
+}
|
||||
+
|
||||
START_TEST(bcrypt)
|
||||
{
|
||||
HMODULE module;
|
||||
@@ -1744,6 +1838,7 @@ START_TEST(bcrypt)
|
||||
test_BCryptDecrypt();
|
||||
test_key_import_export();
|
||||
test_ECDSA();
|
||||
+ test_RSA();
|
||||
|
||||
if (pBCryptHash) /* >= Win 10 */
|
||||
test_BcryptHash();
|
||||
--
|
||||
2.14.1
|
||||
|
@ -0,0 +1,49 @@
|
||||
From 3714e6bcd413355a60a691d38f487f321be93b2a Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Sat, 14 Oct 2017 22:44:13 +0200
|
||||
Subject: bcrypt: Store full ECCKEY_BLOB struct in BCryptImportKeyPair.
|
||||
|
||||
---
|
||||
dlls/bcrypt/bcrypt_main.c | 12 +++++++-----
|
||||
1 file changed, 7 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c
|
||||
index 3356364a6dc..2aecfb9a227 100644
|
||||
--- a/dlls/bcrypt/bcrypt_main.c
|
||||
+++ b/dlls/bcrypt/bcrypt_main.c
|
||||
@@ -1308,6 +1308,7 @@ static void buffer_append_asn1_r_s( struct buffer *buffer, BYTE *r, DWORD r_len,
|
||||
|
||||
static NTSTATUS import_gnutls_pubkey_ecc( struct key *key, gnutls_pubkey_t *gnutls_key )
|
||||
{
|
||||
+ BCRYPT_ECCKEY_BLOB *ecc_blob;
|
||||
gnutls_ecc_curve_t curve;
|
||||
gnutls_datum_t x, y;
|
||||
int ret;
|
||||
@@ -1328,10 +1329,11 @@ static NTSTATUS import_gnutls_pubkey_ecc( struct key *key, gnutls_pubkey_t *gnut
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
- x.data = key->u.a.pubkey;
|
||||
- x.size = key->u.a.pubkey_len / 2;
|
||||
- y.data = key->u.a.pubkey + x.size;
|
||||
- y.size = x.size;
|
||||
+ ecc_blob = (BCRYPT_ECCKEY_BLOB *)key->u.a.pubkey;
|
||||
+ x.data = key->u.a.pubkey + sizeof(*ecc_blob);
|
||||
+ x.size = ecc_blob->cbKey;
|
||||
+ y.data = key->u.a.pubkey + sizeof(*ecc_blob) + ecc_blob->cbKey;
|
||||
+ y.size = ecc_blob->cbKey;
|
||||
|
||||
if ((ret = pgnutls_pubkey_import_ecc_raw( *gnutls_key, curve, &x, &y )))
|
||||
{
|
||||
@@ -1846,7 +1848,7 @@ NTSTATUS WINAPI BCryptImportKeyPair( BCRYPT_ALG_HANDLE algorithm, BCRYPT_KEY_HAN
|
||||
return STATUS_NO_MEMORY;
|
||||
|
||||
key->hdr.magic = MAGIC_KEY;
|
||||
- if ((status = key_asymmetric_init( key, alg, (BYTE *)(ecc_blob + 1), ecc_blob->cbKey * 2 )))
|
||||
+ if ((status = key_asymmetric_init( key, alg, (BYTE *)ecc_blob, sizeof(*ecc_blob) + ecc_blob->cbKey * 2 )))
|
||||
{
|
||||
HeapFree( GetProcessHeap(), 0, key );
|
||||
return status;
|
||||
--
|
||||
2.14.1
|
||||
|
@ -1,3 +1,4 @@
|
||||
Fixes: [40418] Implement BCrypt AES provider
|
||||
Fixes: [42553] Implement BCrypt ECB chaining mode
|
||||
Fixes: [39582] Implement BCrypt RSA provider
|
||||
Fixes: Implement BCryptImportKey and BCryptExportKey
|
||||
|
@ -3575,6 +3575,7 @@ fi
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
# | * [#40418] Implement BCrypt AES provider
|
||||
# | * [#42553] Implement BCrypt ECB chaining mode
|
||||
# | * [#39582] Implement BCrypt RSA provider
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/bcrypt/bcrypt.spec, dlls/bcrypt/bcrypt_main.c, dlls/bcrypt/tests/bcrypt.c, dlls/ncrypt/ncrypt.spec,
|
||||
@ -3602,6 +3603,14 @@ if test "$enable_bcrypt_Improvements" -eq 1; then
|
||||
patch_apply bcrypt-Improvements/0027-bcrypt-Fix-BCryptEncrypt-with-AES_GCM-and-no-input-a.patch
|
||||
patch_apply bcrypt-Improvements/0028-bcrypt-Partial-implementation-of-BCryptImportKey-and.patch
|
||||
patch_apply bcrypt-Improvements/0029-bcrypt-Add-support-for-192-and-256-bit-aes-keys.patch
|
||||
patch_apply bcrypt-Improvements/0030-bcrypt-Preparation-for-asymmetric-keys.patch
|
||||
patch_apply bcrypt-Improvements/0031-include-Add-ecdsa-and-asymmetric-key-related-bcrypt-.patch
|
||||
patch_apply bcrypt-Improvements/0032-bcrypt-tests-Add-basic-test-for-ecdsa.patch
|
||||
patch_apply bcrypt-Improvements/0033-bcrypt-Implement-importing-of-ecdsa-keys.patch
|
||||
patch_apply bcrypt-Improvements/0034-bcrypt-Implement-BCryptVerifySignature-for-ecdsa-sig.patch
|
||||
patch_apply bcrypt-Improvements/0035-bcrypt-Initial-implementation-for-RSA-key-import-and.patch
|
||||
patch_apply bcrypt-Improvements/0036-bcrypt-tests-Add-simple-test-for-RSA.patch
|
||||
patch_apply bcrypt-Improvements/0037-bcrypt-Store-full-ECCKEY_BLOB-struct-in-BCryptImport.patch
|
||||
(
|
||||
printf '%s\n' '+ { "Hans Leidekker", "include: Add missing BCRYPT_CHAIN_MODE definitions.", 1 },';
|
||||
printf '%s\n' '+ { "Sebastian Lackner", "bcrypt/tests: Add test for bugs in BCryptGetProperty.", 1 },';
|
||||
@ -3624,6 +3633,14 @@ if test "$enable_bcrypt_Improvements" -eq 1; then
|
||||
printf '%s\n' '+ { "Andrew Wesie", "bcrypt: Fix BCryptEncrypt with AES_GCM and no input and no output.", 1 },';
|
||||
printf '%s\n' '+ { "Michael Müller", "bcrypt: Partial implementation of BCryptImportKey and BCryptExportKey.", 1 },';
|
||||
printf '%s\n' '+ { "Michael Müller", "bcrypt: Add support for 192 and 256 bit aes keys.", 1 },';
|
||||
printf '%s\n' '+ { "Michael Müller", "bcrypt: Preparation for asymmetric keys.", 1 },';
|
||||
printf '%s\n' '+ { "Michael Müller", "include: Add ecdsa and asymmetric key related bcrypt definitions.", 1 },';
|
||||
printf '%s\n' '+ { "Michael Müller", "bcrypt/tests: Add basic test for ecdsa.", 1 },';
|
||||
printf '%s\n' '+ { "Michael Müller", "bcrypt: Implement importing of ecdsa keys.", 1 },';
|
||||
printf '%s\n' '+ { "Michael Müller", "bcrypt: Implement BCryptVerifySignature for ecdsa signatures.", 1 },';
|
||||
printf '%s\n' '+ { "Kimmo Myllyvirta", "bcrypt: Initial implementation for RSA key import and signature verification.", 1 },';
|
||||
printf '%s\n' '+ { "Kimmo Myllyvirta", "bcrypt/tests: Add simple test for RSA.", 1 },';
|
||||
printf '%s\n' '+ { "Sebastian Lackner", "bcrypt: Store full ECCKEY_BLOB struct in BCryptImportKeyPair.", 1 },';
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
@ -3780,17 +3797,11 @@ fi
|
||||
# | * [#35902] Implement support for validating ECDSA certificate chains
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/bcrypt/bcrypt.spec, dlls/bcrypt/bcrypt_main.c, dlls/bcrypt/tests/bcrypt.c, dlls/crypt32/Makefile.in,
|
||||
# | dlls/crypt32/cert.c, dlls/crypt32/chain.c, dlls/crypt32/crypt32_private.h, dlls/crypt32/decode.c, dlls/crypt32/oid.c,
|
||||
# | dlls/crypt32/tests/chain.c, dlls/crypt32/tests/encode.c, dlls/crypt32/tests/oid.c, include/bcrypt.h, include/ntstatus.h,
|
||||
# | include/wincrypt.h
|
||||
# | * dlls/crypt32/Makefile.in, dlls/crypt32/cert.c, dlls/crypt32/chain.c, dlls/crypt32/crypt32_private.h,
|
||||
# | dlls/crypt32/decode.c, dlls/crypt32/oid.c, dlls/crypt32/tests/chain.c, dlls/crypt32/tests/encode.c,
|
||||
# | dlls/crypt32/tests/oid.c, include/wincrypt.h
|
||||
# |
|
||||
if test "$enable_crypt32_ECDSA_Cert_Chains" -eq 1; then
|
||||
patch_apply crypt32-ECDSA_Cert_Chains/0001-bcrypt-Preparation-for-asymmetric-keys.patch
|
||||
patch_apply crypt32-ECDSA_Cert_Chains/0002-include-Add-ecdsa-and-asymmetric-key-related-bcrypt-.patch
|
||||
patch_apply crypt32-ECDSA_Cert_Chains/0003-bcrypt-tests-Add-basic-test-for-ecdsa.patch
|
||||
patch_apply crypt32-ECDSA_Cert_Chains/0004-bcrypt-Implement-importing-of-ecdsa-keys.patch
|
||||
patch_apply crypt32-ECDSA_Cert_Chains/0005-bcrypt-Implement-BCryptVerifySignature-for-ecdsa-sig.patch
|
||||
patch_apply crypt32-ECDSA_Cert_Chains/0006-crypt32-tests-Basic-tests-for-decoding-ECDSA-signed-.patch
|
||||
patch_apply crypt32-ECDSA_Cert_Chains/0007-crypt32-Implement-decoding-of-X509_OBJECT_IDENTIFIER.patch
|
||||
patch_apply crypt32-ECDSA_Cert_Chains/0008-crypt32-Implement-decoding-of-X509_ECC_SIGNATURE.patch
|
||||
@ -3800,11 +3811,6 @@ if test "$enable_crypt32_ECDSA_Cert_Chains" -eq 1; then
|
||||
patch_apply crypt32-ECDSA_Cert_Chains/0012-crypt32-tets-Add-test-for-verifying-an-ecdsa-chain.patch
|
||||
patch_apply crypt32-ECDSA_Cert_Chains/0013-crypt32-Implement-verification-of-ECDSA-signatures.patch
|
||||
(
|
||||
printf '%s\n' '+ { "Michael Müller", "bcrypt: Preparation for asymmetric keys.", 1 },';
|
||||
printf '%s\n' '+ { "Michael Müller", "include: Add ecdsa and asymmetric key related bcrypt definitions.", 1 },';
|
||||
printf '%s\n' '+ { "Michael Müller", "bcrypt/tests: Add basic test for ecdsa.", 1 },';
|
||||
printf '%s\n' '+ { "Michael Müller", "bcrypt: Implement importing of ecdsa keys.", 1 },';
|
||||
printf '%s\n' '+ { "Michael Müller", "bcrypt: Implement BCryptVerifySignature for ecdsa signatures.", 1 },';
|
||||
printf '%s\n' '+ { "Michael Müller", "crypt32/tests: Basic tests for decoding ECDSA signed certificate.", 1 },';
|
||||
printf '%s\n' '+ { "Michael Müller", "crypt32: Implement decoding of X509_OBJECT_IDENTIFIER.", 1 },';
|
||||
printf '%s\n' '+ { "Michael Müller", "crypt32: Implement decoding of X509_ECC_SIGNATURE.", 1 },';
|
||||
|
Loading…
Reference in New Issue
Block a user