Rebase against 85f1a79be8bbb9b62ad88e0d0fbf1e005fd3ba16

This commit is contained in:
Alistair Leslie-Hughes 2018-06-27 08:20:14 +10:00
parent 2bf4df0d11
commit 59948639b6
3 changed files with 16 additions and 401 deletions

View File

@ -1,384 +0,0 @@
From 2da87110b4a7637cada56e5e188f2d6ccafc97e4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Sat, 30 Sep 2017 03:10:08 +0200
Subject: crypt32: Implement verification of ECDSA signatures.
---
dlls/crypt32/Makefile.in | 2 +-
dlls/crypt32/cert.c | 292 ++++++++++++++++++++++++++++++++++++++++++---
dlls/crypt32/tests/chain.c | 4 +-
3 files changed, 280 insertions(+), 18 deletions(-)
diff --git a/dlls/crypt32/Makefile.in b/dlls/crypt32/Makefile.in
index d3a409fcae6..09342221192 100644
--- a/dlls/crypt32/Makefile.in
+++ b/dlls/crypt32/Makefile.in
@@ -1,7 +1,7 @@
EXTRADEFS = -D_CRYPT32_
MODULE = crypt32.dll
IMPORTLIB = crypt32
-IMPORTS = user32 advapi32
+IMPORTS = user32 advapi32 bcrypt
DELAYIMPORTS = cryptnet
EXTRALIBS = $(SECURITY_LIBS)
diff --git a/dlls/crypt32/cert.c b/dlls/crypt32/cert.c
index 0cfa46788f3..d2aa182ff6e 100644
--- a/dlls/crypt32/cert.c
+++ b/dlls/crypt32/cert.c
@@ -21,9 +21,14 @@
#include <stdarg.h>
#define NONAMELESSUNION
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
#include "windef.h"
#include "winbase.h"
+#include "winternl.h"
+#define CRYPT_OID_INFO_HAS_EXTRA_FIELDS
#include "wincrypt.h"
+#include "bcrypt.h"
#include "winnls.h"
#include "rpc.h"
#include "wine/debug.h"
@@ -2409,36 +2414,29 @@ BOOL WINAPI CryptVerifyCertificateSignature(HCRYPTPROV_LEGACY hCryptProv,
CRYPT_VERIFY_CERT_SIGN_ISSUER_PUBKEY, pPublicKey, 0, NULL);
}
-static BOOL CRYPT_VerifyCertSignatureFromPublicKeyInfo(HCRYPTPROV_LEGACY hCryptProv,
- DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pubKeyInfo,
- const CERT_SIGNED_CONTENT_INFO *signedCert)
+static BOOL verify_signature_crypt(HCRYPTPROV_LEGACY hCryptProv,
+ DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pubKeyInfo,
+ const CERT_SIGNED_CONTENT_INFO *signedCert, PCCRYPT_OID_INFO info)
{
- BOOL ret;
- HCRYPTKEY key;
- PCCRYPT_OID_INFO info;
ALG_ID pubKeyID, hashID;
+ HCRYPTHASH hash;
+ HCRYPTKEY key;
+ BOOL ret;
- info = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY,
- signedCert->SignatureAlgorithm.pszObjId, 0);
- if (!info || info->dwGroupId != CRYPT_SIGN_ALG_OID_GROUP_ID)
- {
- SetLastError(NTE_BAD_ALGID);
- return FALSE;
- }
hashID = info->u.Algid;
if (info->ExtraInfo.cbData >= sizeof(ALG_ID))
pubKeyID = *(ALG_ID *)info->ExtraInfo.pbData;
else
pubKeyID = hashID;
+
/* Load the default provider if necessary */
if (!hCryptProv)
hCryptProv = CRYPT_GetDefaultProvider();
+
ret = CryptImportPublicKeyInfoEx(hCryptProv, dwCertEncodingType,
pubKeyInfo, pubKeyID, 0, NULL, &key);
if (ret)
{
- HCRYPTHASH hash;
-
ret = CryptCreateHash(hCryptProv, hashID, 0, 0, &hash);
if (ret)
{
@@ -2454,6 +2452,270 @@ static BOOL CRYPT_VerifyCertSignatureFromPublicKeyInfo(HCRYPTPROV_LEGACY hCryptP
return ret;
}
+static BOOL calculate_hash_bcrypt(const WCHAR *algorithm,
+ const CERT_SIGNED_CONTENT_INFO *signedCert, BYTE **hash_value, DWORD *hash_len)
+{
+ BCRYPT_HASH_HANDLE hash = NULL;
+ BCRYPT_ALG_HANDLE alg = NULL;
+ NTSTATUS status;
+ DWORD size;
+ BOOL ret = FALSE;
+
+ if ((status = BCryptOpenAlgorithmProvider(&alg, algorithm, NULL, 0)))
+ goto done;
+
+ if ((status = BCryptCreateHash(alg, &hash, NULL, 0, NULL, 0, 0)))
+ goto done;
+
+ if ((status = BCryptHashData(hash, signedCert->ToBeSigned.pbData, signedCert->ToBeSigned.cbData, 0)))
+ goto done;
+
+ if ((status = BCryptGetProperty(hash, BCRYPT_HASH_LENGTH, (BYTE *)hash_len, sizeof(*hash_len), &size, 0)))
+ goto done;
+
+ if (!(*hash_value = CryptMemAlloc(*hash_len)))
+ {
+ status = STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ if ((status = BCryptFinishHash(hash, *hash_value, *hash_len, 0)))
+ {
+ CryptMemFree(*hash_value);
+ goto done;
+ }
+
+ ret = TRUE;
+
+done:
+ if (hash) BCryptDestroyHash(hash);
+ if (alg) BCryptCloseAlgorithmProvider(alg, 0);
+ if (status) SetLastError(RtlNtStatusToDosError(status));
+ return ret;
+}
+
+static BOOL import_bcrypt_pubkey_ecc(PCERT_PUBLIC_KEY_INFO pubKeyInfo, BCRYPT_KEY_HANDLE *key)
+{
+ DWORD blob_magic, ecckey_len, size;
+ NTSTATUS status = STATUS_SUCCESS;
+ BCRYPT_ECCKEY_BLOB *ecckey;
+ const WCHAR *sign_algo;
+ BCRYPT_ALG_HANDLE alg;
+ LPSTR *ecc_curve;
+
+ if (!pubKeyInfo->PublicKey.cbData)
+ {
+ SetLastError(NTE_BAD_ALGID);
+ return FALSE;
+ }
+
+ if (pubKeyInfo->PublicKey.pbData[0] != 0x4)
+ {
+ FIXME("Compressed ECC curves (%02x) not yet supported\n", pubKeyInfo->PublicKey.pbData[0]);
+ SetLastError(NTE_BAD_ALGID);
+ return FALSE;
+ }
+
+ if (!CryptDecodeObjectEx(X509_ASN_ENCODING, X509_OBJECT_IDENTIFIER,
+ pubKeyInfo->Algorithm.Parameters.pbData,
+ pubKeyInfo->Algorithm.Parameters.cbData,
+ CRYPT_DECODE_ALLOC_FLAG, NULL, &ecc_curve, &size))
+ return FALSE;
+
+ if (!strcmp(*ecc_curve, szOID_ECC_CURVE_P256))
+ {
+ sign_algo = BCRYPT_ECDSA_P256_ALGORITHM;
+ blob_magic = BCRYPT_ECDSA_PUBLIC_P256_MAGIC;
+ }
+ else if(!strcmp(*ecc_curve, szOID_ECC_CURVE_P384))
+ {
+ sign_algo = BCRYPT_ECDSA_P384_ALGORITHM;
+ blob_magic = BCRYPT_ECDSA_PUBLIC_P384_MAGIC;
+ }
+ else
+ {
+ FIXME("Unsupported ecc curve type: %s\n", *ecc_curve);
+ sign_algo = NULL;
+ blob_magic = 0;
+ }
+ LocalFree(ecc_curve);
+
+ if (!sign_algo)
+ {
+ SetLastError(NTE_BAD_ALGID);
+ return FALSE;
+ }
+
+ if ((status = BCryptOpenAlgorithmProvider(&alg, sign_algo, NULL, 0)))
+ {
+ SetLastError(RtlNtStatusToDosError(status));
+ return FALSE;
+ }
+
+ ecckey_len = sizeof(BCRYPT_ECCKEY_BLOB) + pubKeyInfo->PublicKey.cbData - 1;
+ if (!(ecckey = CryptMemAlloc(ecckey_len)))
+ {
+ BCryptCloseAlgorithmProvider(alg, 0);
+ SetLastError(ERROR_OUTOFMEMORY);
+ return FALSE;
+ }
+
+ ecckey->dwMagic = blob_magic;
+ ecckey->cbKey = (pubKeyInfo->PublicKey.cbData - 1) / 2;
+ memcpy(ecckey + 1, pubKeyInfo->PublicKey.pbData + 1, pubKeyInfo->PublicKey.cbData - 1);
+
+ status = BCryptImportKeyPair(alg, NULL, BCRYPT_ECCPUBLIC_BLOB, key, (BYTE*)ecckey, ecckey_len, 0);
+ BCryptCloseAlgorithmProvider(alg, 0);
+ if (status)
+ {
+ SetLastError(RtlNtStatusToDosError(status));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static BOOL import_bcrypt_pubkey(PCERT_PUBLIC_KEY_INFO pubKeyInfo, BCRYPT_KEY_HANDLE *key)
+{
+ if (!strcmp(pubKeyInfo->Algorithm.pszObjId, szOID_ECC_PUBLIC_KEY))
+ return import_bcrypt_pubkey_ecc(pubKeyInfo, key);
+
+ FIXME("Unsupported public key type: %s\n", debugstr_a(pubKeyInfo->Algorithm.pszObjId));
+ SetLastError(NTE_BAD_ALGID);
+ return FALSE;
+}
+
+static BOOL prepare_bcrypt_signature_ecc(BYTE *encoded_sig, DWORD encoded_size,
+ BYTE **sig_value, DWORD *sig_len)
+{
+ CERT_ECC_SIGNATURE *ecc_sig;
+ DWORD size;
+ int i;
+
+ if (!CryptDecodeObjectEx(X509_ASN_ENCODING, X509_ECC_SIGNATURE,
+ encoded_sig, encoded_size,
+ CRYPT_DECODE_ALLOC_FLAG, NULL, &ecc_sig, &size))
+ return FALSE;
+
+ if (!ecc_sig->r.cbData || !ecc_sig->s.cbData)
+ {
+ LocalFree(ecc_sig);
+ SetLastError(ERROR_INVALID_DATA);
+ return FALSE;
+ }
+
+ *sig_len = ecc_sig->r.cbData + ecc_sig->s.cbData;
+ if (!(*sig_value = CryptMemAlloc(*sig_len)))
+ {
+ LocalFree(ecc_sig);
+ SetLastError(ERROR_OUTOFMEMORY);
+ return FALSE;
+ }
+
+ for (i = 0; i < ecc_sig->r.cbData; i++)
+ (*sig_value)[i] = ecc_sig->r.pbData[ecc_sig->r.cbData - i - 1];
+ for (i = 0; i < ecc_sig->s.cbData; i++)
+ (*sig_value)[ecc_sig->r.cbData + i] = ecc_sig->s.pbData[ecc_sig->s.cbData - i - 1];
+
+ LocalFree(ecc_sig);
+ return TRUE;
+}
+
+static BOOL prepare_bcrypt_signature(PCERT_PUBLIC_KEY_INFO pubKeyInfo,
+ const CERT_SIGNED_CONTENT_INFO *signedCert, BYTE **sig_value, DWORD *sig_len)
+{
+ BYTE *encoded_sig;
+ BOOL ret = FALSE;
+ int i;
+
+ if (!signedCert->Signature.cbData)
+ {
+ SetLastError(ERROR_INVALID_DATA);
+ return FALSE;
+ }
+
+ if (!(encoded_sig = CryptMemAlloc(signedCert->Signature.cbData)))
+ {
+ SetLastError(ERROR_OUTOFMEMORY);
+ return FALSE;
+ }
+
+ for (i = 0; i < signedCert->Signature.cbData; i++)
+ encoded_sig[i] = signedCert->Signature.pbData[signedCert->Signature.cbData - i - 1];
+
+ if (!strcmp(pubKeyInfo->Algorithm.pszObjId, szOID_ECC_PUBLIC_KEY))
+ ret = prepare_bcrypt_signature_ecc(encoded_sig, signedCert->Signature.cbData, sig_value, sig_len);
+ else
+ {
+ FIXME("Unsupported public key type: %s\n", debugstr_a(pubKeyInfo->Algorithm.pszObjId));
+ SetLastError(NTE_BAD_ALGID);
+ }
+
+ CryptMemFree(encoded_sig);
+ return ret;
+}
+
+static BOOL verify_signature_bcrypt(HCRYPTPROV_LEGACY hCryptProv,
+ DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pubKeyInfo,
+ const CERT_SIGNED_CONTENT_INFO *signedCert, PCCRYPT_OID_INFO info)
+{
+ BCRYPT_KEY_HANDLE key = NULL;
+ BYTE *hash_value, *sig_value;
+ DWORD hash_len, sig_len;
+ NTSTATUS status;
+
+ if (!calculate_hash_bcrypt(info->pwszCNGAlgid, signedCert, &hash_value, &hash_len))
+ return FALSE;
+
+ if (!import_bcrypt_pubkey(pubKeyInfo, &key))
+ {
+ CryptMemFree(hash_value);
+ return FALSE;
+ }
+
+ if (!prepare_bcrypt_signature(pubKeyInfo, signedCert, &sig_value, &sig_len))
+ {
+ CryptMemFree(hash_value);
+ BCryptDestroyKey(key);
+ return FALSE;
+ }
+
+ status = BCryptVerifySignature(key, NULL, hash_value, hash_len, sig_value, sig_len, 0);
+
+ BCryptDestroyKey(key);
+ CryptMemFree(hash_value);
+ CryptMemFree(sig_value);
+
+ if (status)
+ {
+ FIXME("Failed to verify signature: %08x\n", status);
+ SetLastError(RtlNtStatusToDosError(status));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static BOOL CRYPT_VerifyCertSignatureFromPublicKeyInfo(HCRYPTPROV_LEGACY hCryptProv,
+ DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pubKeyInfo,
+ const CERT_SIGNED_CONTENT_INFO *signedCert)
+{
+ PCCRYPT_OID_INFO info;
+
+ info = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY,
+ signedCert->SignatureAlgorithm.pszObjId, 0);
+ if (!info || info->dwGroupId != CRYPT_SIGN_ALG_OID_GROUP_ID)
+ {
+ SetLastError(NTE_BAD_ALGID);
+ return FALSE;
+ }
+
+ if (info->u.Algid == CALG_OID_INFO_CNG_ONLY)
+ return verify_signature_bcrypt(hCryptProv, dwCertEncodingType, pubKeyInfo, signedCert, info);
+ else
+ return verify_signature_crypt(hCryptProv, dwCertEncodingType, pubKeyInfo, signedCert, info);
+}
+
BOOL WINAPI CryptVerifyCertificateSignatureEx(HCRYPTPROV_LEGACY hCryptProv,
DWORD dwCertEncodingType, DWORD dwSubjectType, void *pvSubject,
DWORD dwIssuerType, void *pvIssuer, DWORD dwFlags, void *pvReserved)
diff --git a/dlls/crypt32/tests/chain.c b/dlls/crypt32/tests/chain.c
index 1279735e496..e3b280b0884 100644
--- a/dlls/crypt32/tests/chain.c
+++ b/dlls/crypt32/tests/chain.c
@@ -3945,7 +3945,7 @@ static ChainCheck chainCheckECDSA = {
{ CERT_TRUST_IS_UNTRUSTED_ROOT, CERT_TRUST_HAS_PREFERRED_ISSUER },
{ CERT_TRUST_IS_UNTRUSTED_ROOT, 0 },
1, simpleStatusECDSA
- }, TODO_ERROR
+ }, 0
};
#define test_name_blob(a,b) _test_name_blob(__LINE__,a,b)
@@ -4226,7 +4226,7 @@ static void testGetCertChain(void)
chain = getChain(NULL, &chainCheckECDSA.certs, 0, TRUE, &nov2017, FALSE, 0);
if (chain)
{
- todo_wine ok(chain->TrustStatus.dwErrorStatus == CERT_TRUST_IS_UNTRUSTED_ROOT,
+ ok(chain->TrustStatus.dwErrorStatus == CERT_TRUST_IS_UNTRUSTED_ROOT,
"unexpected chain error status %08x\n", chain->TrustStatus.dwErrorStatus);
checkChainStatus(chain, &chainCheckECDSA.status, chainCheckECDSA.todo, "chainCheckECDSA", 0);
pCertFreeCertificateChain(chain);
--
2.14.1

View File

@ -1,16 +1,17 @@
From 342951349469b7a84f3226d02f04ca5401982273 Mon Sep 17 00:00:00 2001
From 51ba80615215fac54b251e56a374dfab9a2b834b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Sat, 15 Aug 2015 02:59:17 +0200
Subject: dxdiagn: Enumerate DirectSound devices and add some basic properties.
Subject: [PATCH] dxdiagn: Enumerate DirectSound devices and add some basic
properties.
---
dlls/dxdiagn/Makefile.in | 2 +-
dlls/dxdiagn/provider.c | 91 ++++++++++++++++++++++++++
dlls/dxdiagn/tests/container.c | 141 +++++++++++++++++++++++++++++++++++++++++
dlls/dxdiagn/provider.c | 91 +++++++++++++++++++++
dlls/dxdiagn/tests/container.c | 141 +++++++++++++++++++++++++++++++++
3 files changed, 233 insertions(+), 1 deletion(-)
diff --git a/dlls/dxdiagn/Makefile.in b/dlls/dxdiagn/Makefile.in
index 3a1017e9d0a..87f6177aadf 100644
index c16396e464b..e926d3b2a8a 100644
--- a/dlls/dxdiagn/Makefile.in
+++ b/dlls/dxdiagn/Makefile.in
@@ -1,5 +1,5 @@
@ -21,18 +22,18 @@ index 3a1017e9d0a..87f6177aadf 100644
C_SRCS = \
container.c \
diff --git a/dlls/dxdiagn/provider.c b/dlls/dxdiagn/provider.c
index 5665d01d5b8..20998bc9aba 100644
index 1fdab5e2db0..6fb9e585dbd 100644
--- a/dlls/dxdiagn/provider.c
+++ b/dlls/dxdiagn/provider.c
@@ -38,6 +38,7 @@
#include "fil_data.h"
#include "wine/fil_data.h"
#include "psapi.h"
#include "wbemcli.h"
+#include "dsound.h"
#include "wine/debug.h"
@@ -1195,11 +1196,85 @@ static HRESULT build_displaydevices_tree(IDxDiagContainerImpl_Container *node)
@@ -1354,11 +1355,85 @@ static HRESULT build_displaydevices_tree(IDxDiagContainerImpl_Container *node)
return fill_display_information_fallback(node);
}
@ -118,7 +119,7 @@ index 5665d01d5b8..20998bc9aba 100644
IDxDiagContainerImpl_Container *cont;
cont = allocate_information_node(DxDiag_SoundDevices);
@@ -1208,12 +1283,28 @@ static HRESULT build_directsound_tree(IDxDiagContainerImpl_Container *node)
@@ -1367,12 +1442,28 @@ static HRESULT build_directsound_tree(IDxDiagContainerImpl_Container *node)
add_subcontainer(node, cont);
@ -148,7 +149,7 @@ index 5665d01d5b8..20998bc9aba 100644
}
diff --git a/dlls/dxdiagn/tests/container.c b/dlls/dxdiagn/tests/container.c
index 5bc5161635a..2ffe0fb685b 100644
index 936707632a4..c80717cd392 100644
--- a/dlls/dxdiagn/tests/container.c
+++ b/dlls/dxdiagn/tests/container.c
@@ -36,6 +36,11 @@ static IDxDiagContainer *pddc;
@ -163,7 +164,7 @@ index 5bc5161635a..2ffe0fb685b 100644
/* Based on debugstr_variant in dlls/jscript/jsutils.c. */
static const char *debugstr_variant(const VARIANT *var)
@@ -1020,6 +1025,140 @@ cleanup:
@@ -1022,6 +1027,140 @@ cleanup:
IDxDiagProvider_Release(pddp);
}
@ -304,7 +305,7 @@ index 5bc5161635a..2ffe0fb685b 100644
START_TEST(container)
{
CoInitialize(NULL);
@@ -1034,5 +1173,7 @@ START_TEST(container)
@@ -1036,5 +1175,7 @@ START_TEST(container)
test_root_children();
test_DxDiag_SystemInfo();
test_DxDiag_DisplayDevices();
@ -313,5 +314,5 @@ index 5bc5161635a..2ffe0fb685b 100644
CoUninitialize();
}
--
2.11.0
2.18.0

View File

@ -52,7 +52,7 @@ usage()
# Get the upstream commit sha
upstream_commit()
{
echo "6d801377055911d914226a3c6af8d8637a63fa13"
echo "85f1a79be8bbb9b62ad88e0d0fbf1e005fd3ba16"
}
# Show version information
@ -2738,16 +2738,14 @@ fi
# | * [#35902] Implement support for validating ECDSA certificate chains
# |
# | Modified files:
# | * dlls/crypt32/Makefile.in, dlls/crypt32/cert.c, dlls/crypt32/tests/chain.c, dlls/crypt32/tests/encode.c
# | * dlls/crypt32/tests/chain.c, dlls/crypt32/tests/encode.c
# |
if test "$enable_crypt32_ECDSA_Cert_Chains" -eq 1; then
patch_apply crypt32-ECDSA_Cert_Chains/0006-crypt32-tests-Basic-tests-for-decoding-ECDSA-signed-.patch
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", "crypt32/tests: Basic tests for decoding ECDSA signed certificate.", 1 },';
printf '%s\n' '+ { "Michael Müller", "crypt32/tets: Add test for verifying an ecdsa chain.", 1 },';
printf '%s\n' '+ { "Michael Müller", "crypt32: Implement verification of ECDSA signatures.", 1 },';
) >> "$patchlist"
fi