[21311] | 1 | /*
|
---|
| 2 | * Unit test suite for crypt32.dll's Crypt*Message functions
|
---|
| 3 | *
|
---|
| 4 | * Copyright 2007-2008 Juan Lang
|
---|
| 5 | *
|
---|
| 6 | * This library is free software; you can redistribute it and/or
|
---|
| 7 | * modify it under the terms of the GNU Lesser General Public
|
---|
| 8 | * License as published by the Free Software Foundation; either
|
---|
| 9 | * version 2.1 of the License, or (at your option) any later version.
|
---|
| 10 | *
|
---|
| 11 | * This library is distributed in the hope that it will be useful,
|
---|
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
---|
| 14 | * Lesser General Public License for more details.
|
---|
| 15 | *
|
---|
| 16 | * You should have received a copy of the GNU Lesser General Public
|
---|
| 17 | * License along with this library; if not, write to the Free Software
|
---|
| 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
---|
| 19 | */
|
---|
| 20 |
|
---|
| 21 | #include <stdio.h>
|
---|
| 22 | #include <stdarg.h>
|
---|
| 23 | #include <windef.h>
|
---|
| 24 | #include <winbase.h>
|
---|
| 25 | #include <winerror.h>
|
---|
| 26 | #include <wincrypt.h>
|
---|
| 27 |
|
---|
| 28 | #include "wine/test.h"
|
---|
| 29 |
|
---|
| 30 | static const BYTE dataEmptyBareContent[] = { 0x04,0x00 };
|
---|
| 31 | static const BYTE dataEmptyContent[] = {
|
---|
| 32 | 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x02,
|
---|
| 33 | 0x04,0x00 };
|
---|
| 34 | static const BYTE signedEmptyBareContent[] = {
|
---|
| 35 | 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
|
---|
| 36 | 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
|
---|
| 37 | 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
|
---|
| 38 | 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
|
---|
| 39 | 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
|
---|
| 40 | 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
|
---|
| 41 | static const BYTE signedEmptyContent[] = {
|
---|
| 42 | 0x30,0x5f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x52,
|
---|
| 43 | 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
|
---|
| 44 | 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
|
---|
| 45 | 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
|
---|
| 46 | 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
|
---|
| 47 | 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
|
---|
| 48 | 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
|
---|
| 49 |
|
---|
| 50 | static void test_msg_get_signer_count(void)
|
---|
| 51 | {
|
---|
| 52 | LONG count;
|
---|
| 53 |
|
---|
| 54 | SetLastError(0xdeadbeef);
|
---|
| 55 | count = CryptGetMessageSignerCount(0, NULL, 0);
|
---|
| 56 | ok(count == -1, "Expected -1, got %d\n", count);
|
---|
| 57 | ok(GetLastError() == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n",
|
---|
| 58 | GetLastError());
|
---|
| 59 | SetLastError(0xdeadbeef);
|
---|
| 60 | count = CryptGetMessageSignerCount(PKCS_7_ASN_ENCODING, NULL, 0);
|
---|
| 61 | ok(count == -1, "Expected -1, got %d\n", count);
|
---|
| 62 | ok(GetLastError() == CRYPT_E_ASN1_EOD ||
|
---|
| 63 | GetLastError() == OSS_BAD_ARG, /* win9x */
|
---|
| 64 | "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
|
---|
| 65 | SetLastError(0xdeadbeef);
|
---|
| 66 | count = CryptGetMessageSignerCount(PKCS_7_ASN_ENCODING,
|
---|
| 67 | dataEmptyBareContent, sizeof(dataEmptyBareContent));
|
---|
| 68 | ok(count == -1, "Expected -1, got %d\n", count);
|
---|
| 69 | ok(GetLastError() == CRYPT_E_ASN1_BADTAG ||
|
---|
| 70 | GetLastError() == OSS_PDU_MISMATCH, /* win9x */
|
---|
| 71 | "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
|
---|
| 72 | SetLastError(0xdeadbeef);
|
---|
| 73 | count = CryptGetMessageSignerCount(PKCS_7_ASN_ENCODING,
|
---|
| 74 | dataEmptyContent, sizeof(dataEmptyContent));
|
---|
| 75 | ok(count == -1, "Expected -1, got %d\n", count);
|
---|
| 76 | ok(GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
|
---|
| 77 | "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
|
---|
| 78 | SetLastError(0xdeadbeef);
|
---|
| 79 | count = CryptGetMessageSignerCount(PKCS_7_ASN_ENCODING,
|
---|
| 80 | signedEmptyBareContent, sizeof(signedEmptyBareContent));
|
---|
| 81 | ok(count == -1, "Expected -1, got %d\n", count);
|
---|
| 82 | ok(GetLastError() == CRYPT_E_ASN1_BADTAG ||
|
---|
| 83 | GetLastError() == OSS_DATA_ERROR, /* win9x */
|
---|
| 84 | "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
|
---|
| 85 | count = CryptGetMessageSignerCount(PKCS_7_ASN_ENCODING,
|
---|
| 86 | signedEmptyContent, sizeof(signedEmptyContent));
|
---|
| 87 | ok(count == 1 ||
|
---|
| 88 | broken(count == -1), /* win9x */
|
---|
| 89 | "Expected 1, got %d\n", count);
|
---|
| 90 | }
|
---|
| 91 |
|
---|
| 92 | static BYTE detachedHashContent[] = {
|
---|
| 93 | 0x30,0x3f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x32,
|
---|
| 94 | 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
|
---|
| 95 | 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
|
---|
| 96 | 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
|
---|
| 97 | 0x9d,0x2a,0x8f,0x26,0x2f };
|
---|
| 98 | static const BYTE msgData[] = { 1, 2, 3, 4 };
|
---|
| 99 |
|
---|
| 100 | static void test_verify_detached_message_hash(void)
|
---|
| 101 | {
|
---|
| 102 | BOOL ret;
|
---|
| 103 | CRYPT_HASH_MESSAGE_PARA para;
|
---|
| 104 | DWORD size, hashSize;
|
---|
| 105 | const BYTE *pMsgData = msgData;
|
---|
| 106 | BYTE hash[16];
|
---|
| 107 |
|
---|
| 108 | if (0)
|
---|
| 109 | {
|
---|
| 110 | ret = CryptVerifyDetachedMessageHash(NULL, NULL, 0, 0, NULL, NULL, NULL,
|
---|
| 111 | NULL);
|
---|
| 112 | }
|
---|
| 113 | memset(¶, 0, sizeof(para));
|
---|
| 114 | SetLastError(0xdeadbeef);
|
---|
| 115 | ret = CryptVerifyDetachedMessageHash(¶, NULL, 0, 0, NULL, NULL, NULL,
|
---|
| 116 | NULL);
|
---|
| 117 | ok(!ret && GetLastError() == E_INVALIDARG,
|
---|
| 118 | "expected E_INVALIDARG, got %08x\n", GetLastError());
|
---|
| 119 | para.cbSize = sizeof(para);
|
---|
| 120 | SetLastError(0xdeadbeef);
|
---|
| 121 | ret = CryptVerifyDetachedMessageHash(¶, NULL, 0, 0, NULL, NULL, NULL,
|
---|
| 122 | NULL);
|
---|
| 123 | ok(!ret && GetLastError() == E_INVALIDARG,
|
---|
| 124 | "expected E_INVALIDARG, got %08x\n", GetLastError());
|
---|
| 125 | para.dwMsgEncodingType = PKCS_7_ASN_ENCODING;
|
---|
| 126 | SetLastError(0xdeadbeef);
|
---|
| 127 | ret = CryptVerifyDetachedMessageHash(¶, NULL, 0, 0, NULL, NULL, NULL,
|
---|
| 128 | NULL);
|
---|
| 129 | ok(!ret &&
|
---|
| 130 | (GetLastError() == CRYPT_E_ASN1_EOD ||
|
---|
| 131 | GetLastError() == OSS_BAD_ARG), /* win9x */
|
---|
| 132 | "expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
|
---|
| 133 | para.dwMsgEncodingType = X509_ASN_ENCODING;
|
---|
| 134 | SetLastError(0xdeadbeef);
|
---|
| 135 | ret = CryptVerifyDetachedMessageHash(¶, NULL, 0, 0, NULL, NULL, NULL,
|
---|
| 136 | NULL);
|
---|
| 137 | ok(!ret && GetLastError() == E_INVALIDARG,
|
---|
| 138 | "expected E_INVALIDARG, got %08x\n", GetLastError());
|
---|
| 139 | para.dwMsgEncodingType = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING;
|
---|
| 140 | SetLastError(0xdeadbeef);
|
---|
| 141 | ret = CryptVerifyDetachedMessageHash(¶, NULL, 0, 0, NULL, NULL, NULL,
|
---|
| 142 | NULL);
|
---|
| 143 | ok(!ret &&
|
---|
| 144 | (GetLastError() == CRYPT_E_ASN1_EOD ||
|
---|
| 145 | GetLastError() == OSS_BAD_ARG), /* win9x */
|
---|
| 146 | "expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
|
---|
| 147 | /* Curiously, passing no data to hash succeeds.. */
|
---|
| 148 | ret = CryptVerifyDetachedMessageHash(¶, detachedHashContent,
|
---|
| 149 | sizeof(detachedHashContent), 0, NULL, NULL, NULL, NULL);
|
---|
| 150 | todo_wine
|
---|
| 151 | ok(ret, "CryptVerifyDetachedMessageHash failed: %08x\n", GetLastError());
|
---|
| 152 | /* as does passing the actual content of the message to hash.. */
|
---|
| 153 | size = sizeof(msgData);
|
---|
| 154 | pMsgData = msgData;
|
---|
| 155 | ret = CryptVerifyDetachedMessageHash(¶, detachedHashContent,
|
---|
| 156 | sizeof(detachedHashContent), 1, &pMsgData, &size, NULL, NULL);
|
---|
| 157 | ok(ret, "CryptVerifyDetachedMessageHash failed: %08x\n", GetLastError());
|
---|
| 158 | /* while passing data to hash that isn't the content of the message fails.
|
---|
| 159 | */
|
---|
| 160 | size = sizeof(detachedHashContent);
|
---|
| 161 | pMsgData = detachedHashContent;
|
---|
| 162 | SetLastError(0xdeadbeef);
|
---|
| 163 | ret = CryptVerifyDetachedMessageHash(¶, detachedHashContent,
|
---|
| 164 | sizeof(detachedHashContent), 1, &pMsgData, &size, NULL, NULL);
|
---|
| 165 | ok(!ret && GetLastError() == CRYPT_E_HASH_VALUE,
|
---|
| 166 | "expected CRYPT_E_HASH_VALUE, got %08x\n", GetLastError());
|
---|
| 167 | /* Getting the size of the hash while passing no hash data causes the
|
---|
| 168 | * hash to be checked (and fail.)
|
---|
| 169 | */
|
---|
| 170 | SetLastError(0xdeadbeef);
|
---|
| 171 | ret = CryptVerifyDetachedMessageHash(¶, detachedHashContent,
|
---|
| 172 | sizeof(detachedHashContent), 0, NULL, NULL, NULL, &hashSize);
|
---|
| 173 | ok(!ret && GetLastError() == CRYPT_E_HASH_VALUE,
|
---|
| 174 | "expected CRYPT_E_HASH_VALUE, got %08x\n", GetLastError());
|
---|
| 175 | size = sizeof(msgData);
|
---|
| 176 | pMsgData = msgData;
|
---|
| 177 | ret = CryptVerifyDetachedMessageHash(¶, detachedHashContent,
|
---|
| 178 | sizeof(detachedHashContent), 1, &pMsgData, &size, NULL, &hashSize);
|
---|
| 179 | ok(ret, "CryptVerifyDetachedMessageHash failed: %08x\n", GetLastError());
|
---|
| 180 | ok(hashSize == sizeof(hash), "unexpected size %d\n", hashSize);
|
---|
| 181 | hashSize = 1;
|
---|
| 182 | SetLastError(0xdeadbeef);
|
---|
| 183 | ret = CryptVerifyDetachedMessageHash(¶, detachedHashContent,
|
---|
| 184 | sizeof(detachedHashContent), 1, &pMsgData, &size, hash, &hashSize);
|
---|
| 185 | ok(!ret && GetLastError() == ERROR_MORE_DATA,
|
---|
| 186 | "expected ERROR_MORE_DATA, got %08x\n", GetLastError());
|
---|
| 187 | hashSize = sizeof(hash);
|
---|
| 188 | ret = CryptVerifyDetachedMessageHash(¶, detachedHashContent,
|
---|
| 189 | sizeof(detachedHashContent), 1, &pMsgData, &size, hash, &hashSize);
|
---|
| 190 | ok(ret, "CryptVerifyDetachedMessageHash failed: %08x\n", GetLastError());
|
---|
| 191 | }
|
---|
| 192 |
|
---|
| 193 | static BYTE hashContent[] = {
|
---|
| 194 | 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
|
---|
| 195 | 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
|
---|
| 196 | 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
|
---|
| 197 | 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
|
---|
| 198 | 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
|
---|
| 199 |
|
---|
| 200 | static void test_verify_message_hash(void)
|
---|
| 201 | {
|
---|
| 202 | BOOL ret;
|
---|
| 203 | CRYPT_HASH_MESSAGE_PARA para;
|
---|
| 204 | DWORD size;
|
---|
| 205 | BYTE *buf = NULL;
|
---|
| 206 |
|
---|
| 207 | memset(¶, 0, sizeof(para));
|
---|
| 208 | /* Crash */
|
---|
| 209 | if (0)
|
---|
| 210 | ret = CryptVerifyMessageHash(NULL, NULL, 0, NULL, NULL, NULL, NULL);
|
---|
| 211 | SetLastError(0xdeadbeef);
|
---|
| 212 | ret = CryptVerifyMessageHash(¶, NULL, 0, NULL, NULL, NULL, NULL);
|
---|
| 213 | ok(!ret && GetLastError() == E_INVALIDARG,
|
---|
| 214 | "expected E_INVALIDARG, got %08x\n", GetLastError());
|
---|
| 215 | para.cbSize = sizeof(para);
|
---|
| 216 | SetLastError(0xdeadbeef);
|
---|
| 217 | ret = CryptVerifyMessageHash(¶, NULL, 0, NULL, NULL, NULL, NULL);
|
---|
| 218 | ok(!ret && GetLastError() == E_INVALIDARG,
|
---|
| 219 | "expected E_INVALIDARG, got %08x\n", GetLastError());
|
---|
| 220 | para.dwMsgEncodingType = PKCS_7_ASN_ENCODING;
|
---|
| 221 | SetLastError(0xdeadbeef);
|
---|
| 222 | ret = CryptVerifyMessageHash(¶, NULL, 0, NULL, NULL, NULL, NULL);
|
---|
| 223 | ok(!ret, "Expected 0, got %d\n", ret);
|
---|
| 224 | ok(GetLastError() == CRYPT_E_ASN1_EOD ||
|
---|
| 225 | GetLastError() == OSS_BAD_ARG, /* win98 */
|
---|
| 226 | "Expected CRYPT_E_ASN1_EOD or OSS_BAD_ARG, got %08x\n", GetLastError());
|
---|
| 227 | /* Verifying the hash of a detached message succeeds? */
|
---|
| 228 | ret = CryptVerifyMessageHash(¶, detachedHashContent,
|
---|
| 229 | sizeof(detachedHashContent), NULL, NULL, NULL, NULL);
|
---|
| 230 | todo_wine
|
---|
| 231 | ok(ret, "CryptVerifyMessageHash failed: %08x\n", GetLastError());
|
---|
| 232 | /* As does verifying the hash of a regular message. */
|
---|
| 233 | ret = CryptVerifyMessageHash(¶, hashContent, sizeof(hashContent),
|
---|
| 234 | NULL, NULL, NULL, NULL);
|
---|
| 235 | ok(ret, "CryptVerifyMessageHash failed: %08x\n", GetLastError());
|
---|
| 236 | ret = CryptVerifyMessageHash(¶, hashContent, sizeof(hashContent),
|
---|
| 237 | NULL, &size, NULL, NULL);
|
---|
| 238 | ok(ret, "CryptVerifyMessageHash failed: %08x\n", GetLastError());
|
---|
| 239 | if (ret)
|
---|
| 240 | buf = CryptMemAlloc(size);
|
---|
| 241 | if (buf)
|
---|
| 242 | {
|
---|
| 243 | size = 1;
|
---|
| 244 | ret = CryptVerifyMessageHash(¶, hashContent, sizeof(hashContent),
|
---|
| 245 | buf, &size, NULL, NULL);
|
---|
| 246 | ok(!ret && GetLastError() == ERROR_MORE_DATA,
|
---|
| 247 | "expected ERROR_MORE_DATA, got %08x\n", GetLastError());
|
---|
| 248 | ret = CryptVerifyMessageHash(¶, hashContent, sizeof(hashContent),
|
---|
| 249 | buf, &size, NULL, NULL);
|
---|
| 250 | ok(ret, "CryptVerifyMessageHash failed: %08x\n", GetLastError());
|
---|
| 251 | ok(size == sizeof(msgData), "unexpected size %d\n", size);
|
---|
| 252 | ok(!memcmp(buf, msgData, size), "unexpected value\n");
|
---|
| 253 | CryptMemFree(buf);
|
---|
| 254 | }
|
---|
| 255 | }
|
---|
| 256 |
|
---|
| 257 | static const BYTE signedWithCertContent[] = {
|
---|
| 258 | 0x30,0x82,0x01,0x32,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
|
---|
| 259 | 0xa0,0x82,0x01,0x23,0x30,0x82,0x01,0x1f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
|
---|
| 260 | 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,
|
---|
| 261 | 0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,
|
---|
| 262 | 0x02,0x03,0x04,0xa0,0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,
|
---|
| 263 | 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
|
---|
| 264 | 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,
|
---|
| 265 | 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,
|
---|
| 266 | 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,
|
---|
| 267 | 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
|
---|
| 268 | 0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,
|
---|
| 269 | 0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,
|
---|
| 270 | 0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,
|
---|
| 271 | 0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,
|
---|
| 272 | 0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,
|
---|
| 273 | 0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,
|
---|
| 274 | 0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,
|
---|
| 275 | 0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,
|
---|
| 276 | 0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,
|
---|
| 277 | 0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,
|
---|
| 278 | 0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
|
---|
| 279 | static const BYTE signedContent[] = {
|
---|
| 280 | 0x30,0x81,0xb2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
|
---|
| 281 | 0x81,0xa4,0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
|
---|
| 282 | 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,
|
---|
| 283 | 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,
|
---|
| 284 | 0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,
|
---|
| 285 | 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
|
---|
| 286 | 0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
|
---|
| 287 | 0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,
|
---|
| 288 | 0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,
|
---|
| 289 | 0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,
|
---|
| 290 | 0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,
|
---|
| 291 | 0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,
|
---|
| 292 | 0x0d };
|
---|
| 293 | static const BYTE detachedSignedContent[] = {
|
---|
| 294 | 0x30,0x81,0xaa,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
|
---|
| 295 | 0x81,0x9c,0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
|
---|
| 296 | 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,
|
---|
| 297 | 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,
|
---|
| 298 | 0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
|
---|
| 299 | 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,
|
---|
| 300 | 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,
|
---|
| 301 | 0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,
|
---|
| 302 | 0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,
|
---|
| 303 | 0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,
|
---|
| 304 | 0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,
|
---|
| 305 | 0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
|
---|
| 306 | static const BYTE v1CertWithValidPubKey[] = {
|
---|
| 307 | 0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
|
---|
| 308 | 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
|
---|
| 309 | 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
|
---|
| 310 | 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
|
---|
| 311 | 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
|
---|
| 312 | 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
|
---|
| 313 | 0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
|
---|
| 314 | 0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,
|
---|
| 315 | 0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,
|
---|
| 316 | 0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,
|
---|
| 317 | 0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,
|
---|
| 318 | 0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,
|
---|
| 319 | 0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
|
---|
| 320 | 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
|
---|
| 321 |
|
---|
| 322 | static PCCERT_CONTEXT WINAPI msg_get_signer_callback(void *pvArg,
|
---|
| 323 | DWORD certEncodingType, PCERT_INFO signerId, HCERTSTORE store)
|
---|
| 324 | {
|
---|
| 325 | return CertCreateCertificateContext(X509_ASN_ENCODING,
|
---|
| 326 | v1CertWithValidPubKey, sizeof(v1CertWithValidPubKey));
|
---|
| 327 | }
|
---|
| 328 |
|
---|
| 329 | static void test_verify_detached_message_signature(void)
|
---|
| 330 | {
|
---|
| 331 | CRYPT_VERIFY_MESSAGE_PARA para;
|
---|
| 332 | BOOL ret;
|
---|
| 333 | const BYTE *pContent;
|
---|
| 334 | DWORD cbContent;
|
---|
| 335 |
|
---|
| 336 | memset(¶, 0, sizeof(para));
|
---|
| 337 | SetLastError(0xdeadbeef);
|
---|
| 338 | ret = CryptVerifyDetachedMessageSignature(NULL, 0, NULL, 0, 0, NULL,
|
---|
| 339 | NULL, NULL);
|
---|
| 340 | ok(!ret && GetLastError() == E_INVALIDARG,
|
---|
| 341 | "Expected E_INVALIDARG, got %08x\n", GetLastError());
|
---|
| 342 | SetLastError(0xdeadbeef);
|
---|
| 343 | ret = CryptVerifyDetachedMessageSignature(¶, 0, NULL, 0, 0, NULL,
|
---|
| 344 | NULL, NULL);
|
---|
| 345 | ok(!ret && GetLastError() == E_INVALIDARG,
|
---|
| 346 | "Expected E_INVALIDARG, got %08x\n", GetLastError());
|
---|
| 347 | para.cbSize = sizeof(para);
|
---|
| 348 | SetLastError(0xdeadbeef);
|
---|
| 349 | ret = CryptVerifyDetachedMessageSignature(¶, 0, NULL, 0, 0, NULL,
|
---|
| 350 | NULL, NULL);
|
---|
| 351 | ok(!ret && GetLastError() == E_INVALIDARG,
|
---|
| 352 | "Expected E_INVALIDARG, got %08x\n", GetLastError());
|
---|
| 353 | para.dwMsgAndCertEncodingType = X509_ASN_ENCODING;
|
---|
| 354 | SetLastError(0xdeadbeef);
|
---|
| 355 | ret = CryptVerifyDetachedMessageSignature(¶, 0, NULL, 0, 0, NULL,
|
---|
| 356 | NULL, NULL);
|
---|
| 357 | ok(!ret && GetLastError() == E_INVALIDARG,
|
---|
| 358 | "Expected E_INVALIDARG, got %08x\n", GetLastError());
|
---|
| 359 | para.dwMsgAndCertEncodingType = PKCS_7_ASN_ENCODING;
|
---|
| 360 | SetLastError(0xdeadbeef);
|
---|
| 361 | ret = CryptVerifyDetachedMessageSignature(¶, 0, NULL, 0, 0, NULL,
|
---|
| 362 | NULL, NULL);
|
---|
| 363 | ok(!ret, "Expected 0, got %d\n", ret);
|
---|
| 364 | ok(GetLastError() == CRYPT_E_ASN1_EOD ||
|
---|
| 365 | GetLastError() == OSS_BAD_ARG, /* win98 */
|
---|
| 366 | "Expected CRYPT_E_ASN1_EOD or OSS_BAD_ARG, got %08x\n", GetLastError());
|
---|
| 367 | /* None of these messages contains a cert in the message itself, so the
|
---|
| 368 | * default callback isn't able to verify their signature.
|
---|
| 369 | */
|
---|
| 370 | SetLastError(0xdeadbeef);
|
---|
| 371 | ret = CryptVerifyDetachedMessageSignature(¶, 0, signedWithCertContent,
|
---|
| 372 | sizeof(signedWithCertContent), 0, NULL, NULL, NULL);
|
---|
| 373 | ok(!ret, "Expected 0, got %d\n", ret);
|
---|
| 374 | todo_wine
|
---|
| 375 | ok(GetLastError() == CRYPT_E_NOT_FOUND ||
|
---|
| 376 | GetLastError() == OSS_DATA_ERROR, /* win98 */
|
---|
| 377 | "Expected CRYPT_E_NOT_FOUND or OSS_DATA_ERROR, got %08x\n", GetLastError());
|
---|
| 378 | SetLastError(0xdeadbeef);
|
---|
| 379 | ret = CryptVerifyDetachedMessageSignature(¶, 0, signedContent,
|
---|
| 380 | sizeof(signedContent), 0, NULL, NULL, NULL);
|
---|
| 381 | ok(!ret, "Expected 0, got %d\n", ret);
|
---|
| 382 | ok(GetLastError() == CRYPT_E_NOT_FOUND ||
|
---|
| 383 | GetLastError() == OSS_DATA_ERROR, /* win98 */
|
---|
| 384 | "Expected CRYPT_E_NOT_FOUND or OSS_DATA_ERROR, got %08x\n", GetLastError());
|
---|
| 385 | SetLastError(0xdeadbeef);
|
---|
| 386 | ret = CryptVerifyDetachedMessageSignature(¶, 0, detachedSignedContent,
|
---|
| 387 | sizeof(detachedSignedContent), 0, NULL, NULL, NULL);
|
---|
| 388 | ok(!ret, "Expected 0, got %d\n", ret);
|
---|
| 389 | ok(GetLastError() == CRYPT_E_NOT_FOUND ||
|
---|
| 390 | GetLastError() == OSS_DATA_ERROR, /* win98 */
|
---|
| 391 | "Expected CRYPT_E_NOT_FOUND or OSS_DATA_ERROR, got %08x\n", GetLastError());
|
---|
| 392 | SetLastError(0xdeadbeef);
|
---|
| 393 | pContent = msgData;
|
---|
| 394 | cbContent = sizeof(msgData);
|
---|
| 395 | ret = CryptVerifyDetachedMessageSignature(¶, 0, detachedSignedContent,
|
---|
| 396 | sizeof(detachedSignedContent), 1, &pContent, &cbContent, NULL);
|
---|
| 397 | ok(!ret, "Expected 0, got %d\n", ret);
|
---|
| 398 | ok(GetLastError() == CRYPT_E_NOT_FOUND ||
|
---|
| 399 | GetLastError() == OSS_DATA_ERROR, /* win98 */
|
---|
| 400 | "Expected CRYPT_E_NOT_FOUND or OSS_DATA_ERROR, got %08x\n", GetLastError());
|
---|
| 401 | /* Passing the correct callback results in success */
|
---|
| 402 | para.pfnGetSignerCertificate = msg_get_signer_callback;
|
---|
| 403 | ret = CryptVerifyDetachedMessageSignature(¶, 0, detachedSignedContent,
|
---|
| 404 | sizeof(detachedSignedContent), 1, &pContent, &cbContent, NULL);
|
---|
| 405 | ok(ret ||
|
---|
| 406 | broken(!ret), /* win98 */
|
---|
| 407 | "CryptVerifyDetachedMessageSignature failed: %08x\n",
|
---|
| 408 | GetLastError());
|
---|
| 409 | /* Not passing the correct data to be signed results in the signature not
|
---|
| 410 | * matching.
|
---|
| 411 | */
|
---|
| 412 | SetLastError(0xdeadbeef);
|
---|
| 413 | ret = CryptVerifyDetachedMessageSignature(¶, 0, detachedSignedContent,
|
---|
| 414 | sizeof(detachedSignedContent), 0, NULL, NULL, NULL);
|
---|
| 415 | ok(!ret, "Expected 0, got %d\n", ret);
|
---|
| 416 | ok(GetLastError() == NTE_BAD_SIGNATURE ||
|
---|
| 417 | GetLastError() == OSS_DATA_ERROR, /* win98 */
|
---|
| 418 | "Expected NTE_BAD_SIGNATURE or OSS_DATA_ERROR, got %08x\n", GetLastError());
|
---|
| 419 | }
|
---|
| 420 |
|
---|
| 421 | static const BYTE signedWithCertEmptyContent[] = {
|
---|
| 422 | 0x30,0x81,0xdf,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
|
---|
| 423 | 0x81,0xd1,0x30,0x81,0xce,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
|
---|
| 424 | 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,
|
---|
| 425 | 0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
|
---|
| 426 | 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
|
---|
| 427 | 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
|
---|
| 428 | 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
|
---|
| 429 | 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
|
---|
| 430 | 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
|
---|
| 431 | 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,
|
---|
| 432 | 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
|
---|
| 433 | 0xff,0x02,0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,
|
---|
| 434 | 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
|
---|
| 435 | 0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,
|
---|
| 436 | 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
|
---|
| 437 | 0x00 };
|
---|
| 438 | static const BYTE signedWithCertWithPubKeyContent[] = {
|
---|
| 439 | 0x30,0x81,0xfc,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
|
---|
| 440 | 0x81,0xee,0x30,0x81,0xeb,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
|
---|
| 441 | 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x81,
|
---|
| 442 | 0x98,0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,
|
---|
| 443 | 0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,
|
---|
| 444 | 0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
|
---|
| 445 | 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,
|
---|
| 446 | 0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,
|
---|
| 447 | 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
|
---|
| 448 | 0x6e,0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
|
---|
| 449 | 0x01,0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,
|
---|
| 450 | 0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,
|
---|
| 451 | 0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,
|
---|
| 452 | 0x02,0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,
|
---|
| 453 | 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
|
---|
| 454 | 0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
|
---|
| 455 | 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
|
---|
| 456 |
|
---|
| 457 | static void test_verify_message_signature(void)
|
---|
| 458 | {
|
---|
| 459 | BOOL ret;
|
---|
| 460 | CRYPT_VERIFY_MESSAGE_PARA para = { 0 };
|
---|
| 461 | PCCERT_CONTEXT cert;
|
---|
| 462 | DWORD cbDecoded;
|
---|
| 463 |
|
---|
| 464 | SetLastError(0xdeadbeef);
|
---|
| 465 | ret = CryptVerifyMessageSignature(NULL, 0, NULL, 0, NULL, 0, NULL);
|
---|
| 466 | ok(!ret && GetLastError() == E_INVALIDARG,
|
---|
| 467 | "Expected E_INVALIDARG, got %08x\n", GetLastError());
|
---|
| 468 | SetLastError(0xdeadbeef);
|
---|
| 469 | ret = CryptVerifyMessageSignature(¶, 0, NULL, 0, NULL, 0, NULL);
|
---|
| 470 | ok(!ret && GetLastError() == E_INVALIDARG,
|
---|
| 471 | "Expected E_INVALIDARG, got %08x\n", GetLastError());
|
---|
| 472 | para.cbSize = sizeof(para);
|
---|
| 473 | SetLastError(0xdeadbeef);
|
---|
| 474 | ret = CryptVerifyMessageSignature(¶, 0, NULL, 0, NULL, 0, NULL);
|
---|
| 475 | ok(!ret && GetLastError() == E_INVALIDARG,
|
---|
| 476 | "Expected E_INVALIDARG, got %08x\n", GetLastError());
|
---|
| 477 | para.cbSize = 0;
|
---|
| 478 | para.dwMsgAndCertEncodingType = PKCS_7_ASN_ENCODING;
|
---|
| 479 | SetLastError(0xdeadbeef);
|
---|
| 480 | ret = CryptVerifyMessageSignature(¶, 0, NULL, 0, NULL, 0, NULL);
|
---|
| 481 | ok(!ret && GetLastError() == E_INVALIDARG,
|
---|
| 482 | "Expected E_INVALIDARG, got %08x\n", GetLastError());
|
---|
| 483 | para.cbSize = sizeof(para);
|
---|
| 484 | SetLastError(0xdeadbeef);
|
---|
| 485 | ret = CryptVerifyMessageSignature(¶, 0, NULL, 0, NULL, 0, NULL);
|
---|
| 486 | ok(!ret &&
|
---|
| 487 | (GetLastError() == CRYPT_E_ASN1_EOD ||
|
---|
| 488 | GetLastError() == OSS_BAD_ARG), /* win9x */
|
---|
| 489 | "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
|
---|
| 490 | /* Check whether cert is set on error */
|
---|
| 491 | cert = (PCCERT_CONTEXT)0xdeadbeef;
|
---|
| 492 | ret = CryptVerifyMessageSignature(¶, 0, NULL, 0, NULL, 0, &cert);
|
---|
| 493 | ok(cert == NULL, "Expected NULL cert\n");
|
---|
| 494 | /* Check whether cbDecoded is set on error */
|
---|
| 495 | cbDecoded = 0xdeadbeef;
|
---|
| 496 | ret = CryptVerifyMessageSignature(¶, 0, NULL, 0, NULL, &cbDecoded,
|
---|
| 497 | NULL);
|
---|
| 498 | ok(!cbDecoded, "Expected 0\n");
|
---|
| 499 | SetLastError(0xdeadbeef);
|
---|
| 500 | ret = CryptVerifyMessageSignature(¶, 0, dataEmptyBareContent,
|
---|
| 501 | sizeof(dataEmptyBareContent), NULL, 0, NULL);
|
---|
| 502 | ok(GetLastError() == CRYPT_E_ASN1_BADTAG ||
|
---|
| 503 | GetLastError() == OSS_PDU_MISMATCH, /* win9x */
|
---|
| 504 | "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
|
---|
| 505 | SetLastError(0xdeadbeef);
|
---|
| 506 | ret = CryptVerifyMessageSignature(¶, 0, dataEmptyContent,
|
---|
| 507 | sizeof(dataEmptyContent), NULL, 0, NULL);
|
---|
| 508 | ok(!ret && GetLastError() == CRYPT_E_UNEXPECTED_MSG_TYPE,
|
---|
| 509 | "Expected CRYPT_E_UNEXPECTED_MSG_TYPE, got %08x\n", GetLastError());
|
---|
| 510 | SetLastError(0xdeadbeef);
|
---|
| 511 | ret = CryptVerifyMessageSignature(¶, 0, signedEmptyBareContent,
|
---|
| 512 | sizeof(signedEmptyBareContent), NULL, 0, NULL);
|
---|
| 513 | ok(!ret &&
|
---|
| 514 | (GetLastError() == CRYPT_E_ASN1_BADTAG ||
|
---|
| 515 | GetLastError() == OSS_DATA_ERROR), /* win9x */
|
---|
| 516 | "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
|
---|
| 517 | SetLastError(0xdeadbeef);
|
---|
| 518 | ret = CryptVerifyMessageSignature(¶, 0, signedEmptyContent,
|
---|
| 519 | sizeof(signedEmptyContent), NULL, 0, NULL);
|
---|
| 520 | ok(!ret &&
|
---|
| 521 | (GetLastError() == CRYPT_E_NOT_FOUND ||
|
---|
| 522 | GetLastError() == OSS_DATA_ERROR), /* win9x */
|
---|
| 523 | "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
|
---|
| 524 | SetLastError(0xdeadbeef);
|
---|
| 525 | ret = CryptVerifyMessageSignature(¶, 0, signedContent,
|
---|
| 526 | sizeof(signedContent), NULL, 0, NULL);
|
---|
| 527 | ok(!ret &&
|
---|
| 528 | (GetLastError() == CRYPT_E_NOT_FOUND ||
|
---|
| 529 | GetLastError() == OSS_DATA_ERROR), /* win9x */
|
---|
| 530 | "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
|
---|
| 531 | /* FIXME: Windows fails with CRYPT_E_NOT_FOUND for these messages, but
|
---|
| 532 | * their signer certs have invalid public keys that fail to decode. In
|
---|
| 533 | * Wine therefore the failure is an ASN error. Need some messages with
|
---|
| 534 | * valid public keys and invalid signatures to check against.
|
---|
| 535 | */
|
---|
| 536 | ret = CryptVerifyMessageSignature(¶, 0, signedWithCertEmptyContent,
|
---|
| 537 | sizeof(signedWithCertEmptyContent), NULL, 0, NULL);
|
---|
| 538 | ok(!ret, "Expected failure\n");
|
---|
| 539 | ret = CryptVerifyMessageSignature(¶, 0, signedWithCertContent,
|
---|
| 540 | sizeof(signedWithCertContent), NULL, 0, NULL);
|
---|
| 541 | ok(!ret, "Expected failure\n");
|
---|
| 542 | ret = CryptVerifyMessageSignature(¶, 0, signedWithCertWithPubKeyContent,
|
---|
| 543 | sizeof(signedWithCertWithPubKeyContent), NULL, 0, NULL);
|
---|
| 544 | ok(!ret, "Expected failure\n");
|
---|
| 545 | }
|
---|
| 546 |
|
---|
| 547 | static const BYTE detachedHashBlob[] = {
|
---|
| 548 | 0x30,0x3f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x32,
|
---|
| 549 | 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
|
---|
| 550 | 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
|
---|
| 551 | 0x07,0x01,0x04,0x10,0x2d,0x1b,0xbc,0x1f,0xc7,0xab,0x36,0x8d,0xdb,0x95,0xe6,
|
---|
| 552 | 0x24,0xb9,0x66,0x7c,0x21 };
|
---|
| 553 | static const BYTE hashBlob[] = {
|
---|
| 554 | 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
|
---|
| 555 | 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
|
---|
| 556 | 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
|
---|
| 557 | 0x07,0x01,0xa0,0x06,0x04,0x04,0xde,0xad,0xbe,0xef,0x04,0x10,0x2f,0x24,0x92,
|
---|
| 558 | 0x30,0xa8,0xe7,0xc2,0xbf,0x60,0x05,0xcc,0xd2,0x67,0x92,0x59,0xec };
|
---|
| 559 | static const BYTE hashVal[] = {
|
---|
| 560 | 0x2d,0x1b,0xbc,0x1f,0xc7,0xab,0x36,0x8d,0xdb,0x95,0xe6,0x24,0xb9,0x66,0x7c,
|
---|
| 561 | 0x21 };
|
---|
| 562 |
|
---|
| 563 | static void test_hash_message(void)
|
---|
| 564 | {
|
---|
| 565 | BOOL ret;
|
---|
| 566 | CRYPT_HASH_MESSAGE_PARA para;
|
---|
| 567 | static const BYTE blob1[] = { 0xde, 0xad, 0xbe, 0xef };
|
---|
| 568 | static const BYTE blob2[] = { 0xba, 0xad, 0xf0, 0x0d };
|
---|
| 569 | const BYTE *toHash[] = { blob1, blob2 };
|
---|
| 570 | DWORD hashSize[] = { sizeof(blob1), sizeof(blob2) };
|
---|
| 571 | DWORD hashedBlobSize, computedHashSize;
|
---|
| 572 | static char oid_rsa_md5[] = szOID_RSA_MD5;
|
---|
| 573 | LPBYTE hashedBlob, computedHash;
|
---|
| 574 |
|
---|
| 575 | /* Crash
|
---|
| 576 | ret = CryptHashMessage(NULL, FALSE, 0, NULL, 0, NULL, NULL, NULL, NULL);
|
---|
| 577 | */
|
---|
| 578 | memset(¶, 0, sizeof(para));
|
---|
| 579 | SetLastError(0xdeadbeef);
|
---|
| 580 | ret = CryptHashMessage(¶, FALSE, 0, NULL, NULL, NULL, NULL, NULL, NULL);
|
---|
| 581 | ok(!ret && GetLastError() == E_INVALIDARG,
|
---|
| 582 | "expected E_INVALIDARG, got 0x%08x\n", GetLastError());
|
---|
| 583 | para.cbSize = sizeof(para);
|
---|
| 584 | /* Not quite sure what "success" means in this case, but it does succeed */
|
---|
| 585 | SetLastError(0xdeadbeef);
|
---|
| 586 | ret = CryptHashMessage(¶, FALSE, 0, NULL, NULL, NULL, NULL, NULL, NULL);
|
---|
| 587 | ok(ret, "CryptHashMessage failed: 0x%08x\n", GetLastError());
|
---|
| 588 | /* With a bogus encoding type it "succeeds" */
|
---|
| 589 | para.dwMsgEncodingType = 0xdeadbeef;
|
---|
| 590 | SetLastError(0xdeadbeef);
|
---|
| 591 | ret = CryptHashMessage(¶, FALSE, 0, NULL, NULL, NULL, NULL, NULL, NULL);
|
---|
| 592 | ok(ret, "CryptHashMessage failed: 0x%08x\n", GetLastError());
|
---|
| 593 | /* According to MSDN, the third parameter (cToBeHashed) must be 1 if the
|
---|
| 594 | * second parameter (fDetached) is FALSE, but again it "succeeds."
|
---|
| 595 | */
|
---|
| 596 | SetLastError(0xdeadbeef);
|
---|
| 597 | ret = CryptHashMessage(¶, FALSE, 2, NULL, NULL, NULL, NULL, NULL, NULL);
|
---|
| 598 | ok(ret, "CryptHashMessage failed: 0x%08x\n", GetLastError());
|
---|
| 599 | /* Even passing parameters to hash results in "success." */
|
---|
| 600 | SetLastError(0xdeadbeef);
|
---|
| 601 | ret = CryptHashMessage(¶, FALSE, 2, toHash, hashSize, NULL, NULL, NULL,
|
---|
| 602 | NULL);
|
---|
| 603 | /* Try again with a valid encoding type */
|
---|
| 604 | para.dwMsgEncodingType = PKCS_7_ASN_ENCODING;
|
---|
| 605 | SetLastError(0xdeadbeef);
|
---|
| 606 | ret = CryptHashMessage(¶, FALSE, 2, NULL, NULL, NULL, NULL, NULL, NULL);
|
---|
| 607 | ok(ret, "CryptHashMessage failed: 0x%08x\n", GetLastError());
|
---|
| 608 | /* And with valid data to hash */
|
---|
| 609 | SetLastError(0xdeadbeef);
|
---|
| 610 | ret = CryptHashMessage(¶, FALSE, 2, toHash, hashSize, NULL, NULL, NULL,
|
---|
| 611 | NULL);
|
---|
| 612 | ok(ret, "CryptHashMessage failed: 0x%08x\n", GetLastError());
|
---|
| 613 | /* But requesting the size of the hashed blob and indicating there's data
|
---|
| 614 | * to hash results in a crash
|
---|
| 615 | */
|
---|
| 616 | if (0)
|
---|
| 617 | {
|
---|
| 618 | ret = CryptHashMessage(¶, FALSE, 2, NULL, NULL, NULL,
|
---|
| 619 | &hashedBlobSize, NULL, NULL);
|
---|
| 620 | }
|
---|
| 621 | /* Passing a valid pointer for the data to hash fails, as the hash
|
---|
| 622 | * algorithm is finally checked.
|
---|
| 623 | */
|
---|
| 624 | SetLastError(0xdeadbeef);
|
---|
| 625 | ret = CryptHashMessage(¶, FALSE, 2, toHash, hashSize, NULL,
|
---|
| 626 | &hashedBlobSize, NULL, NULL);
|
---|
| 627 | ok(!ret &&
|
---|
| 628 | (GetLastError() == CRYPT_E_UNKNOWN_ALGO ||
|
---|
| 629 | GetLastError() == CRYPT_E_OID_FORMAT), /* Vista */
|
---|
| 630 | "expected CRYPT_E_UNKNOWN_ALGO or CRYPT_E_OID_FORMAT, got 0x%08x (%d)\n",
|
---|
| 631 | GetLastError(), GetLastError());
|
---|
| 632 | para.HashAlgorithm.pszObjId = oid_rsa_md5;
|
---|
| 633 | /* With a valid hash algorithm, this succeeds, even though fDetached is
|
---|
| 634 | * FALSE.
|
---|
| 635 | */
|
---|
| 636 | SetLastError(0xdeadbeef);
|
---|
| 637 | ret = CryptHashMessage(¶, FALSE, 2, toHash, hashSize, NULL,
|
---|
| 638 | &hashedBlobSize, NULL, NULL);
|
---|
| 639 | todo_wine
|
---|
| 640 | ok(ret, "CryptHashMessage failed: 0x%08x\n", GetLastError());
|
---|
| 641 | if (ret)
|
---|
| 642 | {
|
---|
| 643 | /* Actually attempting to get the hashed data fails, perhaps because
|
---|
| 644 | * detached is FALSE.
|
---|
| 645 | */
|
---|
| 646 | hashedBlob = HeapAlloc(GetProcessHeap(), 0, hashedBlobSize);
|
---|
| 647 | SetLastError(0xdeadbeef);
|
---|
| 648 | ret = CryptHashMessage(¶, FALSE, 2, toHash, hashSize, hashedBlob,
|
---|
| 649 | &hashedBlobSize, NULL, NULL);
|
---|
| 650 | ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
|
---|
| 651 | "expected CRYPT_E_MSG_ERROR, got 0x%08x (%d)\n", GetLastError(),
|
---|
| 652 | GetLastError());
|
---|
| 653 | HeapFree(GetProcessHeap(), 0, hashedBlob);
|
---|
| 654 | }
|
---|
| 655 | /* Repeating tests with fDetached = TRUE results in success */
|
---|
| 656 | SetLastError(0xdeadbeef);
|
---|
| 657 | ret = CryptHashMessage(¶, TRUE, 2, toHash, hashSize, NULL,
|
---|
| 658 | &hashedBlobSize, NULL, NULL);
|
---|
| 659 | ok(ret, "CryptHashMessage failed: 0x%08x\n", GetLastError());
|
---|
| 660 | if (ret)
|
---|
| 661 | {
|
---|
| 662 | hashedBlob = HeapAlloc(GetProcessHeap(), 0, hashedBlobSize);
|
---|
| 663 | SetLastError(0xdeadbeef);
|
---|
| 664 | ret = CryptHashMessage(¶, TRUE, 2, toHash, hashSize, hashedBlob,
|
---|
| 665 | &hashedBlobSize, NULL, NULL);
|
---|
| 666 | ok(ret, "CryptHashMessage failed: 0x%08x\n", GetLastError());
|
---|
| 667 | ok(hashedBlobSize == sizeof(detachedHashBlob),
|
---|
| 668 | "unexpected size of detached blob %d\n", hashedBlobSize);
|
---|
| 669 | ok(!memcmp(hashedBlob, detachedHashBlob, hashedBlobSize),
|
---|
| 670 | "unexpected detached blob value\n");
|
---|
| 671 | HeapFree(GetProcessHeap(), 0, hashedBlob);
|
---|
| 672 | }
|
---|
| 673 | /* Hashing a single item with fDetached = FALSE also succeeds */
|
---|
| 674 | SetLastError(0xdeadbeef);
|
---|
| 675 | ret = CryptHashMessage(¶, FALSE, 1, toHash, hashSize, NULL,
|
---|
| 676 | &hashedBlobSize, NULL, NULL);
|
---|
| 677 | ok(ret, "CryptHashMessage failed: 0x%08x\n", GetLastError());
|
---|
| 678 | if (ret)
|
---|
| 679 | {
|
---|
| 680 | hashedBlob = HeapAlloc(GetProcessHeap(), 0, hashedBlobSize);
|
---|
| 681 | ret = CryptHashMessage(¶, FALSE, 1, toHash, hashSize, hashedBlob,
|
---|
| 682 | &hashedBlobSize, NULL, NULL);
|
---|
| 683 | ok(ret, "CryptHashMessage failed: 0x%08x\n", GetLastError());
|
---|
| 684 | ok(hashedBlobSize == sizeof(hashBlob),
|
---|
| 685 | "unexpected size of detached blob %d\n", hashedBlobSize);
|
---|
| 686 | ok(!memcmp(hashedBlob, hashBlob, hashedBlobSize),
|
---|
| 687 | "unexpected detached blob value\n");
|
---|
| 688 | HeapFree(GetProcessHeap(), 0, hashedBlob);
|
---|
| 689 | }
|
---|
| 690 | /* Check the computed hash value too. You don't need to get the encoded
|
---|
| 691 | * blob to get it.
|
---|
| 692 | */
|
---|
| 693 | computedHashSize = 0xdeadbeef;
|
---|
| 694 | ret = CryptHashMessage(¶, TRUE, 2, toHash, hashSize, NULL,
|
---|
| 695 | &hashedBlobSize, NULL, &computedHashSize);
|
---|
| 696 | ok(ret, "CryptHashMessage failed: 0x%08x\n", GetLastError());
|
---|
| 697 | ok(computedHashSize == 16, "expected hash size of 16, got %d\n",
|
---|
| 698 | computedHashSize);
|
---|
| 699 | if (ret)
|
---|
| 700 | {
|
---|
| 701 | computedHash = HeapAlloc(GetProcessHeap(), 0, computedHashSize);
|
---|
| 702 | SetLastError(0xdeadbeef);
|
---|
| 703 | ret = CryptHashMessage(¶, TRUE, 2, toHash, hashSize, NULL,
|
---|
| 704 | &hashedBlobSize, computedHash, &computedHashSize);
|
---|
| 705 | ok(computedHashSize == sizeof(hashVal),
|
---|
| 706 | "unexpected size of hash value %d\n", computedHashSize);
|
---|
| 707 | ok(!memcmp(computedHash, hashVal, computedHashSize),
|
---|
| 708 | "unexpected value\n");
|
---|
| 709 | HeapFree(GetProcessHeap(), 0, computedHash);
|
---|
| 710 | }
|
---|
| 711 | }
|
---|
| 712 |
|
---|
| 713 | START_TEST(message)
|
---|
| 714 | {
|
---|
| 715 | test_msg_get_signer_count();
|
---|
| 716 | test_verify_detached_message_hash();
|
---|
| 717 | test_verify_message_hash();
|
---|
| 718 | test_verify_detached_message_signature();
|
---|
| 719 | test_verify_message_signature();
|
---|
| 720 | test_hash_message();
|
---|
| 721 | }
|
---|