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