Hans Leidekker : bcrypt: Add support for importing legacy DSA public keys.
Alexandre Julliard
julliard at winehq.org
Tue Oct 6 15:33:11 CDT 2020
Module: wine
Branch: master
Commit: f79ca651aeff14a7f4e3443410a89441569ea080
URL: https://source.winehq.org/git/wine.git/?a=commit;h=f79ca651aeff14a7f4e3443410a89441569ea080
Author: Hans Leidekker <hans at codeweavers.com>
Date: Tue Oct 6 12:27:14 2020 +0200
bcrypt: Add support for importing legacy DSA public keys.
This is not supported on native but it will be useful to implement public key
import in dssenh.
Signed-off-by: Hans Leidekker <hans at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/bcrypt/bcrypt_main.c | 28 +++++++++++++++++++++++++
dlls/bcrypt/gnutls.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 80 insertions(+), 1 deletion(-)
diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c
index bc6ec69918..a91f31e9f0 100644
--- a/dlls/bcrypt/bcrypt_main.c
+++ b/dlls/bcrypt/bcrypt_main.c
@@ -1329,6 +1329,34 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP
*ret_key = key;
return STATUS_SUCCESS;
}
+ else if (!wcscmp( type, LEGACY_DSA_V2_PUBLIC_BLOB )) /* not supported on native */
+ {
+ BLOBHEADER *hdr = (BLOBHEADER *)input;
+ DSSPUBKEY *pubkey;
+ ULONG size;
+
+ if (alg->id != ALG_ID_DSA) return STATUS_NOT_SUPPORTED;
+ if (input_len < sizeof(*hdr)) return STATUS_INVALID_PARAMETER;
+
+ if (hdr->bType != PUBLICKEYBLOB && hdr->bVersion != 2 && hdr->aiKeyAlg != CALG_DSS_SIGN)
+ {
+ FIXME( "blob type %u version %u alg id %u not supported\n", hdr->bType, hdr->bVersion, hdr->aiKeyAlg );
+ return STATUS_NOT_SUPPORTED;
+ }
+
+ if (input_len < sizeof(*hdr) + sizeof(*pubkey)) return STATUS_INVALID_PARAMETER;
+ pubkey = (DSSPUBKEY *)(hdr + 1);
+ if (pubkey->magic != MAGIC_DSS1) return STATUS_NOT_SUPPORTED;
+
+ size = sizeof(*hdr) + sizeof(*pubkey) + (pubkey->bitlen / 8) * 3 + 20 + sizeof(DSSSEED);
+ if (input_len < size) return STATUS_INVALID_PARAMETER;
+
+ if ((status = key_asymmetric_create( &key, alg, pubkey->bitlen, (BYTE *)hdr, size ))) return status;
+ key->u.a.flags |= KEY_FLAG_LEGACY_DSA_V2;
+
+ *ret_key = key;
+ return STATUS_SUCCESS;
+ }
FIXME( "unsupported key type %s\n", debugstr_w(type) );
return STATUS_NOT_SUPPORTED;
diff --git a/dlls/bcrypt/gnutls.c b/dlls/bcrypt/gnutls.c
index 2d80b74aac..94e375cc8c 100644
--- a/dlls/bcrypt/gnutls.c
+++ b/dlls/bcrypt/gnutls.c
@@ -1336,6 +1336,54 @@ static NTSTATUS import_gnutls_pubkey_dsa( struct key *key, gnutls_pubkey_t *gnut
return STATUS_SUCCESS;
}
+static NTSTATUS import_gnutls_pubkey_dsa_capi( struct key *key, gnutls_pubkey_t *gnutls_key )
+{
+ BLOBHEADER *hdr;
+ DSSPUBKEY *pubkey;
+ gnutls_datum_t p, q, g, y;
+ unsigned char *data, p_data[128], q_data[20], g_data[128], y_data[128];
+ int i, ret, size;
+
+ if ((ret = pgnutls_pubkey_init( gnutls_key )))
+ {
+ pgnutls_perror( ret );
+ return STATUS_INTERNAL_ERROR;
+ }
+
+ hdr = (BLOBHEADER *)key->u.a.pubkey;
+ pubkey = (DSSPUBKEY *)(hdr + 1);
+ size = pubkey->bitlen / 8;
+ data = (unsigned char *)(pubkey + 1);
+
+ p.data = p_data;
+ p.size = size;
+ for (i = 0; i < p.size; i++) p.data[i] = data[p.size - i - 1];
+ data += p.size;
+
+ q.data = q_data;
+ q.size = sizeof(q_data);
+ for (i = 0; i < q.size; i++) q.data[i] = data[q.size - i - 1];
+ data += q.size;
+
+ g.data = g_data;
+ g.size = size;
+ for (i = 0; i < g.size; i++) g.data[i] = data[g.size - i - 1];
+ data += g.size;
+
+ y.data = y_data;
+ y.size = sizeof(y_data);
+ for (i = 0; i < y.size; i++) y.data[i] = data[y.size - i - 1];
+
+ if ((ret = pgnutls_pubkey_import_dsa_raw( *gnutls_key, &p, &q, &g, &y )))
+ {
+ 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)
@@ -1349,7 +1397,10 @@ static NTSTATUS import_gnutls_pubkey( struct key *key, gnutls_pubkey_t *gnutls_k
return import_gnutls_pubkey_rsa( key, gnutls_key );
case ALG_ID_DSA:
- return import_gnutls_pubkey_dsa( key, gnutls_key );
+ if (key->u.a.flags & KEY_FLAG_LEGACY_DSA_V2)
+ return import_gnutls_pubkey_dsa_capi( key, gnutls_key );
+ else
+ return import_gnutls_pubkey_dsa( key, gnutls_key );
default:
FIXME("algorithm %u not yet supported\n", key->alg_id );
More information about the wine-cvs
mailing list