Nikolay Sivov : bcrypt: Implement RSA key pair importing.
Alexandre Julliard
julliard at winehq.org
Thu Dec 3 15:35:58 CST 2020
Module: wine
Branch: master
Commit: 21839185d9d8a2db8bea33c5a70bf9e273916b35
URL: https://source.winehq.org/git/wine.git/?a=commit;h=21839185d9d8a2db8bea33c5a70bf9e273916b35
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Thu Dec 3 09:02:35 2020 +0300
bcrypt: Implement RSA key pair importing.
Requires libgnutls 3.7.0, that contains fixes for optional arguments handling
in gnutls_privkey_import_rsa_raw() to support BCRYPT_RSAPRIVATE_BLOB.
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Hans Leidekker <hans at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/bcrypt/bcrypt_internal.h | 1 +
dlls/bcrypt/bcrypt_main.c | 21 +++++++++++++++++++++
dlls/bcrypt/gnutls.c | 36 +++++++++++++++++++++++++++++++++++-
dlls/bcrypt/macos.c | 9 ++++++++-
4 files changed, 65 insertions(+), 2 deletions(-)
diff --git a/dlls/bcrypt/bcrypt_internal.h b/dlls/bcrypt/bcrypt_internal.h
index d5a54aad92b..e1777ed130b 100644
--- a/dlls/bcrypt/bcrypt_internal.h
+++ b/dlls/bcrypt/bcrypt_internal.h
@@ -214,6 +214,7 @@ struct key_funcs
NTSTATUS (CDECL *key_export_ecc)( struct key *, UCHAR *, ULONG, ULONG * );
NTSTATUS (CDECL *key_import_dsa_capi)( struct key *, UCHAR *, ULONG );
NTSTATUS (CDECL *key_import_ecc)( struct key *, UCHAR *, ULONG );
+ NTSTATUS (CDECL *key_import_rsa)( struct key *, UCHAR *, ULONG );
};
#endif /* __BCRYPT_INTERNAL_H */
diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c
index 1b7881d4910..591c01c710c 100644
--- a/dlls/bcrypt/bcrypt_main.c
+++ b/dlls/bcrypt/bcrypt_main.c
@@ -1331,6 +1331,27 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP
size = sizeof(*rsa_blob) + rsa_blob->cbPublicExp + rsa_blob->cbModulus;
return key_asymmetric_create( (struct key **)ret_key, alg, rsa_blob->BitLength, (BYTE *)rsa_blob, size );
}
+ else if (!wcscmp( type, BCRYPT_RSAPRIVATE_BLOB ))
+ {
+ BCRYPT_RSAKEY_BLOB *rsa_blob = (BCRYPT_RSAKEY_BLOB *)input;
+ ULONG size;
+
+ if (input_len < sizeof(*rsa_blob)) return STATUS_INVALID_PARAMETER;
+ if (alg->id != ALG_ID_RSA || rsa_blob->Magic != BCRYPT_RSAPRIVATE_MAGIC)
+ return STATUS_NOT_SUPPORTED;
+
+ size = sizeof(*rsa_blob) + rsa_blob->cbPublicExp + rsa_blob->cbModulus;
+ if ((status = key_asymmetric_create( &key, alg, rsa_blob->BitLength, (BYTE *)rsa_blob, size )))
+ return status;
+ if ((status = key_funcs->key_import_rsa( key, input, input_len )))
+ {
+ BCryptDestroyKey( key );
+ return status;
+ }
+
+ *ret_key = key;
+ return STATUS_SUCCESS;
+ }
else if (!wcscmp( type, BCRYPT_DSA_PUBLIC_BLOB ))
{
BCRYPT_DSA_KEY_BLOB *dsa_blob = (BCRYPT_DSA_KEY_BLOB *)input;
diff --git a/dlls/bcrypt/gnutls.c b/dlls/bcrypt/gnutls.c
index 41df88ca8f6..162ac9ea732 100644
--- a/dlls/bcrypt/gnutls.c
+++ b/dlls/bcrypt/gnutls.c
@@ -1119,6 +1119,39 @@ static NTSTATUS CDECL key_import_ecc( struct key *key, UCHAR *buf, ULONG len )
return STATUS_SUCCESS;
}
+static NTSTATUS CDECL key_import_rsa( struct key *key, UCHAR *buf, ULONG len )
+{
+ BCRYPT_RSAKEY_BLOB *rsa_blob = (BCRYPT_RSAKEY_BLOB *)buf;
+ gnutls_datum_t m, e, p, q;
+ gnutls_privkey_t handle;
+ int ret;
+
+ if ((ret = pgnutls_privkey_init( &handle )))
+ {
+ pgnutls_perror( ret );
+ return STATUS_INTERNAL_ERROR;
+ }
+
+ e.data = (unsigned char *)(rsa_blob + 1);
+ e.size = rsa_blob->cbPublicExp;
+ m.data = e.data + e.size;
+ m.size = rsa_blob->cbModulus;
+ p.data = m.data + m.size;
+ p.size = rsa_blob->cbPrime1;
+ q.data = p.data + p.size;
+ q.size = rsa_blob->cbPrime2;
+
+ if ((ret = pgnutls_privkey_import_rsa_raw( handle, &m, &e, NULL, &p, &q, NULL, NULL, NULL )))
+ {
+ pgnutls_perror( ret );
+ pgnutls_privkey_deinit( handle );
+ return STATUS_INTERNAL_ERROR;
+ }
+
+ key_data(key)->privkey = handle;
+ return STATUS_SUCCESS;
+}
+
static NTSTATUS CDECL key_export_dsa_capi( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
{
BLOBHEADER *hdr;
@@ -1869,7 +1902,8 @@ static const struct key_funcs key_funcs =
key_export_dsa_capi,
key_export_ecc,
key_import_dsa_capi,
- key_import_ecc
+ key_import_ecc,
+ key_import_rsa
};
NTSTATUS CDECL __wine_init_unix_lib( HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out )
diff --git a/dlls/bcrypt/macos.c b/dlls/bcrypt/macos.c
index d8bba46ad5c..57edc3e262b 100644
--- a/dlls/bcrypt/macos.c
+++ b/dlls/bcrypt/macos.c
@@ -249,6 +249,12 @@ static NTSTATUS CDECL key_import_ecc( struct key *key, UCHAR *input, ULONG len )
return STATUS_NOT_IMPLEMENTED;
}
+static NTSTATUS CDECL key_import_rsa( struct key *key, UCHAR *input, ULONG len )
+{
+ FIXME( "not implemented on Mac\n" );
+ return STATUS_NOT_IMPLEMENTED;
+}
+
static NTSTATUS CDECL key_asymmetric_generate( struct key *key )
{
FIXME( "not implemented on Mac\n" );
@@ -284,7 +290,8 @@ static const struct key_funcs key_funcs =
key_export_dsa_capi,
key_export_ecc,
key_import_dsa_capi,
- key_import_ecc
+ key_import_ecc,
+ key_import_rsa
};
NTSTATUS CDECL __wine_init_unix_lib( HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out )
More information about the wine-cvs
mailing list