2008-12-12 00:21:13 +01:00
|
|
|
/*
|
|
|
|
* Unit test suite for crypt32.dll's Crypt*Object functions
|
|
|
|
*
|
|
|
|
* Copyright 2008 Juan Lang
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdarg.h>
|
|
|
|
#include <windef.h>
|
|
|
|
#include <winbase.h>
|
|
|
|
#include <winerror.h>
|
|
|
|
#include <wincrypt.h>
|
|
|
|
|
|
|
|
#include "wine/test.h"
|
|
|
|
|
2009-01-12 12:46:08 +01:00
|
|
|
static BOOL (WINAPI * pCryptQueryObject)(DWORD, const void *, DWORD, DWORD,
|
|
|
|
DWORD, DWORD *, DWORD *, DWORD *, HCERTSTORE *, HCRYPTMSG *, const void **);
|
|
|
|
|
2008-12-12 00:21:13 +01:00
|
|
|
static BYTE bigCert[] = {
|
|
|
|
0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,
|
|
|
|
0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
|
|
|
|
0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,
|
|
|
|
0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,
|
|
|
|
0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
|
|
|
|
0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,
|
|
|
|
0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
|
|
|
|
0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x07,0x30,0x02,0x06,
|
|
|
|
0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,
|
|
|
|
0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
|
|
|
|
0xff,0x02,0x01,0x01 };
|
|
|
|
static char bigCertBase64[] =
|
|
|
|
"MHoCAQEwAgYAMBUxEzARBgNVBAMTCkp1YW4gTGFuZwAwIhgPMTYwMTAxMDEwMDAw\n"
|
|
|
|
"MDBaGA8xNjAxMDEwMTAwMDAwMFowFTETMBEGA1UEAxMKSnVhbiBMYW5nADAHMAIG\n"
|
|
|
|
"AAMBAKMWMBQwEgYDVR0TAQH/BAgwBgEB/wIBAQ==\n";
|
2022-03-31 11:06:03 +02:00
|
|
|
static WCHAR bigCertBase64W[] =
|
|
|
|
L"MHoCAQEwAgYAMBUxEzARBgNVBAMTCkp1YW4gTGFuZwAwIhgPMTYwMTAxMDEw,DAw\n"
|
|
|
|
"MDBaGA8xNjAxMDEwMTAwMDAwMFowFTETMBEGA1UEAxMKSnVhbiBMYW5nADAHMAIG\n"
|
|
|
|
"AAMBAKMWMBQwEgYDVR0TAQH/BAgwBgEB/wIBAQ==\n";
|
2008-12-12 00:21:13 +01:00
|
|
|
static BYTE signedWithCertWithValidPubKeyContent[] = {
|
|
|
|
0x30,0x82,0x01,0x89,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
|
|
|
|
0xa0,0x82,0x01,0x7a,0x30,0x82,0x01,0x76,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
|
|
|
|
0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,
|
|
|
|
0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,
|
|
|
|
0x02,0x03,0x04,0xa0,0x81,0xd2,0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,
|
|
|
|
0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
|
|
|
|
0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
|
|
|
|
0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,
|
|
|
|
0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
|
|
|
|
0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
|
|
|
|
0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,
|
|
|
|
0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,
|
|
|
|
0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,
|
|
|
|
0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,
|
|
|
|
0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,
|
|
|
|
0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,
|
|
|
|
0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,
|
|
|
|
0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,
|
|
|
|
0x01,0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,
|
|
|
|
0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
|
|
|
|
0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,
|
|
|
|
0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
|
|
|
|
0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,
|
|
|
|
0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,
|
|
|
|
0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,
|
|
|
|
0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,
|
|
|
|
0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
|
|
|
|
static char signedWithCertWithValidPubKeyContentBase64[] =
|
|
|
|
"MIIBiQYJKoZIhvcNAQcCoIIBejCCAXYCAQExDjAMBggqhkiG9w0CBQUAMBMGCSqG"
|
|
|
|
"SIb3DQEHAaAGBAQBAgMEoIHSMIHPAgEBMAIGADAVMRMwEQYDVQQDEwpKdWFuIExh"
|
|
|
|
"bmcAMCIYDzE2MDEwMTAxMDAwMDAwWhgPMTYwMTAxMDEwMDAwMDBaMBUxEzARBgNV"
|
|
|
|
"BAMTCkp1YW4gTGFuZwAwXDANBgkqhkiG9w0BAQEFAANLADBIAkEA4lQ6p4OxJxQ+"
|
|
|
|
"Wbu0U+Yf513xIWithVPbax7rZZcDhmDe82w4deBMYbu8YhepzXk/IU6Wyw7cYZQw"
|
|
|
|
"GBBr0BwQeQIDAQABoxYwFDASBgNVHRMBAf8ECDAGAQH/AgEBMXcwdQIBATAaMBUx"
|
|
|
|
"EzARBgNVBAMTCkp1YW4gTGFuZwACAQEwDAYIKoZIhvcNAgUFADAEBgAFAARAgaZw"
|
|
|
|
"s+9Z0WbRm8CatppebW9tDVmpqm7pLKAe7sJgvFm+P2MGjckRHSNkku8u/FcppK/g"
|
|
|
|
"7pMZOVHkRLgLKPSoDQ==";
|
2022-03-31 11:06:03 +02:00
|
|
|
static WCHAR signedWithCertWithValidPubKeyContentBase64W[] =
|
|
|
|
L"MIIBiQYJKoZIhvcNAQcCoIIBejCCAXYCAQExDjAMBggqhkiG9w0CBQUAMBMGCSqG"
|
|
|
|
"SIb3DQEHAaAGBAQBAgMEoIHSMIHPAgEBMAIGADAVMRMwEQYDVQQDEwpKdWFuIExh"
|
|
|
|
"bmcAMCIYDzE2MDEwMTAxMDAwMDAwWhgPMTYwMTAxMDEwMDAwMDBaMBUxEzARBgNV"
|
|
|
|
"BAMTCkp1YW4gTGFuZwAwXDANBgkqhkiG9w0BAQEFAANLADBIAkEA4lQ6p4OxJxQ+"
|
|
|
|
"Wbu0U+Yf513xIWithVPbax7rZZcDhmDe82w4deBMYbu8YhepzXk/IU6Wyw7cYZQw"
|
|
|
|
"GBBr0BwQeQIDAQABoxYwFDASBgNVHRMBAf8ECDAGAQH/AgEBMXcwdQIBATAaMBUx"
|
|
|
|
"EzARBgNVBAMTCkp1YW4gTGFuZwACAQEwDAYIKoZIhvcNAgUFADAEBgAFAARAgaZw"
|
|
|
|
"s+9Z0WbRm8CatppebW9tDVmpqm7pLKAe7sJgvFm+P2MGjckRHSNkku8u/FcppK/g"
|
|
|
|
"7pMZOVHkRLgLKPSoDQ==";
|
2008-12-12 00:21:13 +01:00
|
|
|
|
|
|
|
static void test_query_object(void)
|
|
|
|
{
|
|
|
|
BOOL ret;
|
|
|
|
CRYPT_DATA_BLOB blob;
|
|
|
|
|
|
|
|
/* Test the usual invalid arguments */
|
|
|
|
SetLastError(0xdeadbeef);
|
2009-01-12 12:46:08 +01:00
|
|
|
ret = pCryptQueryObject(0, NULL, 0, 0, 0, NULL, NULL, NULL, NULL, NULL,
|
2008-12-12 00:21:13 +01:00
|
|
|
NULL);
|
|
|
|
ok(!ret && GetLastError() == E_INVALIDARG,
|
2022-02-23 09:12:05 +01:00
|
|
|
"expected E_INVALIDARG, got %08lx\n", GetLastError());
|
2008-12-12 00:21:13 +01:00
|
|
|
SetLastError(0xdeadbeef);
|
2009-01-12 12:46:08 +01:00
|
|
|
ret = pCryptQueryObject(CERT_QUERY_OBJECT_BLOB, NULL, 0, 0, 0, NULL, NULL,
|
2008-12-12 00:21:13 +01:00
|
|
|
NULL, NULL, NULL, NULL);
|
|
|
|
ok(!ret && GetLastError() == E_INVALIDARG,
|
2022-02-23 09:12:05 +01:00
|
|
|
"expected E_INVALIDARG, got %08lx\n", GetLastError());
|
2008-12-12 00:21:13 +01:00
|
|
|
/* Test with a simple cert */
|
|
|
|
blob.pbData = bigCert;
|
|
|
|
blob.cbData = sizeof(bigCert);
|
|
|
|
SetLastError(0xdeadbeef);
|
2009-01-12 12:46:08 +01:00
|
|
|
ret = pCryptQueryObject(CERT_QUERY_OBJECT_BLOB, &blob,
|
2008-12-12 00:21:13 +01:00
|
|
|
CERT_QUERY_CONTENT_FLAG_ALL, CERT_QUERY_FORMAT_FLAG_ALL, 0, NULL, NULL,
|
|
|
|
NULL, NULL, NULL, NULL);
|
2022-02-23 09:12:05 +01:00
|
|
|
ok(ret, "CryptQueryObject failed: %08lx\n", GetLastError());
|
2008-12-12 00:21:13 +01:00
|
|
|
/* The same cert, base64-encoded */
|
|
|
|
blob.pbData = (BYTE *)bigCertBase64;
|
|
|
|
blob.cbData = sizeof(bigCertBase64);
|
|
|
|
SetLastError(0xdeadbeef);
|
2009-01-12 12:46:08 +01:00
|
|
|
ret = pCryptQueryObject(CERT_QUERY_OBJECT_BLOB, &blob,
|
2008-12-12 00:21:13 +01:00
|
|
|
CERT_QUERY_CONTENT_FLAG_ALL, CERT_QUERY_FORMAT_FLAG_ALL, 0, NULL, NULL,
|
|
|
|
NULL, NULL, NULL, NULL);
|
2022-02-23 09:12:05 +01:00
|
|
|
ok(ret, "CryptQueryObject failed: %08lx\n", GetLastError());
|
2008-12-12 00:21:13 +01:00
|
|
|
/* The same base64-encoded cert, restricting the format types */
|
|
|
|
SetLastError(0xdeadbeef);
|
2009-01-12 12:46:08 +01:00
|
|
|
ret = pCryptQueryObject(CERT_QUERY_OBJECT_BLOB, &blob,
|
2008-12-12 00:21:13 +01:00
|
|
|
CERT_QUERY_CONTENT_FLAG_ALL, CERT_QUERY_FORMAT_FLAG_BINARY, 0, NULL, NULL,
|
|
|
|
NULL, NULL, NULL, NULL);
|
|
|
|
ok(!ret && GetLastError() == CRYPT_E_NO_MATCH,
|
2022-02-23 09:12:05 +01:00
|
|
|
"expected CRYPT_E_NO_MATCH, got %08lx\n", GetLastError());
|
2008-12-12 00:21:13 +01:00
|
|
|
SetLastError(0xdeadbeef);
|
2009-01-12 12:46:08 +01:00
|
|
|
ret = pCryptQueryObject(CERT_QUERY_OBJECT_BLOB, &blob,
|
2008-12-12 00:21:13 +01:00
|
|
|
CERT_QUERY_CONTENT_FLAG_ALL, CERT_QUERY_FORMAT_FLAG_BASE64_ENCODED, 0,
|
|
|
|
NULL, NULL, NULL, NULL, NULL, NULL);
|
2022-02-23 09:12:05 +01:00
|
|
|
ok(ret, "CryptQueryObject failed: %08lx\n", GetLastError());
|
2008-12-12 00:21:13 +01:00
|
|
|
/* The same cert, base64-encoded but as a wide character string */
|
|
|
|
blob.pbData = (BYTE *)bigCertBase64W;
|
|
|
|
blob.cbData = sizeof(bigCertBase64W);
|
|
|
|
SetLastError(0xdeadbeef);
|
2009-01-12 12:46:08 +01:00
|
|
|
ret = pCryptQueryObject(CERT_QUERY_OBJECT_BLOB, &blob,
|
2008-12-12 00:21:13 +01:00
|
|
|
CERT_QUERY_CONTENT_FLAG_ALL, CERT_QUERY_FORMAT_FLAG_ALL, 0, NULL, NULL,
|
|
|
|
NULL, NULL, NULL, NULL);
|
|
|
|
ok(!ret && GetLastError() == CRYPT_E_NO_MATCH,
|
2022-02-23 09:12:05 +01:00
|
|
|
"expected CRYPT_E_NO_MATCH, got %08lx\n", GetLastError());
|
2008-12-12 00:21:13 +01:00
|
|
|
/* For brevity, not tested here, but tested on Windows: same failure
|
|
|
|
* (CRYPT_E_NO_MATCH) when the wide character base64-encoded cert
|
|
|
|
* is written to a file and queried.
|
|
|
|
*/
|
|
|
|
/* Test with a valid signed message */
|
|
|
|
blob.pbData = signedWithCertWithValidPubKeyContent;
|
|
|
|
blob.cbData = sizeof(signedWithCertWithValidPubKeyContent);
|
|
|
|
SetLastError(0xdeadbeef);
|
2009-01-12 12:46:08 +01:00
|
|
|
ret = pCryptQueryObject(CERT_QUERY_OBJECT_BLOB, &blob,
|
2008-12-12 00:21:13 +01:00
|
|
|
CERT_QUERY_CONTENT_FLAG_ALL, CERT_QUERY_FORMAT_FLAG_ALL, 0, NULL, NULL,
|
|
|
|
NULL, NULL, NULL, NULL);
|
2022-02-23 09:12:05 +01:00
|
|
|
ok(ret, "CryptQueryObject failed: %08lx\n", GetLastError());
|
2008-12-12 00:21:13 +01:00
|
|
|
blob.pbData = (BYTE *)signedWithCertWithValidPubKeyContentBase64;
|
|
|
|
blob.cbData = sizeof(signedWithCertWithValidPubKeyContentBase64);
|
|
|
|
SetLastError(0xdeadbeef);
|
2009-01-12 12:46:08 +01:00
|
|
|
ret = pCryptQueryObject(CERT_QUERY_OBJECT_BLOB, &blob,
|
2008-12-12 00:21:13 +01:00
|
|
|
CERT_QUERY_CONTENT_FLAG_ALL, CERT_QUERY_FORMAT_FLAG_ALL, 0, NULL, NULL,
|
|
|
|
NULL, NULL, NULL, NULL);
|
2022-02-23 09:12:05 +01:00
|
|
|
ok(ret, "CryptQueryObject failed: %08lx\n", GetLastError());
|
2008-12-12 00:21:13 +01:00
|
|
|
/* A valid signed message, encoded as a wide character base64 string, can
|
|
|
|
* be queried successfully.
|
|
|
|
*/
|
|
|
|
blob.pbData = (BYTE *)signedWithCertWithValidPubKeyContentBase64W;
|
|
|
|
blob.cbData = sizeof(signedWithCertWithValidPubKeyContentBase64W);
|
|
|
|
SetLastError(0xdeadbeef);
|
2009-01-12 12:46:08 +01:00
|
|
|
ret = pCryptQueryObject(CERT_QUERY_OBJECT_BLOB, &blob,
|
2008-12-12 00:21:13 +01:00
|
|
|
CERT_QUERY_CONTENT_FLAG_ALL, CERT_QUERY_FORMAT_FLAG_ALL, 0, NULL, NULL,
|
|
|
|
NULL, NULL, NULL, NULL);
|
2022-02-23 09:12:05 +01:00
|
|
|
ok(ret, "CryptQueryObject failed: %08lx\n", GetLastError());
|
2008-12-12 00:21:13 +01:00
|
|
|
SetLastError(0xdeadbeef);
|
2009-01-12 12:46:08 +01:00
|
|
|
ret = pCryptQueryObject(CERT_QUERY_OBJECT_BLOB, &blob,
|
2008-12-12 00:21:13 +01:00
|
|
|
CERT_QUERY_CONTENT_FLAG_ALL, CERT_QUERY_FORMAT_FLAG_BINARY, 0, NULL, NULL,
|
|
|
|
NULL, NULL, NULL, NULL);
|
|
|
|
ok(!ret && GetLastError() == CRYPT_E_NO_MATCH,
|
2022-02-23 09:12:05 +01:00
|
|
|
"expected CRYPT_E_NO_MATCH, got %08lx\n", GetLastError());
|
2008-12-12 00:21:13 +01:00
|
|
|
SetLastError(0xdeadbeef);
|
2009-01-12 12:46:08 +01:00
|
|
|
ret = pCryptQueryObject(CERT_QUERY_OBJECT_BLOB, &blob,
|
2008-12-12 00:21:13 +01:00
|
|
|
CERT_QUERY_CONTENT_FLAG_ALL, CERT_QUERY_FORMAT_FLAG_BASE64_ENCODED, 0,
|
|
|
|
NULL, NULL, NULL, NULL, NULL, NULL);
|
2022-02-23 09:12:05 +01:00
|
|
|
ok(ret, "CryptQueryObject failed: %08lx\n", GetLastError());
|
2008-12-12 00:21:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
START_TEST(object)
|
|
|
|
{
|
2009-01-12 12:46:08 +01:00
|
|
|
HMODULE mod = GetModuleHandleA("crypt32.dll");
|
|
|
|
|
|
|
|
pCryptQueryObject = (void *)GetProcAddress(mod, "CryptQueryObject");
|
|
|
|
|
|
|
|
if (!pCryptQueryObject)
|
|
|
|
{
|
|
|
|
win_skip("CryptQueryObject is not available\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2008-12-12 00:21:13 +01:00
|
|
|
test_query_object();
|
|
|
|
}
|