diff --git a/patches/bcrypt-BCryptDeriveKeyPBKDF2/0001-bcrypt-Implement-BCryptDeriveKeyPBKDF2-and-add-test-.patch b/patches/bcrypt-BCryptDeriveKeyPBKDF2/0001-bcrypt-Implement-BCryptDeriveKeyPBKDF2-and-add-test-.patch new file mode 100644 index 00000000..6ff3f1e0 --- /dev/null +++ b/patches/bcrypt-BCryptDeriveKeyPBKDF2/0001-bcrypt-Implement-BCryptDeriveKeyPBKDF2-and-add-test-.patch @@ -0,0 +1,346 @@ +From d850bbb2836fa4d77c7842009901382b54f29a69 Mon Sep 17 00:00:00 2001 +From: Jack Grigg +Date: Sat, 17 Mar 2018 21:14:05 +1100 +Subject: [PATCH] bcrypt: Implement BCryptDeriveKeyPBKDF2 and add test vectors. + +Fixes https://bugs.winehq.org/show_bug.cgi?id=42704 + +Tested on Ubuntu 16.04.2 LTS. + +v2 - Removed C++ comment + - Removed all warnings. + - Use heap_* functions + - Formatting changes. + +Signed-off-by: Jack Grigg +--- + dlls/bcrypt/bcrypt.spec | 1 + + dlls/bcrypt/bcrypt_main.c | 163 +++++++++++++++++++++++++++++++++++++++++++++ + dlls/bcrypt/tests/bcrypt.c | 85 +++++++++++++++++++++++ + include/bcrypt.h | 1 + + 4 files changed, 250 insertions(+) + +diff --git a/dlls/bcrypt/bcrypt.spec b/dlls/bcrypt/bcrypt.spec +index 78824d73b39..f4d9a57bb08 100644 +--- a/dlls/bcrypt/bcrypt.spec ++++ b/dlls/bcrypt/bcrypt.spec +@@ -8,6 +8,7 @@ + @ stdcall BCryptDecrypt(ptr ptr long ptr ptr long ptr long ptr long) + @ stub BCryptDeleteContext + @ stub BCryptDeriveKey ++@ stdcall BCryptDeriveKeyPBKDF2(ptr ptr long ptr long int64 ptr long long) + @ stdcall BCryptDestroyHash(ptr) + @ stdcall BCryptDestroyKey(ptr) + @ stub BCryptDestroySecret +diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c +index 1490089cf72..4ffab1a9cf9 100644 +--- a/dlls/bcrypt/bcrypt_main.c ++++ b/dlls/bcrypt/bcrypt_main.c +@@ -2282,6 +2282,169 @@ NTSTATUS WINAPI BCryptSetProperty( BCRYPT_HANDLE handle, const WCHAR *prop, UCHA + } + } + ++NTSTATUS PBKDF2_F( BCRYPT_ALG_HANDLE algorithm, ++ UCHAR *password, ULONG password_length, ++ UCHAR *salt, ULONG salt_length, ++ ULONGLONG iterations, int i, ++ UCHAR *res, int hash_length ) ++{ ++ BCRYPT_HASH_HANDLE handle; ++ NTSTATUS status = STATUS_NOT_SUPPORTED; ++ UCHAR bytes[4]; ++ UCHAR *tmp; ++ int j; ++ int k; ++ ++ if (!(tmp = heap_alloc( hash_length ))) ++ { ++ return STATUS_NO_MEMORY; ++ } ++ ++ for (j = 0; j < iterations; j++) ++ { ++ status = BCryptCreateHash( algorithm, &handle, NULL, 0, ++ password, password_length, 0 ); ++ if (status != STATUS_SUCCESS) ++ goto done; ++ ++ if (j == 0) ++ { ++ /* Use salt || INT(i) */ ++ status = BCryptHashData( handle, salt, salt_length, 0 ); ++ if (status != STATUS_SUCCESS) ++ goto done; ++ bytes[0] = (i >> 24) & 0xFF; ++ bytes[1] = (i >> 16) & 0xFF; ++ bytes[2] = (i >> 8) & 0xFF; ++ bytes[3] = i & 0xFF; ++ status = BCryptHashData( handle, bytes, 4, 0 ); ++ } ++ else ++ { ++ /* Use U_j */ ++ status = BCryptHashData( handle, tmp, hash_length, 0 ); ++ } ++ if (status != STATUS_SUCCESS) ++ goto done; ++ ++ status = BCryptFinishHash( handle, tmp, hash_length, 0 ); ++ if (status != STATUS_SUCCESS) ++ goto done; ++ ++ status = BCryptDestroyHash( handle ); ++ if (status != STATUS_SUCCESS) ++ goto done; ++ ++ handle = NULL; ++ ++ if (j == 0) ++ { ++ /* Copy into res */ ++ memcpy( res, tmp, hash_length ); ++ } ++ else ++ { ++ /* XOR into res */ ++ for (k = 0; k < hash_length; k++) ++ res[k] ^= tmp[k]; ++ } ++ } ++ ++done: ++ TRACE("<- status 0x%08x\n", status); ++ if(handle) ++ BCryptDestroyHash( handle ); ++ heap_free( tmp ); ++ return status; ++} ++ ++/************************************************************ ++ * BCryptDeriveKeyPBKDF2 (BCRYPT.@) ++ * ++ * Derive a key from a password using the PBKDF2 function ++ * (RFC 2898). ++ * ++ * PARAMS ++ * handle [I] Pointer to the PRF provider ++ * password [I] Optional pointer to the beginning of the password ++ * password_length [I] Length of the password ++ * salt [I] Optional pointer to the beginning of the salt ++ * salt_length [I] Length of the salt ++ * iterations [I] Iteration count ++ * dk [O] Pointer to the beginning of the buffer to store the ++ * derived key in, at least dklen in size ++ * dklen [I] Intended length of the derived key, at most ++ * (2^32 - 1) * (output length of PRF) ++ * flags [I] Reserved, must be zero ++ * ++ * RETURNS ++ * Success: STATUS_SUCCESS. ++ * Failure: - STATUS_INVALID_HANDLE ++ * - STATUS_INVALID_PARAMETER ++ * - STATUS_NO_MEMORY ++ */ ++NTSTATUS WINAPI BCryptDeriveKeyPBKDF2( BCRYPT_ALG_HANDLE handle, ++ PUCHAR password, ULONG password_length, ++ PUCHAR salt, ULONG salt_length, ++ ULONGLONG iterations, ++ PUCHAR dk, ULONG dklen, ++ ULONG flags ) ++{ ++ struct algorithm *alg = handle; ++ int hlen = alg_props[alg->id].hash_length; ++ UCHAR *partial; ++ NTSTATUS status; ++ int l; ++ int r; ++ int i; ++ ++ TRACE( "%p, %p, %u, %p, %u, %s, %p, %u, %08x - stub\n", ++ handle, password, password_length, salt, salt_length, ++ wine_dbgstr_longlong(iterations), dk, dklen, flags ); ++ ++ if (dklen <= 0 || dklen > ((((ULONGLONG) 1) << 32) - 1) * hlen) ++ { ++ return STATUS_INVALID_PARAMETER; ++ } ++ ++ l = 1 + ((dklen - 1) / hlen); /* ceil(dklen/hlen) */ ++ r = dklen - (l - 1) * hlen; ++ ++ /* Full blocks */ ++ for (i = 1; i < l; i++) ++ { ++ status = PBKDF2_F( handle, ++ password, password_length, ++ salt, salt_length, ++ iterations, i, ++ dk + ((i - 1) * hlen), hlen ); ++ if (status != STATUS_SUCCESS) ++ { ++ return status; ++ } ++ } ++ ++ /* Final partial block */ ++ if (!(partial = heap_alloc( hlen ))) ++ { ++ return STATUS_NO_MEMORY; ++ } ++ status = PBKDF2_F( handle, ++ password, password_length, ++ salt, salt_length, ++ iterations, l, ++ partial, hlen ); ++ if (status != STATUS_SUCCESS) ++ { ++ heap_free( partial ); ++ return status; ++ } ++ memcpy( dk + ((l - 1) * hlen), partial, r ); ++ heap_free( partial ); ++ ++ return STATUS_SUCCESS; ++} ++ + BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved ) + { + switch (reason) +diff --git a/dlls/bcrypt/tests/bcrypt.c b/dlls/bcrypt/tests/bcrypt.c +index 7d59f6d4c1d..5b1b6c7e189 100644 +--- a/dlls/bcrypt/tests/bcrypt.c ++++ b/dlls/bcrypt/tests/bcrypt.c +@@ -26,6 +26,8 @@ + + #include "wine/test.h" + ++#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) ++ + static NTSTATUS (WINAPI *pBCryptOpenAlgorithmProvider)(BCRYPT_ALG_HANDLE *, LPCWSTR, LPCWSTR, ULONG); + static NTSTATUS (WINAPI *pBCryptCloseAlgorithmProvider)(BCRYPT_ALG_HANDLE, ULONG); + static NTSTATUS (WINAPI *pBCryptGetFipsAlgorithmMode)(BOOLEAN *); +@@ -36,6 +38,8 @@ static NTSTATUS (WINAPI *pBCryptHashData)(BCRYPT_HASH_HANDLE, PUCHAR, ULONG, ULO + static NTSTATUS (WINAPI *pBCryptDuplicateHash)(BCRYPT_HASH_HANDLE, BCRYPT_HASH_HANDLE *, UCHAR *, ULONG, ULONG); + static NTSTATUS (WINAPI *pBCryptFinishHash)(BCRYPT_HASH_HANDLE, PUCHAR, ULONG, ULONG); + static NTSTATUS (WINAPI *pBCryptDestroyHash)(BCRYPT_HASH_HANDLE); ++static NTSTATUS (WINAPI *pBCryptDeriveKeyPBKDF2)(BCRYPT_ALG_HANDLE, PUCHAR, ULONG, PUCHAR, ULONG, ++ ULONGLONG, PUCHAR, ULONG, ULONG); + static NTSTATUS (WINAPI *pBCryptGenRandom)(BCRYPT_ALG_HANDLE, PUCHAR, ULONG, ULONG); + static NTSTATUS (WINAPI *pBCryptGetProperty)(BCRYPT_HANDLE, LPCWSTR, PUCHAR, ULONG, ULONG *, ULONG); + static NTSTATUS (WINAPI *pBCryptSetProperty)(BCRYPT_HANDLE, LPCWSTR, PUCHAR, ULONG, ULONG); +@@ -396,6 +400,81 @@ static void test_BcryptHash(void) + ok(ret == STATUS_SUCCESS, "got %08x\n", ret); + } + ++/* Test vectors from RFC 6070 */ ++static UCHAR password[] = "password"; ++static UCHAR salt[] = "salt"; ++static UCHAR long_password[] = ++ "passwordPASSWORDpassword"; ++static UCHAR long_salt[] = ++ "saltSALTsaltSALTsaltSALTsaltSALTsalt"; ++static UCHAR password_NUL[] = "pass\0word"; ++static UCHAR salt_NUL[] = "sa\0lt"; ++ ++static UCHAR dk1[] = ++ "0c60c80f961f0e71f3a9b524af6012062fe037a6"; ++static UCHAR dk2[] = ++ "ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957"; ++static UCHAR dk3[] = ++ "4b007901b765489abead49d926f721d065a429c1"; ++static UCHAR dk4[] = ++ "eefe3d61cd4da4e4e9945b3d6ba2158c2634e984"; ++static UCHAR dk5[] = ++ "3d2eec4fe41c849b80c8d83662c0e44a8b291a964cf2f07038"; ++static UCHAR dk6[] = ++ "56fa6aa75548099dcc37d7f03425e0c3"; ++ ++static const struct { ++ ULONG password_length; ++ ULONG salt_length; ++ ULONGLONG iterations; ++ ULONG dklen; ++ UCHAR *password; ++ UCHAR *salt; ++ const UCHAR *dk; ++} rfc6070[] = { ++ { 8, 4, 1, 20, password, salt, dk1 }, ++ { 8, 4, 2, 20, password, salt, dk2 }, ++ { 8, 4, 4096, 20, password, salt, dk3 }, ++ { 8, 4, 16777216, 20, password, salt, dk4 }, ++ { 24, 36, 4096, 25, long_password, long_salt, dk5 }, ++ { 9, 5, 4096, 16, password_NUL, salt_NUL, dk6 } ++}; ++ ++static void test_BcryptDeriveKeyPBKDF2(void) ++{ ++ BCRYPT_ALG_HANDLE alg; ++ UCHAR dk[25]; ++ char str[51]; ++ NTSTATUS ret; ++ int i; ++ ++ alg = NULL; ++ ret = pBCryptOpenAlgorithmProvider(&alg, BCRYPT_SHA1_ALGORITHM, MS_PRIMITIVE_PROVIDER, ++ BCRYPT_ALG_HANDLE_HMAC_FLAG); ++ ok(ret == STATUS_SUCCESS, "got %08x\n", ret); ++ ok(alg != NULL, "alg not set\n"); ++ ++ test_hash_length(alg, 20); ++ test_alg_name(alg, "SHA1"); ++ ++ for (i = 0; i < ARRAY_SIZE(rfc6070); i++) ++ { ++ memset(dk, 0, sizeof(dk)); ++ ret = pBCryptDeriveKeyPBKDF2(alg, ++ rfc6070[i].password, rfc6070[i].password_length, ++ rfc6070[i].salt, rfc6070[i].salt_length, ++ rfc6070[i].iterations, ++ dk, rfc6070[i].dklen, ++ 0); ++ ok(ret == STATUS_SUCCESS, "got %08x\n", ret); ++ format_hash( dk, rfc6070[i].dklen, str ); ++ ok(!memcmp(str, rfc6070[i].dk, rfc6070[i].dklen), "got %s\n", str); ++ } ++ ++ ret = pBCryptCloseAlgorithmProvider(alg, 0); ++ ok(ret == STATUS_SUCCESS, "got %08x\n", ret); ++} ++ + static void test_rng(void) + { + BCRYPT_ALG_HANDLE alg; +@@ -1609,6 +1688,7 @@ START_TEST(bcrypt) + pBCryptDuplicateHash = (void *)GetProcAddress(module, "BCryptDuplicateHash"); + pBCryptFinishHash = (void *)GetProcAddress(module, "BCryptFinishHash"); + pBCryptDestroyHash = (void *)GetProcAddress(module, "BCryptDestroyHash"); ++ pBCryptDeriveKeyPBKDF2 = (void *)GetProcAddress(module, "BCryptDeriveKeyPBKDF2"); + pBCryptGenRandom = (void *)GetProcAddress(module, "BCryptGenRandom"); + pBCryptGetProperty = (void *)GetProcAddress(module, "BCryptGetProperty"); + pBCryptSetProperty = (void *)GetProcAddress(module, "BCryptSetProperty"); +@@ -1639,5 +1719,10 @@ START_TEST(bcrypt) + else + win_skip("BCryptHash is not available\n"); + ++ if (pBCryptDeriveKeyPBKDF2) /* >= Win 7 */ ++ test_BcryptDeriveKeyPBKDF2(); ++ else ++ win_skip("BCryptDeriveKeyPBKDF2 is not available\n"); ++ + FreeLibrary(module); + } +diff --git a/include/bcrypt.h b/include/bcrypt.h +index df54f621fa7..d3e4b9959dc 100644 +--- a/include/bcrypt.h ++++ b/include/bcrypt.h +@@ -217,6 +217,7 @@ typedef PVOID BCRYPT_HASH_HANDLE; + NTSTATUS WINAPI BCryptCloseAlgorithmProvider(BCRYPT_ALG_HANDLE, ULONG); + NTSTATUS WINAPI BCryptCreateHash(BCRYPT_ALG_HANDLE, BCRYPT_HASH_HANDLE *, PUCHAR, ULONG, PUCHAR, ULONG, ULONG); + NTSTATUS WINAPI BCryptDecrypt(BCRYPT_KEY_HANDLE, PUCHAR, ULONG, VOID *, PUCHAR, ULONG, PUCHAR, ULONG, ULONG *, ULONG); ++NTSTATUS WINAPI BCryptDeriveKeyPBKDF2(BCRYPT_ALG_HANDLE, PUCHAR, ULONG, PUCHAR, ULONG, ULONGLONG, PUCHAR, ULONG, ULONG); + NTSTATUS WINAPI BCryptDestroyHash(BCRYPT_HASH_HANDLE); + NTSTATUS WINAPI BCryptDestroyKey(BCRYPT_KEY_HANDLE); + NTSTATUS WINAPI BCryptEncrypt(BCRYPT_KEY_HANDLE, PUCHAR, ULONG, VOID *, PUCHAR, ULONG, PUCHAR, ULONG, ULONG *, ULONG); +-- +2.16.2 + diff --git a/patches/bcrypt-BCryptDeriveKeyPBKDF2/definition b/patches/bcrypt-BCryptDeriveKeyPBKDF2/definition new file mode 100644 index 00000000..161b7ba6 --- /dev/null +++ b/patches/bcrypt-BCryptDeriveKeyPBKDF2/definition @@ -0,0 +1,2 @@ +Fixes: [42704] Implement BCryptDeriveKeyPBKDF2 +Depends: crypt32-ECDSA_Cert_Chains diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index f5b22aa1..3f8989f7 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -98,6 +98,7 @@ patch_enable_all () enable_api_ms_win_Stub_DLLs="$1" enable_avifil32_IGetFrame_fnSetFormat="$1" enable_avifile_dll16_AVIStreamGetFrame="$1" + enable_bcrypt_BCryptDeriveKeyPBKDF2="$1" enable_browseui_Progress_Dialog="$1" enable_combase_RoApi="$1" enable_comctl32_Listview_DrawItem="$1" @@ -491,6 +492,9 @@ patch_enable () avifile.dll16-AVIStreamGetFrame) enable_avifile_dll16_AVIStreamGetFrame="$2" ;; + bcrypt-BCryptDeriveKeyPBKDF2) + enable_bcrypt_BCryptDeriveKeyPBKDF2="$2" + ;; browseui-Progress_Dialog) enable_browseui_Progress_Dialog="$2" ;; @@ -2399,6 +2403,13 @@ if test "$enable_d3d11_Deferred_Context" -eq 1; then enable_d3d11_ID3D11Texture1D_Rebased=1 fi +if test "$enable_bcrypt_BCryptDeriveKeyPBKDF2" -eq 1; then + if test "$enable_crypt32_ECDSA_Cert_Chains" -gt 1; then + abort "Patchset crypt32-ECDSA_Cert_Chains disabled, but bcrypt-BCryptDeriveKeyPBKDF2 depends on that." + fi + enable_crypt32_ECDSA_Cert_Chains=1 +fi + if test "$enable_api_ms_win_Stub_DLLs" -eq 1; then if test "$enable_combase_RoApi" -gt 1; then abort "Patchset combase-RoApi disabled, but api-ms-win-Stub_DLLs depends on that." @@ -2890,6 +2901,55 @@ if test "$enable_avifile_dll16_AVIStreamGetFrame" -eq 1; then ) >> "$patchlist" fi +# Patchset crypt32-ECDSA_Cert_Chains +# | +# | This patchset fixes the following Wine bugs: +# | * [#35902] Implement support for validating ECDSA certificate chains +# | +# | Modified files: +# | * 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/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 + patch_apply crypt32-ECDSA_Cert_Chains/0009-crypt32-tests-Add-basic-test-for-ecdsa-oid.patch + patch_apply crypt32-ECDSA_Cert_Chains/0010-crypt32-Add-oids-for-sha256ECDSA-and-sha384ECDSA.patch + patch_apply crypt32-ECDSA_Cert_Chains/0011-crypt32-Correctly-return-how-the-issuer-of-a-self-si.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: Implement decoding of X509_OBJECT_IDENTIFIER.", 1 },'; + printf '%s\n' '+ { "Michael Müller", "crypt32: Implement decoding of X509_ECC_SIGNATURE.", 1 },'; + printf '%s\n' '+ { "Michael Müller", "crypt32/tests: Add basic test for ecdsa oid.", 1 },'; + printf '%s\n' '+ { "Michael Müller", "crypt32: Add oids for sha256ECDSA and sha384ECDSA.", 1 },'; + printf '%s\n' '+ { "Michael Müller", "crypt32: Correctly return how the issuer of a self signed certificate was checked.", 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 + +# Patchset bcrypt-BCryptDeriveKeyPBKDF2 +# | +# | This patchset has the following (direct or indirect) dependencies: +# | * crypt32-ECDSA_Cert_Chains +# | +# | This patchset fixes the following Wine bugs: +# | * [#42704] Implement BCryptDeriveKeyPBKDF2 +# | +# | Modified files: +# | * dlls/bcrypt/bcrypt.spec, dlls/bcrypt/bcrypt_main.c, dlls/bcrypt/tests/bcrypt.c, include/bcrypt.h +# | +if test "$enable_bcrypt_BCryptDeriveKeyPBKDF2" -eq 1; then + patch_apply bcrypt-BCryptDeriveKeyPBKDF2/0001-bcrypt-Implement-BCryptDeriveKeyPBKDF2-and-add-test-.patch + ( + printf '%s\n' '+ { "Jack Grigg", "bcrypt: Implement BCryptDeriveKeyPBKDF2 and add test vectors.", 1 },'; + ) >> "$patchlist" +fi + # Patchset browseui-Progress_Dialog # | # | Modified files: @@ -2992,37 +3052,6 @@ if test "$enable_crypt32_CryptUnprotectMemory" -eq 1; then ) >> "$patchlist" fi -# Patchset crypt32-ECDSA_Cert_Chains -# | -# | This patchset fixes the following Wine bugs: -# | * [#35902] Implement support for validating ECDSA certificate chains -# | -# | Modified files: -# | * 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/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 - patch_apply crypt32-ECDSA_Cert_Chains/0009-crypt32-tests-Add-basic-test-for-ecdsa-oid.patch - patch_apply crypt32-ECDSA_Cert_Chains/0010-crypt32-Add-oids-for-sha256ECDSA-and-sha384ECDSA.patch - patch_apply crypt32-ECDSA_Cert_Chains/0011-crypt32-Correctly-return-how-the-issuer-of-a-self-si.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: Implement decoding of X509_OBJECT_IDENTIFIER.", 1 },'; - printf '%s\n' '+ { "Michael Müller", "crypt32: Implement decoding of X509_ECC_SIGNATURE.", 1 },'; - printf '%s\n' '+ { "Michael Müller", "crypt32/tests: Add basic test for ecdsa oid.", 1 },'; - printf '%s\n' '+ { "Michael Müller", "crypt32: Add oids for sha256ECDSA and sha384ECDSA.", 1 },'; - printf '%s\n' '+ { "Michael Müller", "crypt32: Correctly return how the issuer of a self signed certificate was checked.", 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 - # Patchset crypt32-MS_Root_Certs # | # | Modified files: