ReactOS 0.4.16-dev-91-g764881a
msg.c File Reference
#include <stdio.h>
#include <stdarg.h>
#include <windef.h>
#include <winbase.h>
#include <winerror.h>
#include <wincrypt.h>
#include "wine/test.h"
Include dependency graph for msg.c:

Go to the source code of this file.

Classes

struct  update_accum
 

Macros

#define CMSG_SIGNER_ENCODE_INFO_HAS_CMS_FIELDS
 
#define CMSG_SIGNED_ENCODE_INFO_HAS_CMS_FIELDS
 
#define GET_PROC(dll, func)
 

Functions

static BOOL (WINAPI *pCryptAcquireContextA)(HCRYPTPROV *
 
static void init_function_pointers (void)
 
static void test_msg_open_to_encode (void)
 
static void test_msg_open_to_decode (void)
 
static void test_msg_get_param (void)
 
static void test_msg_close (void)
 
static void check_param (LPCSTR test, HCRYPTMSG msg, DWORD param, const BYTE *expected, DWORD expectedSize)
 
static void test_data_msg_open (void)
 
static BOOL WINAPI nop_stream_output (const void *pvArg, BYTE *pb, DWORD cb, BOOL final)
 
static void test_data_msg_update (void)
 
static void test_data_msg_get_param (void)
 
static BOOL WINAPI accumulating_stream_output (const void *pvArg, BYTE *pb, DWORD cb, BOOL final)
 
static void check_updates (LPCSTR header, const struct update_accum *expected, const struct update_accum *got)
 
static void free_updates (struct update_accum *accum)
 
static void test_data_msg_encoding (void)
 
static void test_data_msg (void)
 
static void test_hash_msg_open (void)
 
static void test_hash_msg_update (void)
 
static void test_hash_msg_get_param (void)
 
static void test_hash_msg_encoding (void)
 
static void test_hash_msg (void)
 
static void test_signed_msg_open (void)
 
static void test_signed_msg_update (void)
 
static void test_signed_msg_encoding (void)
 
static void test_signed_msg_get_param (void)
 
static void test_signed_msg (void)
 
static void test_enveloped_msg_open (void)
 
static void test_enveloped_msg_update (void)
 
static void test_enveloped_msg_encoding (void)
 
static void test_enveloped_msg (void)
 
static void test_decode_msg_update (void)
 
static void compare_signer_info (const CMSG_SIGNER_INFO *got, const CMSG_SIGNER_INFO *expected)
 
static void compare_cms_signer_info (const CMSG_CMS_SIGNER_INFO *got, const CMSG_CMS_SIGNER_INFO *expected)
 
static void test_decode_msg_get_param (void)
 
static void test_decode_msg (void)
 
static void test_msg_control (void)
 
static BOOL detect_nt (void)
 
static void test_msg_get_and_verify_signer (void)
 
 START_TEST (msg)
 

Variables

static BOOL have_nt = TRUE
 
static BOOL old_crypt32 = FALSE
 
static char oid_rsa_md5 [] = szOID_RSA_MD5
 
static LPCSTR
 
static DWORD
 
static LPCWSTR
 
static const BYTE msgData [] = { 1, 2, 3, 4 }
 
static const BYTE dataEmptyBareContent [] = { 0x04,0x00 }
 
static const BYTE dataEmptyContent []
 
static const BYTE dataBareContent [] = { 0x04,0x04,0x01,0x02,0x03,0x04 }
 
static const BYTE dataContent []
 
static BYTE u1 []
 
static BYTE u2 [] = { 0x01,0x02,0x03,0x04 }
 
static CRYPT_DATA_BLOB b1 []
 
static const struct update_accum a1 = { ARRAY_SIZE(b1), b1 }
 
static BYTE u3 []
 
static CRYPT_DATA_BLOB b2 []
 
static const struct update_accum a2 = { ARRAY_SIZE(b2), b2 }
 
static BYTE u4 []
 
static BYTE u5 [] = { 0x04,0x04 }
 
static BYTE u6 [] = { 0x00,0x00,0x00,0x00,0x00,0x00 }
 
static CRYPT_DATA_BLOB b3 []
 
static const struct update_accum a3 = { ARRAY_SIZE(b3), b3 }
 
static const BYTE emptyHashParam []
 
static const BYTE hashEmptyBareContent []
 
static const BYTE hashEmptyContent []
 
static const BYTE hashBareContent []
 
static const BYTE hashContent []
 
static const BYTE detachedHashNonFinalBareContent []
 
static const BYTE detachedHashNonFinalContent []
 
static const BYTE detachedHashBareContent []
 
static const BYTE detachedHashContent []
 
static const CHAR cspNameA []
 
static const WCHAR cspNameW []
 
static BYTE serialNum [] = { 1 }
 
static BYTE encodedCommonName []
 
static const BYTE privKey []
 
static BYTE pubKey []
 
static const BYTE signedEmptyBareContent []
 
static const BYTE signedEmptyContent []
 
static const BYTE detachedSignedBareContent []
 
static const BYTE detachedSignedContent []
 
static const BYTE signedBareContent []
 
static const BYTE signedContent []
 
static const BYTE signedHash []
 
static const BYTE signedKeyIdEmptyContent []
 
static const BYTE signedEncodedSigner []
 
static const BYTE signedWithAuthAttrsBareContent []
 
static BYTE cert []
 
static BYTE v1CertWithPubKey []
 
static const BYTE signedWithCertEmptyBareContent []
 
static const BYTE signedWithCertBareContent []
 
static BYTE crl []
 
static const BYTE signedWithCrlEmptyBareContent []
 
static const BYTE signedWithCrlBareContent []
 
static const BYTE signedWithCertAndCrlEmptyBareContent []
 
static const BYTE signedWithCertAndCrlBareContent []
 
static const BYTE signedWithCertWithPubKeyBareContent []
 
static BYTE v1CertWithValidPubKey []
 
static const BYTE signedWithCertWithValidPubKeyEmptyContent []
 
static const BYTE signedWithCertWithValidPubKeyContent []
 
static char oid_rsa_rc4 [] = szOID_RSA_RC4
 
static const BYTE envelopedEmptyBareContent []
 
static const BYTE envelopedEmptyContent []
 
static CRYPT_DATA_BLOB b4 = { 0, NULL }
 
static const struct update_accum a4 = { 1, &b4 }
 
static const BYTE bogusOIDContent []
 
static const BYTE bogusHashContent []
 
static const BYTE envelopedBareContentWithoutData []
 
static const BYTE hashParam []
 
static const BYTE signedWithCertAndCrlComputedHash []
 
static BYTE keyIdIssuer []
 
static const BYTE publicPrivateKeyPair []
 
static const BYTE envelopedMessage []
 
static const BYTE envelopedBareMessage []
 
static const BYTE envelopedMessageWith3Recps []
 
static const BYTE serialNumber []
 
static const BYTE issuer []
 
static BYTE aKey [] = { 0,1,2,3,4,5,6,7,8,9,0xa,0xb,0xc,0xd,0xe,0xf }
 
static BYTE encodedPubKey []
 
static BYTE mod_encoded []
 

Macro Definition Documentation

◆ CMSG_SIGNED_ENCODE_INFO_HAS_CMS_FIELDS

#define CMSG_SIGNED_ENCODE_INFO_HAS_CMS_FIELDS

Definition at line 27 of file msg.c.

◆ CMSG_SIGNER_ENCODE_INFO_HAS_CMS_FIELDS

#define CMSG_SIGNER_ENCODE_INFO_HAS_CMS_FIELDS

Definition at line 26 of file msg.c.

◆ GET_PROC

#define GET_PROC (   dll,
  func 
)
Value:
p ## func = (void *)GetProcAddress(dll, #func); \
if(!p ## func) \
trace("GetProcAddress(%s) failed\n", #func);
#define GetProcAddress(x, y)
Definition: compat.h:753
GLenum func
Definition: glext.h:6028
GLfloat GLfloat p
Definition: glext.h:8902
static HMODULE dll
Definition: str.c:188

Function Documentation

◆ accumulating_stream_output()

static BOOL WINAPI accumulating_stream_output ( const void pvArg,
BYTE pb,
DWORD  cb,
BOOL  final 
)
static

Definition at line 542 of file msg.c.

544{
545 struct update_accum *accum = (struct update_accum *)pvArg;
546 BOOL ret = FALSE;
547
548 if (accum->cUpdates)
549 accum->updates = CryptMemRealloc(accum->updates,
550 (accum->cUpdates + 1) * sizeof(CRYPT_DATA_BLOB));
551 else
552 accum->updates = CryptMemAlloc(sizeof(CRYPT_DATA_BLOB));
553 if (accum->updates)
554 {
555 CRYPT_DATA_BLOB *blob = &accum->updates[accum->cUpdates];
556
557 blob->pbData = CryptMemAlloc(cb);
558 if (blob->pbData)
559 {
560 memcpy(blob->pbData, pb, cb);
561 blob->cbData = cb;
562 ret = TRUE;
563 }
564 accum->cUpdates++;
565 }
566 return ret;
567}
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
LPVOID WINAPI CryptMemAlloc(ULONG cbSize)
Definition: main.c:131
LPVOID WINAPI CryptMemRealloc(LPVOID pv, ULONG cbSize)
Definition: main.c:136
unsigned int BOOL
Definition: ntddk_ex.h:94
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static HMODULE MODULEINFO DWORD cb
Definition: module.c:33
Definition: image.c:134
DWORD cUpdates
Definition: msg.c:538
CRYPT_DATA_BLOB * updates
Definition: msg.c:539
int ret

Referenced by test_data_msg_encoding(), test_decode_msg_update(), test_get_digest_stream(), and test_hash_msg_encoding().

◆ BOOL()

static BOOL ( WINAPI pCryptAcquireContextA)
static

◆ check_param()

static void check_param ( LPCSTR  test,
HCRYPTMSG  msg,
DWORD  param,
const BYTE expected,
DWORD  expectedSize 
)
static

Definition at line 288 of file msg.c.

290{
291 DWORD size;
292 LPBYTE buf;
293 BOOL ret;
294
295 size = 0xdeadbeef;
297 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */ ||
298 GetLastError() == CRYPT_E_INVALID_MSG_TYPE /* Win9x, for some params */),
299 "%s: CryptMsgGetParam failed: %08x\n", test, GetLastError());
300 if (!ret)
301 {
302 win_skip("parameter %d not supported, skipping tests\n", param);
303 return;
304 }
307 ok(ret, "%s: CryptMsgGetParam failed: %08x\n", test, GetLastError());
308 ok(size == expectedSize, "%s: expected size %d, got %d\n", test,
309 expectedSize, size);
310 if (size == expectedSize && size)
311 ok(!memcmp(buf, expected, size), "%s: unexpected data\n", test);
313}
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define ok(value,...)
Definition: atltest.h:57
#define broken(x)
Definition: atltest.h:178
#define msg(x)
Definition: auth_time.c:54
#define NULL
Definition: types.h:112
BOOL WINAPI CryptMsgGetParam(HCRYPTMSG hCryptMsg, DWORD dwParamType, DWORD dwIndex, void *pvData, DWORD *pcbData)
Definition: msg.c:3626
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define HeapFree(x, y, z)
Definition: compat.h:735
unsigned long DWORD
Definition: ntddk_ex.h:95
GLsizeiptr size
Definition: glext.h:5919
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLfloat param
Definition: glext.h:5796
BOOL expected
Definition: store.c:2063
#define test
Definition: rosglue.h:37
#define win_skip
Definition: test.h:163
unsigned char * LPBYTE
Definition: typedefs.h:53
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define OSS_LIMITED
Definition: winerror.h:3047
#define CRYPT_E_INVALID_MSG_TYPE
Definition: winerror.h:2988

Referenced by test_data_msg_encoding(), test_decode_msg_get_param(), test_enveloped_msg_encoding(), test_hash_msg_encoding(), and test_signed_msg_encoding().

◆ check_updates()

static void check_updates ( LPCSTR  header,
const struct update_accum expected,
const struct update_accum got 
)
static

Definition at line 602 of file msg.c.

604{
605 DWORD i;
606
607 ok(expected->cUpdates == got->cUpdates,
608 "%s: expected %d updates, got %d\n", header, expected->cUpdates,
609 got->cUpdates);
610 if (expected->cUpdates == got->cUpdates)
611 for (i = 0; i < min(expected->cUpdates, got->cUpdates); i++)
612 {
613 ok(expected->updates[i].cbData == got->updates[i].cbData,
614 "%s, update %d: expected %d bytes, got %d\n", header, i,
615 expected->updates[i].cbData, got->updates[i].cbData);
616 if (expected->updates[i].cbData && expected->updates[i].cbData ==
617 got->updates[i].cbData)
618 ok(!memcmp(expected->updates[i].pbData, got->updates[i].pbData,
619 got->updates[i].cbData), "%s, update %d: unexpected value\n",
620 header, i);
621 }
622}
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define min(a, b)
Definition: monoChain.cc:55
BYTE * pbData
Definition: wincrypt.h:103

Referenced by test_data_msg_encoding(), test_decode_msg_update(), test_get_digest_stream(), and test_hash_msg_encoding().

◆ compare_cms_signer_info()

static void compare_cms_signer_info ( const CMSG_CMS_SIGNER_INFO got,
const CMSG_CMS_SIGNER_INFO expected 
)
static

Definition at line 2679 of file msg.c.

2681{
2682 ok(got->dwVersion == expected->dwVersion, "Expected version %d, got %d\n",
2683 expected->dwVersion, got->dwVersion);
2684 ok(got->SignerId.dwIdChoice == expected->SignerId.dwIdChoice,
2685 "Expected id choice %d, got %d\n", expected->SignerId.dwIdChoice,
2686 got->SignerId.dwIdChoice);
2687 if (got->SignerId.dwIdChoice == expected->SignerId.dwIdChoice)
2688 {
2690 {
2691 ok(U(got->SignerId).IssuerSerialNumber.Issuer.cbData ==
2692 U(expected->SignerId).IssuerSerialNumber.Issuer.cbData,
2693 "Expected issuer size %d, got %d\n",
2694 U(expected->SignerId).IssuerSerialNumber.Issuer.cbData,
2695 U(got->SignerId).IssuerSerialNumber.Issuer.cbData);
2696 ok(!memcmp(U(got->SignerId).IssuerSerialNumber.Issuer.pbData,
2697 U(expected->SignerId).IssuerSerialNumber.Issuer.pbData,
2698 U(got->SignerId).IssuerSerialNumber.Issuer.cbData),
2699 "Unexpected issuer\n");
2700 ok(U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
2701 U(expected->SignerId).IssuerSerialNumber.SerialNumber.cbData,
2702 "Expected serial number size %d, got %d\n",
2703 U(expected->SignerId).IssuerSerialNumber.SerialNumber.cbData,
2704 U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData);
2705 ok(!memcmp(U(got->SignerId).IssuerSerialNumber.SerialNumber.pbData,
2706 U(expected->SignerId).IssuerSerialNumber.SerialNumber.pbData,
2707 U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData),
2708 "Unexpected serial number\n");
2709 }
2710 else
2711 {
2712 ok(U(got->SignerId).KeyId.cbData == U(expected->SignerId).KeyId.cbData,
2713 "expected key id size %d, got %d\n",
2714 U(expected->SignerId).KeyId.cbData, U(got->SignerId).KeyId.cbData);
2715 ok(!memcmp(U(expected->SignerId).KeyId.pbData,
2716 U(got->SignerId).KeyId.pbData, U(got->SignerId).KeyId.cbData),
2717 "unexpected key id\n");
2718 }
2719 }
2720 /* FIXME: check more things */
2721}
#define U(x)
Definition: wordpad.c:45
DWORD dwIdChoice
Definition: wincrypt.h:3665
#define CERT_ID_ISSUER_SERIAL_NUMBER
Definition: wincrypt.h:3673

Referenced by test_decode_msg_get_param().

◆ compare_signer_info()

static void compare_signer_info ( const CMSG_SIGNER_INFO got,
const CMSG_SIGNER_INFO expected 
)
static

Definition at line 2661 of file msg.c.

2663{
2664 ok(got->dwVersion == expected->dwVersion, "Expected version %d, got %d\n",
2665 expected->dwVersion, got->dwVersion);
2666 ok(got->Issuer.cbData == expected->Issuer.cbData,
2667 "Expected issuer size %d, got %d\n", expected->Issuer.cbData,
2668 got->Issuer.cbData);
2669 ok(!memcmp(got->Issuer.pbData, expected->Issuer.pbData, got->Issuer.cbData),
2670 "Unexpected issuer\n");
2671 ok(got->SerialNumber.cbData == expected->SerialNumber.cbData,
2672 "Expected serial number size %d, got %d\n", expected->SerialNumber.cbData,
2673 got->SerialNumber.cbData);
2674 ok(!memcmp(got->SerialNumber.pbData, expected->SerialNumber.pbData,
2675 got->SerialNumber.cbData), "Unexpected serial number\n");
2676 /* FIXME: check more things */
2677}
CERT_NAME_BLOB Issuer
Definition: wincrypt.h:770
CRYPT_INTEGER_BLOB SerialNumber
Definition: wincrypt.h:771

Referenced by test_decode_msg_get_param().

◆ detect_nt()

static BOOL detect_nt ( void  )
static

Definition at line 3602 of file msg.c.

3603{
3604 BOOL ret;
3605 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
3606 CERT_INFO certInfo = { 0 };
3607
3608 if (!pCryptAcquireContextW)
3609 return FALSE;
3610
3611 certInfo.SerialNumber.cbData = sizeof(serialNum);
3612 certInfo.SerialNumber.pbData = serialNum;
3613 certInfo.Issuer.cbData = sizeof(encodedCommonName);
3614 certInfo.Issuer.pbData = encodedCommonName;
3615 signer.pCertInfo = &certInfo;
3617
3618 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
3620 if (!ret && GetLastError() == NTE_EXISTS) {
3621 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
3622 PROV_RSA_FULL, 0);
3623 }
3624
3625 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) return FALSE;
3626
3627 /* cleanup */
3629 pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, PROV_RSA_FULL,
3631
3632 return TRUE;
3633}
BOOL WINAPI CryptReleaseContext(HCRYPTPROV hProv, DWORD dwFlags)
Definition: crypt.c:648
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:102
static BYTE serialNum[]
Definition: msg.c:1072
static BYTE encodedCommonName[]
Definition: msg.c:1073
static const WCHAR cspNameW[]
Definition: msg.c:1070
static char oid_rsa_md5[]
Definition: msg.c:34
CERT_NAME_BLOB Issuer
Definition: wincrypt.h:244
CRYPT_INTEGER_BLOB SerialNumber
Definition: wincrypt.h:242
CRYPT_ALGORITHM_IDENTIFIER HashAlgorithm
Definition: wincrypt.h:3714
#define CRYPT_NEWKEYSET
Definition: wincrypt.h:2070
#define PROV_RSA_FULL
Definition: wincrypt.h:2039
#define CRYPT_DELETEKEYSET
Definition: wincrypt.h:2071
#define NTE_EXISTS
Definition: winerror.h:2883

Referenced by START_TEST().

◆ free_updates()

static void free_updates ( struct update_accum accum)
static

Definition at line 625 of file msg.c.

626{
627 DWORD i;
628
629 for (i = 0; i < accum->cUpdates; i++)
630 CryptMemFree(accum->updates[i].pbData);
631 CryptMemFree(accum->updates);
632 accum->updates = NULL;
633 accum->cUpdates = 0;
634}
VOID WINAPI CryptMemFree(LPVOID pv)
Definition: main.c:141

Referenced by test_data_msg_encoding(), test_decode_msg_update(), test_get_digest_stream(), and test_hash_msg_encoding().

◆ init_function_pointers()

static void init_function_pointers ( void  )
static

Definition at line 41 of file msg.c.

42{
43 HMODULE hAdvapi32 = GetModuleHandleA("advapi32.dll");
44
45#define GET_PROC(dll, func) \
46 p ## func = (void *)GetProcAddress(dll, #func); \
47 if(!p ## func) \
48 trace("GetProcAddress(%s) failed\n", #func);
49
52
53#undef GET_PROC
54}
BOOL WINAPI CryptAcquireContextA(HCRYPTPROV *phProv, LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType, DWORD dwFlags)
Definition: crypt.c:569
BOOL WINAPI CryptAcquireContextW(HCRYPTPROV *phProv, LPCWSTR pszContainer, LPCWSTR pszProvider, DWORD dwProvType, DWORD dwFlags)
Definition: crypt.c:358
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
#define GET_PROC(dll, func)

Referenced by START_TEST().

◆ nop_stream_output()

static BOOL WINAPI nop_stream_output ( const void pvArg,
BYTE pb,
DWORD  cb,
BOOL  final 
)
static

◆ START_TEST()

START_TEST ( msg  )

Definition at line 3761 of file msg.c.

3762{
3764 have_nt = detect_nt();
3765 if (!have_nt)
3766 win_skip("Win9x crashes on some parameter checks\n");
3767
3768 /* I_CertUpdateStore can be used for verification if crypt32 is new enough */
3769 if (!GetProcAddress(GetModuleHandleA("crypt32.dll"), "I_CertUpdateStore"))
3770 {
3771 win_skip("Some tests will crash on older crypt32 implementations\n");
3772 old_crypt32 = TRUE;
3773 }
3774
3775 /* Basic parameter checking tests */
3781
3782 /* Message-type specific tests */
3783 test_data_msg();
3784 test_hash_msg();
3788
3790}
static void test_msg_open_to_decode(void)
Definition: msg.c:101
static void test_signed_msg(void)
Definition: msg.c:2043
static void test_msg_get_and_verify_signer(void)
Definition: msg.c:3635
static void init_function_pointers(void)
Definition: msg.c:41
static void test_enveloped_msg(void)
Definition: msg.c:2277
static BOOL old_crypt32
Definition: msg.c:33
static void test_msg_close(void)
Definition: msg.c:270
static void test_data_msg(void)
Definition: msg.c:715
static void test_msg_control(void)
Definition: msg.c:3205
static BOOL detect_nt(void)
Definition: msg.c:3602
static void test_msg_open_to_encode(void)
Definition: msg.c:56
static void test_decode_msg(void)
Definition: msg.c:3188
static void test_hash_msg(void)
Definition: msg.c:1060
static void test_msg_get_param(void)
Definition: msg.c:164
static BOOL have_nt
Definition: msg.c:32

◆ test_data_msg()

static void test_data_msg ( void  )
static

Definition at line 715 of file msg.c.

716{
721}
static void test_data_msg_get_param(void)
Definition: msg.c:480
static void test_data_msg_open(void)
Definition: msg.c:315
static void test_data_msg_encoding(void)
Definition: msg.c:636
static void test_data_msg_update(void)
Definition: msg.c:368

Referenced by START_TEST().

◆ test_data_msg_encoding()

static void test_data_msg_encoding ( void  )
static

Definition at line 636 of file msg.c.

637{
639 BOOL ret;
640 static char oid[] = "1.2.3";
641 struct update_accum accum = { 0, NULL };
642 CMSG_STREAM_INFO streamInfo = { 0, accumulating_stream_output, &accum };
643
645 NULL);
646 check_param("data empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
648 check_param("data empty content", msg, CMSG_CONTENT_PARAM, dataEmptyContent,
649 sizeof(dataEmptyContent));
651 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
652 check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
655 sizeof(dataContent));
657 /* Same test, but with CMSG_BARE_CONTENT_FLAG set */
660 check_param("data empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
662 check_param("data empty content", msg, CMSG_CONTENT_PARAM, dataEmptyContent,
663 sizeof(dataEmptyContent));
665 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
666 check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
669 sizeof(dataContent));
671 /* The inner OID is apparently ignored */
673 NULL);
674 check_param("data bogus oid bare content", msg, CMSG_BARE_CONTENT_PARAM,
676 check_param("data bogus oid content", msg, CMSG_CONTENT_PARAM,
679 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
680 check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
683 sizeof(dataContent));
685 /* A streaming message is DER encoded if the length is not 0xffffffff, but
686 * curiously, updates aren't validated to make sure they don't exceed the
687 * stated length. (The resulting output will of course fail to decode.)
688 */
690 NULL, &streamInfo);
694 check_updates("bogus data message with definite length", &a1, &accum);
695 free_updates(&accum);
696 /* A valid definite-length encoding: */
697 streamInfo.cbContent = sizeof(msgData);
699 NULL, &streamInfo);
702 check_updates("data message with definite length", &a2, &accum);
703 free_updates(&accum);
704 /* An indefinite-length encoding: */
705 streamInfo.cbContent = 0xffffffff;
707 NULL, &streamInfo);
711 check_updates("data message with indefinite length", &a3, &accum);
712 free_updates(&accum);
713}
HCRYPTMSG WINAPI CryptMsgOpenToEncode(DWORD dwMsgEncodingType, DWORD dwFlags, DWORD dwMsgType, const void *pvMsgEncodeInfo, LPSTR pszInnerContentObjID, PCMSG_STREAM_INFO pStreamInfo)
Definition: msg.c:2034
BOOL WINAPI CryptMsgUpdate(HCRYPTMSG hCryptMsg, const BYTE *pbData, DWORD cbData, BOOL fFinal)
Definition: msg.c:3616
BOOL WINAPI CryptMsgClose(HCRYPTMSG hCryptMsg)
Definition: msg.c:3597
static const BYTE dataBareContent[]
Definition: msg.c:531
static void check_updates(LPCSTR header, const struct update_accum *expected, const struct update_accum *got)
Definition: msg.c:602
static BOOL WINAPI accumulating_stream_output(const void *pvArg, BYTE *pb, DWORD cb, BOOL final)
Definition: msg.c:542
static void check_param(LPCSTR test, HCRYPTMSG msg, DWORD param, const BYTE *expected, DWORD expectedSize)
Definition: msg.c:288
static const struct update_accum a1
Definition: msg.c:578
static const struct update_accum a2
Definition: msg.c:586
static const BYTE dataEmptyContent[]
Definition: msg.c:528
static const BYTE dataContent[]
Definition: msg.c:532
static void free_updates(struct update_accum *accum)
Definition: msg.c:625
static const struct update_accum a3
Definition: msg.c:600
static const BYTE dataEmptyBareContent[]
Definition: msg.c:366
static const BYTE msgData[]
Definition: msg.c:358
#define CMSG_DATA
Definition: wincrypt.h:3679
#define CMSG_BARE_CONTENT_FLAG
Definition: wincrypt.h:3860
#define CMSG_BARE_CONTENT_PARAM
Definition: wincrypt.h:3927
#define PKCS_7_ASN_ENCODING
Definition: wincrypt.h:2299
#define CMSG_CONTENT_PARAM
Definition: wincrypt.h:3926

Referenced by test_data_msg().

◆ test_data_msg_get_param()

static void test_data_msg_get_param ( void  )
static

Definition at line 480 of file msg.c.

481{
483 DWORD size;
484 BOOL ret;
485 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
486
488 NULL);
489
490 /* Content and bare content are always gettable when not streaming */
491 size = 0;
493 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
494 size = 0;
496 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
497 /* But for this type of message, the signer and hash aren't applicable,
498 * and the type isn't available.
499 */
500 size = 0;
501 SetLastError(0xdeadbeef);
504 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
505 SetLastError(0xdeadbeef);
508 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
511 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
513
514 /* Can't get content or bare content when streaming */
516 NULL, &streamInfo);
517 SetLastError(0xdeadbeef);
519 ok((!ret && GetLastError() == E_INVALIDARG) || broken(ret /* Win9x */),
520 "Expected E_INVALIDARG, got %x\n", GetLastError());
521 SetLastError(0xdeadbeef);
523 ok((!ret && GetLastError() == E_INVALIDARG) || broken(ret /* Win9x */),
524 "Expected E_INVALIDARG, got %x\n", GetLastError());
526}
#define E_INVALIDARG
Definition: ddrawi.h:101
#define SetLastError(x)
Definition: compat.h:752
static BOOL WINAPI nop_stream_output(const void *pvArg, BYTE *pb, DWORD cb, BOOL final)
Definition: msg.c:360
#define CMSG_COMPUTED_HASH_PARAM
Definition: wincrypt.h:3945
#define CMSG_TYPE_PARAM
Definition: wincrypt.h:3925
#define CMSG_ENCODED_SIGNER
Definition: wincrypt.h:3948

Referenced by test_data_msg().

◆ test_data_msg_open()

static void test_data_msg_open ( void  )
static

Definition at line 315 of file msg.c.

316{
318 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
319 CMSG_STREAM_INFO streamInfo = { 0 };
320 char oid[] = "1.2.3";
321
322 /* The data message type takes no additional info */
323 SetLastError(0xdeadbeef);
325 NULL, NULL);
327 "Expected E_INVALIDARG, got %x\n", GetLastError());
329 NULL);
330 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
332
333 /* An empty stream info is allowed. */
335 &streamInfo);
336 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
338
339 /* Passing a bogus inner OID succeeds for a non-streamed message.. */
341 NULL);
342 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
344 /* and still succeeds when CMSG_DETACHED_FLAG is passed.. */
346 CMSG_DATA, NULL, oid, NULL);
347 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
349 /* and when a stream info is given, even though you're not supposed to be
350 * able to use anything but szOID_RSA_data when streaming is being used.
351 */
353 CMSG_DATA, NULL, oid, &streamInfo);
354 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
356}
#define CMSG_DETACHED_FLAG
Definition: wincrypt.h:3862

Referenced by test_data_msg().

◆ test_data_msg_update()

static void test_data_msg_update ( void  )
static

Definition at line 368 of file msg.c.

369{
371 BOOL ret;
372 CMSG_STREAM_INFO streamInfo = { 0 };
373
375 NULL);
376 /* Can't update a message that wasn't opened detached with final = FALSE */
377 SetLastError(0xdeadbeef);
380 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
381 /* Updating it with final = TRUE succeeds */
383 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
384 /* Any subsequent update will fail, as the last was final */
385 SetLastError(0xdeadbeef);
388 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
390
392 NULL);
393 /* Starting with Vista, can update a message with no data. */
395 ok(ret || broken(!ret), "CryptMsgUpdate failed: %08x\n", GetLastError());
396 if (ret)
397 {
398 DWORD size;
399
401 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
402 if (ret)
403 {
405
406 if (buf)
407 {
409 &size);
410 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
411 if (ret)
412 {
413 ok(size == sizeof(dataEmptyBareContent),
414 "unexpected size %d\n", size);
416 "unexpected value\n");
417 }
419 }
420 }
421 }
423
426 if (have_nt)
427 {
428 /* Doesn't appear to be able to update CMSG-DATA with non-final updates.
429 * On Win9x, this sometimes succeeds, sometimes fails with
430 * GetLastError() == 0, so it's not worth checking there.
431 */
432 SetLastError(0xdeadbeef);
434 ok(!ret &&
436 broken(GetLastError() == ERROR_SUCCESS)), /* Older NT4 */
437 "Expected E_INVALIDARG, got %x\n", GetLastError());
438 SetLastError(0xdeadbeef);
440 ok(!ret &&
442 broken(GetLastError() == ERROR_SUCCESS)), /* Older NT4 */
443 "Expected E_INVALIDARG, got %x\n", GetLastError());
444 }
445 else
446 skip("not updating CMSG_DATA with a non-final update\n");
448 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
450
451 if (!old_crypt32)
452 {
453 /* Calling update after opening with an empty stream info (with a bogus
454 * output function) yields an error:
455 */
456 /* Crashes on some Win9x */
458 &streamInfo);
459 SetLastError(0xdeadbeef);
463 "Expected STATUS_ACCESS_VIOLATION or STATUS_ILLEGAL_INSTRUCTION, got %x\n",
464 GetLastError());
466 }
467 /* Calling update with a valid output function succeeds, even if the data
468 * exceeds the size specified in the stream info.
469 */
472 &streamInfo);
474 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
476 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
478}
#define skip(...)
Definition: atltest.h:64
#define ERROR_SUCCESS
Definition: deptool.c:10
#define STATUS_ILLEGAL_INSTRUCTION
Definition: ntstatus.h:266
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242
PFN_CMSG_STREAM_OUTPUT pfnStreamOutput
Definition: wincrypt.h:3653
#define CRYPT_E_MSG_ERROR
Definition: winerror.h:2985

Referenced by test_data_msg().

◆ test_decode_msg()

static void test_decode_msg ( void  )
static

Definition at line 3188 of file msg.c.

3189{
3192}
static void test_decode_msg_update(void)
Definition: msg.c:2313
static void test_decode_msg_get_param(void)
Definition: msg.c:2854

Referenced by START_TEST().

◆ test_decode_msg_get_param()

static void test_decode_msg_get_param ( void  )
static

Definition at line 2854 of file msg.c.

2855{
2856 HCRYPTMSG msg;
2857 HCRYPTPROV hCryptProv;
2858 HCRYPTKEY key = 0;
2859 BOOL ret;
2860 DWORD size = 0, value, req_size;
2861 LPBYTE buf;
2862 CMSG_CTRL_DECRYPT_PARA decryptPara = { sizeof(decryptPara), 0 };
2863
2865 SetLastError(0xdeadbeef);
2868 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
2870 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2871 check_param("data content", msg, CMSG_CONTENT_PARAM, msgData,
2872 sizeof(msgData));
2874
2877 if (ret)
2878 {
2879 /* Crashes on some Win9x */
2880 check_param("empty hash content", msg, CMSG_CONTENT_PARAM, NULL, 0);
2881 check_param("empty hash hash data", msg, CMSG_HASH_DATA_PARAM, NULL, 0);
2882 check_param("empty hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2884 }
2888 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2889 check_param("hash content", msg, CMSG_CONTENT_PARAM, msgData,
2890 sizeof(msgData));
2891 check_param("hash hash data", msg, CMSG_HASH_DATA_PARAM, hashParam,
2892 sizeof(hashParam));
2893 check_param("hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2894 hashParam, sizeof(hashParam));
2895 /* Curiously, on NT-like systems, getting the hash of index 1 succeeds,
2896 * even though there's only one hash.
2897 */
2899 ok(ret || GetLastError() == OSS_DATA_ERROR /* Win9x */,
2900 "CryptMsgGetParam failed: %08x\n", GetLastError());
2901 if (ret)
2903 else
2904 buf = NULL;
2905 if (buf)
2906 {
2908 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2909 ok(size == sizeof(hashParam), "Unexpected size %d\n", size);
2910 ok(!memcmp(buf, hashParam, size), "Unexpected value\n");
2912 }
2914 (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2916 check_param("hash version", msg, CMSG_VERSION_PARAM, (const BYTE *)&value,
2917 sizeof(value));
2919
2922 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2923 check_param("signed content", msg, CMSG_CONTENT_PARAM, msgData,
2924 sizeof(msgData));
2926 (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2927 size = sizeof(value);
2928 value = 2112;
2930 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2931 ok(value == 1, "Expected 1 signer, got %d\n", value);
2932 size = 0;
2934 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
2935 "CryptMsgGetParam failed: %08x\n", GetLastError());
2936 if (ret)
2938 else
2939 buf = NULL;
2940 if (buf)
2941 {
2942 CMSG_SIGNER_INFO signer = { 0 };
2943
2944 signer.dwVersion = 1;
2945 signer.Issuer.cbData = sizeof(encodedCommonName);
2947 signer.SerialNumber.cbData = sizeof(serialNum);
2948 signer.SerialNumber.pbData = serialNum;
2950 req_size = size;
2951 size += 10;
2953 ok(size == req_size, "size = %u, expected %u\n", size, req_size);
2956 }
2957 /* Getting the CMS signer info of a PKCS7 message is possible. */
2958 size = 0;
2960 ok(ret || broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE /* Win9x */),
2961 "CryptMsgGetParam failed: %08x\n", GetLastError());
2962 if (ret)
2964 else
2965 buf = NULL;
2966 if (buf)
2967 {
2968 CMSG_CMS_SIGNER_INFO signer = { 0 };
2969
2970 signer.dwVersion = 1;
2972 U(signer.SignerId).IssuerSerialNumber.Issuer.cbData =
2973 sizeof(encodedCommonName);
2974 U(signer.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonName;
2975 U(signer.SignerId).IssuerSerialNumber.SerialNumber.cbData =
2976 sizeof(serialNum);
2977 U(signer.SignerId).IssuerSerialNumber.SerialNumber.pbData = serialNum;
2982 }
2983 /* index is ignored when getting signer count */
2984 size = sizeof(value);
2986 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2987 ok(value == 1, "Expected 1 signer, got %d\n", value);
2989 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2990 ok(value == 0, "Expected 0 certs, got %d\n", value);
2992 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2993 ok(value == 0, "Expected 0 CRLs, got %d\n", value);
2996 NULL);
2999 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3001 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3002 ok(value == 1, "Expected 1 cert, got %d\n", value);
3003 check_param("cert", msg, CMSG_CERT_PARAM, cert, sizeof(cert));
3005 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3006 ok(value == 1, "Expected 1 CRL, got %d\n", value);
3007 check_param("crl", msg, CMSG_CRL_PARAM, crl, sizeof(crl));
3008 check_param("signed with cert and CRL computed hash", msg,
3012
3015 sizeof(signedKeyIdEmptyContent), TRUE);
3016 if (!ret && GetLastError() == OSS_DATA_ERROR)
3017 {
3019 win_skip("Subsequent tests crash on some Win9x\n");
3020 return;
3021 }
3022 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3023 size = sizeof(value);
3025 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3026 ok(value == 1, "Expected 1 signer, got %d\n", value);
3027 /* Getting the regular (non-CMS) signer info from a CMS message is also
3028 * possible..
3029 */
3030 size = 0;
3032 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3033 if (ret)
3035 else
3036 buf = NULL;
3037 if (buf)
3038 {
3039 CMSG_SIGNER_INFO signer;
3040 BYTE zero = 0;
3041
3042 /* and here's the little oddity: for a CMS message using the key id
3043 * variant of a SignerId, retrieving the CMSG_SIGNER_INFO param yields
3044 * a signer with a zero (not empty) serial number, and whose issuer is
3045 * an RDN with OID szOID_KEYID_RDN, value type CERT_RDN_OCTET_STRING,
3046 * and value of the key id.
3047 */
3049 signer.Issuer.cbData = sizeof(keyIdIssuer);
3050 signer.Issuer.pbData = keyIdIssuer;
3051 signer.SerialNumber.cbData = 1;
3052 signer.SerialNumber.pbData = &zero;
3056 }
3057 size = 0;
3059 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3060 if (ret)
3062 else
3063 buf = NULL;
3064 if (buf)
3065 {
3066 CMSG_CMS_SIGNER_INFO signer = { 0 };
3067
3070 U(signer.SignerId).KeyId.cbData = sizeof(serialNum);
3071 U(signer.SignerId).KeyId.pbData = serialNum;
3076 }
3078
3080 NULL);
3083 check_param("enveloped empty bare content", msg, CMSG_CONTENT_PARAM, NULL,
3084 0);
3086
3089 TRUE);
3090 check_param("enveloped empty content", msg, CMSG_CONTENT_PARAM, NULL, 0);
3092
3093 pCryptAcquireContextA(&hCryptProv, NULL, MS_ENHANCED_PROV_A, PROV_RSA_FULL,
3095 SetLastError(0xdeadbeef);
3097 sizeof(publicPrivateKeyPair), 0, 0, &key);
3098 ok(ret ||
3099 broken(!ret && GetLastError() == NTE_PERM), /* WinME and some NT4 */
3100 "CryptImportKey failed: %08x\n", GetLastError());
3101
3104 check_param("enveloped message before decrypting", msg, CMSG_CONTENT_PARAM,
3105 envelopedMessage + sizeof(envelopedMessage) - 4, 4);
3106 if (key)
3107 {
3108 decryptPara.hCryptProv = hCryptProv;
3109 SetLastError(0xdeadbeef);
3110 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3111 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
3112 decryptPara.hCryptProv = 0;
3113 SetLastError(0xdeadbeef);
3114 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3116 "expected CRYPT_E_ALREADY_DECRYPTED, got %08x\n", GetLastError());
3117 check_param("enveloped message", msg, CMSG_CONTENT_PARAM, msgData,
3118 sizeof(msgData));
3119 }
3120 else
3121 win_skip("failed to import a key, skipping tests\n");
3123
3125 NULL);
3127 TRUE);
3128 check_param("enveloped bare message before decrypting", msg,
3130 sizeof(envelopedBareMessage) - 4, 4);
3131 if (key)
3132 {
3133 decryptPara.hCryptProv = hCryptProv;
3134 SetLastError(0xdeadbeef);
3135 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3136 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
3137 check_param("enveloped bare message", msg, CMSG_CONTENT_PARAM, msgData,
3138 sizeof(msgData));
3139 }
3140 else
3141 win_skip("failed to import a key, skipping tests\n");
3143
3144 if (key)
3146 CryptReleaseContext(hCryptProv, 0);
3147
3151 value = 3;
3152 check_param("recipient count", msg, CMSG_RECIPIENT_COUNT_PARAM,
3153 (const BYTE *)&value, sizeof(value));
3154 size = 0;
3155 SetLastError(0xdeadbeef);
3158 "expected CRYPT_E_INVALID_INDEX, got %08x\n", GetLastError());
3159 size = 0;
3160 SetLastError(0xdeadbeef);
3162 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3163 ok(size >= 142, "unexpected size: %u\n", size);
3164 if (ret)
3166 else
3167 buf = NULL;
3168 if (buf)
3169 {
3170 CERT_INFO *certInfo = (CERT_INFO *)buf;
3171
3172 SetLastError(0xdeadbeef);
3174 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3175 ok(certInfo->SerialNumber.cbData == sizeof(serialNumber),
3176 "unexpected serial number size: %u\n", certInfo->SerialNumber.cbData);
3178 sizeof(serialNumber)), "unexpected serial number\n");
3179 ok(certInfo->Issuer.cbData == sizeof(issuer),
3180 "unexpected issuer size: %u\n", certInfo->Issuer.cbData);
3181 ok(!memcmp(certInfo->Issuer.pbData, issuer, sizeof(issuer)),
3182 "unexpected issuer\n");
3184 }
3186}
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
BOOL WINAPI CryptDestroyKey(HCRYPTKEY hKey)
Definition: crypt.c:930
BOOL WINAPI CryptImportKey(HCRYPTPROV hProv, const BYTE *pbData, DWORD dwDataLen, HCRYPTKEY hPubKey, DWORD dwFlags, HCRYPTKEY *phKey)
Definition: crypt.c:1850
HCRYPTMSG WINAPI CryptMsgOpenToDecode(DWORD dwMsgEncodingType, DWORD dwFlags, DWORD dwMsgType, HCRYPTPROV_LEGACY hCryptProv, PCERT_INFO pRecipientInfo, PCMSG_STREAM_INFO pStreamInfo)
Definition: msg.c:3552
BOOL WINAPI CryptMsgControl(HCRYPTMSG hCryptMsg, DWORD dwFlags, DWORD dwCtrlType, const void *pvCtrlPara)
Definition: msg.c:3636
static WCHAR issuer[MAX_STRING_RESOURCE_LEN]
Definition: object.c:1905
static const BYTE signedWithCertAndCrlComputedHash[]
Definition: msg.c:2723
static void compare_cms_signer_info(const CMSG_CMS_SIGNER_INFO *got, const CMSG_CMS_SIGNER_INFO *expected)
Definition: msg.c:2679
static const BYTE envelopedBareMessage[]
Definition: msg.c:2788
static const BYTE publicPrivateKeyPair[]
Definition: msg.c:2729
static const BYTE envelopedMessageWith3Recps[]
Definition: msg.c:2805
static const BYTE envelopedEmptyContent[]
Definition: msg.c:2248
static const BYTE envelopedEmptyBareContent[]
Definition: msg.c:2244
static const BYTE hashContent[]
Definition: msg.c:938
static const BYTE signedWithCertAndCrlBareContent[]
Definition: msg.c:1544
static BYTE cert[]
Definition: msg.c:1437
static const BYTE signedContent[]
Definition: msg.c:1386
static const BYTE hashParam[]
Definition: msg.c:2658
static const BYTE signedKeyIdEmptyContent[]
Definition: msg.c:1403
static void compare_signer_info(const CMSG_SIGNER_INFO *got, const CMSG_SIGNER_INFO *expected)
Definition: msg.c:2661
static const BYTE serialNumber[]
Definition: msg.c:2848
static BYTE crl[]
Definition: msg.c:1495
static const BYTE hashEmptyContent[]
Definition: msg.c:929
static const BYTE envelopedMessage[]
Definition: msg.c:2770
static const BYTE emptyHashParam[]
Definition: msg.c:816
static BYTE keyIdIssuer[]
Definition: msg.c:2726
int zero
Definition: sehframes.cpp:29
CRYPT_ALGORITHM_IDENTIFIER HashAlgorithm
Definition: wincrypt.h:3964
CRYPT_ALGORITHM_IDENTIFIER HashAlgorithm
Definition: wincrypt.h:772
Definition: copy.c:22
Definition: pdh_main.c:94
#define CMSG_VERSION_PARAM
Definition: wincrypt.h:3950
#define CRYPT_VERIFYCONTEXT
Definition: wincrypt.h:2069
ULONG_PTR HCRYPTPROV
Definition: wincrypt.h:46
#define CERT_ID_KEY_IDENTIFIER
Definition: wincrypt.h:3674
#define CMSG_SIGNED_DATA_V3
Definition: wincrypt.h:3974
#define CMSG_CMS_SIGNER_INFO_PARAM
Definition: wincrypt.h:3959
#define CMSG_INNER_CONTENT_TYPE_PARAM
Definition: wincrypt.h:3928
#define CMSG_ENVELOPED
Definition: wincrypt.h:3681
#define CMSG_CTRL_DECRYPT
Definition: wincrypt.h:3870
#define CMSG_RECIPIENT_INFO_PARAM
Definition: wincrypt.h:3942
#define CMSG_SIGNER_INFO_PARAM
Definition: wincrypt.h:3930
#define CMSG_SIGNED
Definition: wincrypt.h:3680
#define CMSG_HASHED_DATA_V0
Definition: wincrypt.h:3983
#define CMSG_CRL_PARAM
Definition: wincrypt.h:3938
#define MS_ENHANCED_PROV_A
Definition: wincrypt.h:1874
#define CMSG_SIGNER_COUNT_PARAM
Definition: wincrypt.h:3929
#define szOID_RSA_data
Definition: wincrypt.h:3028
#define CMSG_HASH_DATA_PARAM
Definition: wincrypt.h:3944
ULONG_PTR HCRYPTKEY
Definition: wincrypt.h:49
#define CMSG_CERT_COUNT_PARAM
Definition: wincrypt.h:3935
#define CMSG_RECIPIENT_COUNT_PARAM
Definition: wincrypt.h:3940
#define CMSG_CRL_COUNT_PARAM
Definition: wincrypt.h:3937
#define CMSG_CERT_PARAM
Definition: wincrypt.h:3936
#define CRYPT_E_INVALID_INDEX
Definition: winerror.h:2992
#define NTE_PERM
Definition: winerror.h:2884
#define OSS_DATA_ERROR
Definition: winerror.h:3042
#define CRYPT_E_ALREADY_DECRYPTED
Definition: winerror.h:2993
unsigned char BYTE
Definition: xxhash.c:193

Referenced by test_decode_msg().

◆ test_decode_msg_update()

static void test_decode_msg_update ( void  )
static

Definition at line 2313 of file msg.c.

2314{
2315 HCRYPTMSG msg;
2316 BOOL ret;
2317 CMSG_STREAM_INFO streamInfo = { 0 };
2318 DWORD i;
2319 struct update_accum accum = { 0, NULL };
2320
2322 /* Update with a full message in a final update */
2324 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2325 /* Can't update after a final update */
2326 SetLastError(0xdeadbeef);
2329 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
2331
2333 /* Can't send a non-final update without streaming */
2334 SetLastError(0xdeadbeef);
2336 FALSE);
2338 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
2339 /* A subsequent final update succeeds */
2341 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2343
2344 if (!old_crypt32)
2345 {
2346 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2347 /* Updating a message that has a NULL stream callback fails */
2348 SetLastError(0xdeadbeef);
2349 /* Crashes on some Win9x */
2351 FALSE);
2352 todo_wine
2354 GetLastError() == STATUS_ILLEGAL_INSTRUCTION /* WinME */),
2355 "Expected STATUS_ACCESS_VIOLATION or STATUS_ILLEGAL_INSTRUCTION, got %x\n",
2356 GetLastError());
2357 /* Changing the callback pointer after the fact yields the same error (so
2358 * the message must copy the stream info, not just store a pointer to it)
2359 */
2361 SetLastError(0xdeadbeef);
2363 FALSE);
2364 todo_wine
2366 GetLastError() == STATUS_ILLEGAL_INSTRUCTION /* WinME */),
2367 "Expected STATUS_ACCESS_VIOLATION or STATUS_ILLEGAL_INSTRUCTION, got %x\n",
2368 GetLastError());
2370 }
2371
2372 /* Empty non-final updates are allowed when streaming.. */
2373 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2375 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2376 /* but final updates aren't when not enough data has been received. */
2377 SetLastError(0xdeadbeef);
2378 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2379 todo_wine
2381 "Expected CRYPT_E_STREAM_INSUFFICIENT_DATA, got %x\n", GetLastError());
2383
2384 /* Updating the message byte by byte is legal */
2386 streamInfo.pvArg = &accum;
2387 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2388 for (i = 0, ret = TRUE; ret && i < sizeof(dataEmptyContent); i++)
2390 ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
2391 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2392 ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
2394 todo_wine
2395 check_updates("byte-by-byte empty content", &a4, &accum);
2396 free_updates(&accum);
2397
2398 /* Decoding bogus content fails in non-streaming mode.. */
2400 SetLastError(0xdeadbeef);
2401 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2403 GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2404 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2405 GetLastError());
2407 /* and as the final update in streaming mode.. */
2409 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2410 SetLastError(0xdeadbeef);
2411 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2413 GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2414 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2415 GetLastError());
2417 /* and even as a non-final update in streaming mode. */
2419 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2420 SetLastError(0xdeadbeef);
2421 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2422 todo_wine
2424 GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2425 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2426 GetLastError());
2428
2429 /* An empty message can be opened with undetermined type.. */
2432 TRUE);
2433 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2435 /* but decoding it as an explicitly typed message fails. */
2437 NULL);
2438 SetLastError(0xdeadbeef);
2440 TRUE);
2442 GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2443 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2444 GetLastError());
2446 /* On the other hand, decoding the bare content of an empty message fails
2447 * with unspecified type..
2448 */
2450 SetLastError(0xdeadbeef);
2452 sizeof(dataEmptyBareContent), TRUE);
2454 GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2455 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2456 GetLastError());
2458 /* but succeeds with explicit type. */
2460 NULL);
2462 sizeof(dataEmptyBareContent), TRUE);
2463 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2465
2466 /* Decoding valid content with an unsupported OID fails */
2468 SetLastError(0xdeadbeef);
2471 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
2473
2474 /* Similarly, opening an empty hash with unspecified type succeeds.. */
2476 SetLastError(0xdeadbeef);
2478 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
2479 "CryptMsgUpdate failed: %08x\n", GetLastError());
2481 /* while with specified type it fails. */
2483 NULL);
2484 SetLastError(0xdeadbeef);
2487 GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2488 GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2489 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2490 GetLastError());
2492 /* On the other hand, decoding the bare content of an empty hash message
2493 * fails with unspecified type..
2494 */
2496 SetLastError(0xdeadbeef);
2498 sizeof(hashEmptyBareContent), TRUE);
2500 GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2501 GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2502 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2503 GetLastError());
2505 /* but succeeds with explicit type. */
2507 NULL);
2509 sizeof(hashEmptyBareContent), TRUE);
2510 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* win9x */),
2511 "CryptMsgUpdate failed: %x\n", GetLastError());
2513
2514 /* And again, opening a (non-empty) hash message with unspecified type
2515 * succeeds..
2516 */
2518 SetLastError(0xdeadbeef);
2520 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2522 /* while with specified type it fails.. */
2524 NULL);
2525 SetLastError(0xdeadbeef);
2528 GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2529 GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2530 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2531 GetLastError());
2533 /* and decoding the bare content of a non-empty hash message fails with
2534 * unspecified type..
2535 */
2537 SetLastError(0xdeadbeef);
2540 GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2541 GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2542 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2543 GetLastError());
2545 /* but succeeds with explicit type. */
2547 NULL);
2549 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2551
2552 /* Opening a (non-empty) hash message with unspecified type and a bogus
2553 * hash value succeeds..
2554 */
2556 SetLastError(0xdeadbeef);
2558 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2560
2563 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2566 SetLastError(0xdeadbeef);
2570 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2571 "Expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
2572 GetLastError());
2575 NULL);
2578 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2580
2582 NULL, NULL);
2583 /* The first update succeeds.. */
2585 sizeof(detachedSignedContent), TRUE);
2586 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2587 /* as does a second (probably to update the detached portion).. */
2589 sizeof(detachedSignedContent), TRUE);
2590 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2591 /* while a third fails. */
2593 sizeof(detachedSignedContent), TRUE);
2595 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2597
2600 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2601 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2602 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2604 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2605 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2606 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2607
2610 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2612
2614 NULL);
2615 SetLastError(0xdeadbeef);
2618 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2620
2622 NULL);
2623 SetLastError(0xdeadbeef);
2625 sizeof(envelopedEmptyContent), TRUE);
2626 ok(!ret &&
2628 GetLastError() == OSS_DATA_ERROR), /* Win9x */
2629 "expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2631
2633 SetLastError(0xdeadbeef);
2636 ok(!ret &&
2638 GetLastError() == OSS_DATA_ERROR), /* Win9x */
2639 "expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2641
2643 SetLastError(0xdeadbeef);
2645 sizeof(envelopedEmptyContent), TRUE);
2646 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2648
2650 NULL);
2651 SetLastError(0xdeadbeef);
2654 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2656}
static const BYTE bogusOIDContent[]
Definition: msg.c:2287
static const BYTE hashEmptyBareContent[]
Definition: msg.c:926
static const BYTE hashBareContent[]
Definition: msg.c:933
static const BYTE bogusHashContent[]
Definition: msg.c:2290
static const BYTE envelopedBareContentWithoutData[]
Definition: msg.c:2296
static const BYTE detachedSignedContent[]
Definition: msg.c:1361
static const struct update_accum a4
Definition: msg.c:2285
#define todo_wine
Definition: custom.c:89
#define CMSG_HASHED
Definition: wincrypt.h:3683
#define CRYPT_E_STREAM_INSUFFICIENT_DATA
Definition: winerror.h:3001
#define OSS_PDU_MISMATCH
Definition: winerror.h:3046
#define CRYPT_E_ASN1_BADTAG
Definition: winerror.h:3095

Referenced by test_decode_msg().

◆ test_enveloped_msg()

static void test_enveloped_msg ( void  )
static

Definition at line 2277 of file msg.c.

2278{
2282}
static void test_enveloped_msg_encoding(void)
Definition: msg.c:2254
static void test_enveloped_msg_update(void)
Definition: msg.c:2120
static void test_enveloped_msg_open(void)
Definition: msg.c:2053

Referenced by START_TEST().

◆ test_enveloped_msg_encoding()

static void test_enveloped_msg_encoding ( void  )
static

Definition at line 2254 of file msg.c.

2255{
2256 HCRYPTMSG msg;
2257 CMSG_ENVELOPED_ENCODE_INFO envelopedInfo = { sizeof(envelopedInfo), 0,
2258 { oid_rsa_rc4, { 0, NULL } }, NULL };
2259
2260 SetLastError(0xdeadbeef);
2262 &envelopedInfo, NULL, NULL);
2263 ok(msg != NULL ||
2264 broken(!msg), /* Win9x */
2265 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2266 if (msg)
2267 {
2268 check_param("enveloped empty bare content", msg,
2271 check_param("enveloped empty content", msg, CMSG_CONTENT_PARAM,
2274 }
2275}
static char oid_rsa_rc4[]
Definition: msg.c:2051

Referenced by test_enveloped_msg().

◆ test_enveloped_msg_open()

static void test_enveloped_msg_open ( void  )
static

Definition at line 2053 of file msg.c.

2054{
2055 HCRYPTMSG msg;
2056 BOOL ret;
2057 CMSG_ENVELOPED_ENCODE_INFO envelopedInfo = { 0 };
2059
2060 SetLastError(0xdeadbeef);
2062 &envelopedInfo, NULL, NULL);
2064 "expected E_INVALIDARG, got %08x\n", GetLastError());
2065
2066 envelopedInfo.cbSize = sizeof(envelopedInfo);
2067 SetLastError(0xdeadbeef);
2069 &envelopedInfo, NULL, NULL);
2070 ok(!msg &&
2072 GetLastError() == E_INVALIDARG), /* Win9x */
2073 "expected CRYPT_E_UNKNOWN_ALGO or E_INVALIDARG, got %08x\n", GetLastError());
2074
2076 SetLastError(0xdeadbeef);
2078 &envelopedInfo, NULL, NULL);
2079 ok(msg != NULL ||
2080 broken(!msg), /* Win9x */
2081 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2083
2084 envelopedInfo.cRecipients = 1;
2085 if (!old_crypt32)
2086 {
2087 SetLastError(0xdeadbeef);
2089 &envelopedInfo, NULL, NULL);
2091 "expected E_INVALIDARG, got %08x\n", GetLastError());
2092 }
2093
2096 if (context)
2097 {
2098 envelopedInfo.rgpRecipientCert = (PCERT_INFO *)&context->pCertInfo;
2099 SetLastError(0xdeadbeef);
2101 &envelopedInfo, NULL, NULL);
2102 ok(msg != NULL, "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2104 SetLastError(0xdeadbeef);
2105 ret = pCryptAcquireContextA(&envelopedInfo.hCryptProv, NULL, NULL,
2107 ok(ret, "CryptAcquireContextA failed: %08x\n", GetLastError());
2108 SetLastError(0xdeadbeef);
2110 &envelopedInfo, NULL, NULL);
2111 ok(msg != NULL, "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2113 CryptReleaseContext(envelopedInfo.hCryptProv, 0);
2115 }
2116 else
2117 win_skip("failed to create certificate context, skipping tests\n");
2118}
BOOL WINAPI CertFreeCertificateContext(PCCERT_CONTEXT pCertContext)
Definition: cert.c:371
PCCERT_CONTEXT WINAPI CertCreateCertificateContext(DWORD dwCertEncodingType, const BYTE *pbCertEncoded, DWORD cbCertEncoded)
Definition: cert.c:316
static BYTE v1CertWithValidPubKey[]
Definition: msg.c:1585
HCRYPTPROV_LEGACY hCryptProv
Definition: wincrypt.h:3819
PCERT_INFO * rgpRecipientCert
Definition: wincrypt.h:3823
CRYPT_ALGORITHM_IDENTIFIER ContentEncryptionAlgorithm
Definition: wincrypt.h:3820
Definition: http.c:7252
#define X509_ASN_ENCODING
Definition: wincrypt.h:2297
#define CRYPT_E_UNKNOWN_ALGO
Definition: winerror.h:2986

Referenced by test_enveloped_msg().

◆ test_enveloped_msg_update()

static void test_enveloped_msg_update ( void  )
static

Definition at line 2120 of file msg.c.

2121{
2122 HCRYPTMSG msg;
2123 BOOL ret;
2124 CMSG_ENVELOPED_ENCODE_INFO envelopedInfo = { sizeof(envelopedInfo), 0,
2125 { oid_rsa_rc4, { 0, NULL } }, NULL };
2126 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
2127
2128 SetLastError(0xdeadbeef);
2130 &envelopedInfo, NULL, NULL);
2131 ok(msg != NULL ||
2132 broken(!msg), /* Win9x */
2133 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2134 if (msg)
2135 {
2136 SetLastError(0xdeadbeef);
2139 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2140 SetLastError(0xdeadbeef);
2141 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2142 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2143 SetLastError(0xdeadbeef);
2144 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2146 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2148 }
2149 SetLastError(0xdeadbeef);
2151 &envelopedInfo, NULL, NULL);
2152 ok(msg != NULL ||
2153 broken(!msg), /* Win9x */
2154 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2155 if (msg)
2156 {
2157 SetLastError(0xdeadbeef);
2158 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2160 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2161 SetLastError(0xdeadbeef);
2162 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2163 ok(ret ||
2164 broken(!ret && GetLastError() == NTE_PERM), /* some NT4 */
2165 "CryptMsgUpdate failed: %08x\n", GetLastError());
2166 SetLastError(0xdeadbeef);
2167 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2169 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2171 }
2172 SetLastError(0xdeadbeef);
2174 CMSG_ENVELOPED, &envelopedInfo, NULL, NULL);
2175 ok(msg != NULL ||
2176 broken(!msg), /* Win9x */
2177 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2178 if (msg)
2179 {
2180 SetLastError(0xdeadbeef);
2183 "expected E_INVALIDARG, got %08x\n", GetLastError());
2184 SetLastError(0xdeadbeef);
2185 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2186 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2188 }
2189 SetLastError(0xdeadbeef);
2191 CMSG_ENVELOPED, &envelopedInfo, NULL, NULL);
2192 ok(msg != NULL ||
2193 broken(!msg), /* Win9x */
2194 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2195 if (msg)
2196 {
2197 SetLastError(0xdeadbeef);
2198 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2200 "expected E_INVALIDARG, got %08x\n", GetLastError());
2201 SetLastError(0xdeadbeef);
2202 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2203 ok(ret ||
2204 broken(!ret && GetLastError() == NTE_PERM), /* some NT4 */
2205 "CryptMsgUpdate failed: %08x\n", GetLastError());
2207 }
2208 SetLastError(0xdeadbeef);
2210 &envelopedInfo, NULL, &streamInfo);
2211 ok(msg != NULL ||
2212 broken(!msg), /* Win9x */
2213 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2214 if (msg)
2215 {
2216 SetLastError(0xdeadbeef);
2218 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2219 SetLastError(0xdeadbeef);
2220 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2221 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2223 }
2224 SetLastError(0xdeadbeef);
2226 &envelopedInfo, NULL, &streamInfo);
2227 ok(msg != NULL ||
2228 broken(!msg), /* Win9x */
2229 "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2230 if (msg)
2231 {
2232 SetLastError(0xdeadbeef);
2233 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2234 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2235 SetLastError(0xdeadbeef);
2236 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2237 ok(ret ||
2238 broken(!ret && GetLastError() == NTE_PERM), /* some NT4 */
2239 "CryptMsgUpdate failed: %08x\n", GetLastError());
2241 }
2242}

Referenced by test_enveloped_msg().

◆ test_hash_msg()

static void test_hash_msg ( void  )
static

Definition at line 1060 of file msg.c.

1061{
1066}
static void test_hash_msg_update(void)
Definition: msg.c:755
static void test_hash_msg_get_param(void)
Definition: msg.c:820
static void test_hash_msg_encoding(void)
Definition: msg.c:966
static void test_hash_msg_open(void)
Definition: msg.c:723

Referenced by START_TEST().

◆ test_hash_msg_encoding()

static void test_hash_msg_encoding ( void  )
static

Definition at line 966 of file msg.c.

967{
969 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0 };
970 BOOL ret;
971 struct update_accum accum = { 0, NULL }, empty_accum = { 0, NULL };
972 CMSG_STREAM_INFO streamInfo = { 0, accumulating_stream_output, &accum };
973
976 NULL, NULL);
977 check_param("hash empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
979 check_param("hash empty content", msg, CMSG_CONTENT_PARAM,
982 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
983 check_param("hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
985 check_param("hash content", msg, CMSG_CONTENT_PARAM,
986 hashContent, sizeof(hashContent));
988 /* Same test, but with CMSG_BARE_CONTENT_FLAG set */
990 CMSG_HASHED, &hashInfo, NULL, NULL);
991 check_param("hash empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
993 check_param("hash empty content", msg, CMSG_CONTENT_PARAM,
996 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
997 check_param("hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
999 check_param("hash content", msg, CMSG_CONTENT_PARAM,
1000 hashContent, sizeof(hashContent));
1002 /* Same test, but with CMSG_DETACHED_FLAG set */
1004 CMSG_HASHED, &hashInfo, NULL, NULL);
1005 check_param("detached hash empty bare content", msg,
1007 sizeof(hashEmptyBareContent));
1008 check_param("detached hash empty content", msg, CMSG_CONTENT_PARAM,
1010 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1011 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1012 check_param("detached hash not final bare content", msg,
1015 check_param("detached hash not final content", msg, CMSG_CONTENT_PARAM,
1017 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1018 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1019 check_param("detached hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
1021 check_param("detached hash content", msg, CMSG_CONTENT_PARAM,
1023 check_param("detached hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
1025 check_param("detached hash content", msg, CMSG_CONTENT_PARAM,
1028 /* In what appears to be a bug, streamed updates to hash messages don't
1029 * call the output function.
1030 */
1032 NULL, &streamInfo);
1034 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1035 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1036 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1038 check_updates("empty hash message", &empty_accum, &accum);
1039 free_updates(&accum);
1040
1041 streamInfo.cbContent = sizeof(msgData);
1043 NULL, &streamInfo);
1044 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1045 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1047 check_updates("hash message", &empty_accum, &accum);
1048 free_updates(&accum);
1049
1050 streamInfo.cbContent = sizeof(msgData);
1052 CMSG_HASHED, &hashInfo, NULL, &streamInfo);
1053 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1054 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1056 check_updates("detached hash message", &empty_accum, &accum);
1057 free_updates(&accum);
1058}
static const BYTE detachedHashContent[]
Definition: msg.c:959
static const BYTE detachedHashBareContent[]
Definition: msg.c:954
static const BYTE detachedHashNonFinalBareContent[]
Definition: msg.c:945
static const BYTE detachedHashNonFinalContent[]
Definition: msg.c:949
CRYPT_ALGORITHM_IDENTIFIER HashAlgorithm
Definition: wincrypt.h:3849

Referenced by test_hash_msg().

◆ test_hash_msg_get_param()

static void test_hash_msg_get_param ( void  )
static

Definition at line 820 of file msg.c.

821{
823 BOOL ret;
824 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0,
825 { oid_rsa_md5, { 0, NULL } }, NULL };
827 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
828 BYTE buf[16];
829
831 NULL, NULL);
832 /* Content and bare content are always gettable for non-streamed messages */
833 size = 0;
835 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
836 "CryptMsgGetParam failed: %08x\n", GetLastError());
837 size = 0;
839 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
840 "CryptMsgGetParam failed: %08x\n", GetLastError());
841 /* For an encoded hash message, the hash data aren't available */
842 SetLastError(0xdeadbeef);
845 GetLastError() == OSS_LIMITED /* Win9x */),
846 "Expected CRYPT_E_INVALID_MSG_TYPE or OSS_LIMITED, got %08x\n",
847 GetLastError());
848 /* The hash is also available. */
849 size = 0;
851 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
852 ok(size == sizeof(buf), "Unexpected size %d\n", size);
854 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
855 ok(size == sizeof(buf), "Unexpected size %d\n", size);
856 if (size == sizeof(buf))
857 ok(!memcmp(buf, emptyHashParam, size), "Unexpected value\n");
858 /* By getting the hash, further updates are not allowed */
859 SetLastError(0xdeadbeef);
861 ok(!ret &&
862 (GetLastError() == NTE_BAD_HASH_STATE /* NT */ ||
863 GetLastError() == NTE_BAD_ALGID /* 9x */ ||
864 GetLastError() == CRYPT_E_MSG_ERROR /* Vista */ ||
865 broken(GetLastError() == ERROR_SUCCESS) /* Some Win9x */),
866 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, got 0x%x\n", GetLastError());
867
868 /* Even after a final update, the hash data aren't available */
869 SetLastError(0xdeadbeef);
872 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
873 /* The version is also available, and should be zero for this message. */
874 size = 0;
877 "CryptMsgGetParam failed: %08x\n", GetLastError());
878 size = sizeof(value);
881 "CryptMsgGetParam failed: %08x\n", GetLastError());
882 if (ret)
883 ok(value == 0, "Expected version 0, got %d\n", value);
884 /* As usual, the type isn't available. */
886 ok(!ret, "Expected failure\n");
888
890 NULL, &streamInfo);
891 /* Streamed messages don't allow you to get the content or bare content. */
892 SetLastError(0xdeadbeef);
894 ok(!ret && (GetLastError() == E_INVALIDARG ||
895 GetLastError() == OSS_LIMITED /* Win9x */),
896 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
897 SetLastError(0xdeadbeef);
899 ok(!ret && (GetLastError() == E_INVALIDARG ||
900 GetLastError() == OSS_LIMITED /* Win9x */),
901 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
902 /* The hash is still available. */
903 size = 0;
905 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
906 ok(size == sizeof(buf), "Unexpected size %d\n", size);
908 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
909 if (size == sizeof(buf))
910 ok(!memcmp(buf, emptyHashParam, size), "Unexpected value\n");
911 /* After updating the hash, further updates aren't allowed on streamed
912 * messages either.
913 */
914 SetLastError(0xdeadbeef);
916 ok(!ret &&
917 (GetLastError() == NTE_BAD_HASH_STATE /* NT */ ||
918 GetLastError() == NTE_BAD_ALGID /* 9x */ ||
919 GetLastError() == CRYPT_E_MSG_ERROR /* Vista */ ||
920 broken(GetLastError() == ERROR_SUCCESS) /* Some Win9x */),
921 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, got 0x%x\n", GetLastError());
922
924}
#define NTE_BAD_ALGID
Definition: winerror.h:2876
#define NTE_BAD_HASH_STATE
Definition: winerror.h:2880

Referenced by test_hash_msg().

◆ test_hash_msg_open()

static void test_hash_msg_open ( void  )
static

Definition at line 723 of file msg.c.

724{
726 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
727 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
728
729 SetLastError(0xdeadbeef);
731 NULL, NULL);
733 "Expected E_INVALIDARG, got %x\n", GetLastError());
734 hashInfo.cbSize = sizeof(hashInfo);
735 SetLastError(0xdeadbeef);
737 NULL, NULL);
739 "Expected CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
742 NULL, NULL);
743 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
746 CMSG_HASHED, &hashInfo, NULL, NULL);
747 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
750 CMSG_HASHED, &hashInfo, NULL, &streamInfo);
751 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
753}

Referenced by test_hash_msg().

◆ test_hash_msg_update()

static void test_hash_msg_update ( void  )
static

Definition at line 755 of file msg.c.

756{
758 BOOL ret;
759 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0,
760 { oid_rsa_md5, { 0, NULL } }, NULL };
761 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
762
764 CMSG_HASHED, &hashInfo, NULL, NULL);
765 /* Detached hashed messages opened in non-streaming mode allow non-final
766 * updates..
767 */
769 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
770 /* including non-final updates with no data.. */
772 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
773 /* and final updates with no data. */
775 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
776 /* But no updates are allowed after the final update. */
777 SetLastError(0xdeadbeef);
780 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
781 SetLastError(0xdeadbeef);
784 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
786 /* Non-detached messages, in contrast, don't allow non-final updates in
787 * non-streaming mode.
788 */
790 NULL, NULL);
791 SetLastError(0xdeadbeef);
794 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
795 /* Final updates (including empty ones) are allowed. */
797 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
799 /* And, of course, streaming mode allows non-final updates */
801 NULL, &streamInfo);
803 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
805 /* Setting pfnStreamOutput to NULL results in no error. (In what appears
806 * to be a bug, it isn't actually used - see encoding tests.)
807 */
808 streamInfo.pfnStreamOutput = NULL;
810 NULL, &streamInfo);
812 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
814}

Referenced by test_hash_msg().

◆ test_msg_close()

static void test_msg_close ( void  )
static

Definition at line 270 of file msg.c.

271{
272 BOOL ret;
274
275 /* NULL succeeds.. */
277 ok(ret, "CryptMsgClose failed: %x\n", GetLastError());
278 /* but an arbitrary pointer crashes. */
279 if (0)
282 NULL);
283 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
285 ok(ret, "CryptMsgClose failed: %x\n", GetLastError());
286}

Referenced by START_TEST().

◆ test_msg_control()

static void test_msg_control ( void  )
static

Definition at line 3205 of file msg.c.

3206{
3207 static char oid_rsa_rsa[] = szOID_RSA_RSA;
3208 BOOL ret;
3209 HCRYPTMSG msg;
3210 DWORD i;
3211 CERT_INFO certInfo = { 0 };
3212 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
3213 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
3214 CMSG_CTRL_DECRYPT_PARA decryptPara = { sizeof(decryptPara), 0 };
3215
3216 /* Crashes
3217 ret = CryptMsgControl(NULL, 0, 0, NULL);
3218 */
3219
3220 /* Data encode messages don't allow any sort of control.. */
3222 NULL);
3223 /* either with no prior update.. */
3224 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3225 {
3226 SetLastError(0xdeadbeef);
3227 ret = CryptMsgControl(msg, 0, i, NULL);
3229 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3230 }
3231 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3232 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3233 /* or after an update. */
3234 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3235 {
3236 SetLastError(0xdeadbeef);
3237 ret = CryptMsgControl(msg, 0, i, NULL);
3239 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3240 }
3242
3243 /* Hash encode messages don't allow any sort of control.. */
3244 hashInfo.cbSize = sizeof(hashInfo);
3247 NULL, NULL);
3248 /* either with no prior update.. */
3249 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3250 {
3251 SetLastError(0xdeadbeef);
3252 ret = CryptMsgControl(msg, 0, i, NULL);
3254 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3255 }
3256 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
3257 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3258 /* or after an update. */
3259 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3260 {
3261 SetLastError(0xdeadbeef);
3262 ret = CryptMsgControl(msg, 0, i, NULL);
3264 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3265 }
3267
3268 /* Signed encode messages likewise don't allow any sort of control.. */
3269 signInfo.cbSize = sizeof(signInfo);
3271 NULL, NULL);
3272 /* either before an update.. */
3273 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3274 {
3275 SetLastError(0xdeadbeef);
3276 ret = CryptMsgControl(msg, 0, i, NULL);
3278 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3279 }
3280 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
3281 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3282 /* or after an update. */
3283 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3284 {
3285 SetLastError(0xdeadbeef);
3286 ret = CryptMsgControl(msg, 0, i, NULL);
3288 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3289 }
3291
3292 /* Decode messages behave a bit differently. */
3294 /* Bad control type */
3295 SetLastError(0xdeadbeef);
3296 ret = CryptMsgControl(msg, 0, 0, NULL);
3298 "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
3299 SetLastError(0xdeadbeef);
3300 ret = CryptMsgControl(msg, 1, 0, NULL);
3302 "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
3303 /* Can't verify the hash of an indeterminate-type message */
3304 SetLastError(0xdeadbeef);
3307 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3308 /* Crashes
3309 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, NULL);
3310 */
3311 /* Can't decrypt an indeterminate-type message */
3312 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3314 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3316
3317 if (!old_crypt32)
3318 {
3320 NULL);
3321 /* Can't verify the hash of an empty message */
3322 SetLastError(0xdeadbeef);
3323 /* Crashes on some Win9x */
3325 todo_wine
3327 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3328 /* Crashes
3329 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
3330 */
3331 /* Can't verify the signature of a hash message */
3334 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3336 TRUE);
3337 /* Oddly enough, this fails, crashes on some Win9x */
3339 ok(!ret, "Expected failure\n");
3341 }
3343 NULL);
3346 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
3347 /* Can't decrypt an indeterminate-type message */
3348 SetLastError(0xdeadbeef);
3349 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3351 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3353
3355 NULL, NULL);
3356 /* Can't verify the hash of a detached message before it's been updated. */
3357 SetLastError(0xdeadbeef);
3360 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3362 TRUE);
3363 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3364 /* Still can't verify the hash of a detached message with the content
3365 * of the detached hash given..
3366 */
3367 SetLastError(0xdeadbeef);
3370 "Expected CRYPT_E_HASH_VALUE, got %08x\n", GetLastError());
3371 /* and giving the content of the message after attempting to verify the
3372 * hash fails.
3373 */
3374 SetLastError(0xdeadbeef);
3375 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3376 todo_wine
3377 ok(!ret &&
3379 GetLastError() == NTE_BAD_ALGID || /* Win9x */
3380 GetLastError() == CRYPT_E_MSG_ERROR), /* Vista */
3381 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, "
3382 "got %08x\n", GetLastError());
3384
3385 /* Finally, verifying the hash of a detached message in the correct order:
3386 * 1. Update with the detached hash message
3387 * 2. Update with the content of the message
3388 * 3. Verifying the hash of the message
3389 * succeeds.
3390 */
3392 NULL, NULL);
3394 TRUE);
3395 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3396 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3397 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3398 SetLastError(0xdeadbeef);
3400 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
3402
3404 NULL);
3405 /* Can't verify the hash of a signed message */
3406 SetLastError(0xdeadbeef);
3409 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3410 /* Can't decrypt a signed message */
3411 SetLastError(0xdeadbeef);
3412 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3414 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3415 /* Crash
3416 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
3417 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3418 */
3421 /* With an empty cert info, the signer can't be found in the message (and
3422 * the signature can't be verified.
3423 */
3424 SetLastError(0xdeadbeef);
3427 GetLastError() == OSS_DATA_ERROR /* Win9x */),
3428 "Expected CRYPT_E_SIGNER_NOT_FOUND or OSS_DATA_ERROR, got %08x\n",
3429 GetLastError());
3430 /* The cert info is expected to have an issuer, serial number, and public
3431 * key info set.
3432 */
3433 certInfo.SerialNumber.cbData = sizeof(serialNum);
3434 certInfo.SerialNumber.pbData = serialNum;
3435 certInfo.Issuer.cbData = sizeof(encodedCommonName);
3436 certInfo.Issuer.pbData = encodedCommonName;
3437 SetLastError(0xdeadbeef);
3439 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
3440 GetLastError() == OSS_DATA_ERROR /* Win9x */),
3441 "Expected CRYPT_E_ASN1_EOD or OSS_DATA_ERROR, got %08x\n", GetLastError());
3443 /* This cert has a public key, but it's not in a usable form */
3445 NULL);
3448 if (ret)
3449 {
3450 /* Crashes on some Win9x */
3451 /* Again, cert info needs to have a public key set */
3452 SetLastError(0xdeadbeef);
3454 ok(!ret &&
3456 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3457 "Expected CRYPT_E_ASN1_EOD or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
3458 /* The public key is supposed to be in encoded form.. */
3459 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
3460 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey);
3462 SetLastError(0xdeadbeef);
3464 ok(!ret &&
3466 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3467 "Expected CRYPT_E_ASN1_BADTAG or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
3468 /* but not as a X509_PUBLIC_KEY_INFO.. */
3472 SetLastError(0xdeadbeef);
3474 ok(!ret &&
3476 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3477 "Expected CRYPT_E_ASN1_BADTAG or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
3478 /* This decodes successfully, but it doesn't match any key in the message */
3481 SetLastError(0xdeadbeef);
3483 /* In Wine's rsaenh, this fails to decode because the key length is too
3484 * small. Not sure if that's a bug in rsaenh, so leaving todo_wine for
3485 * now.
3486 */
3487 todo_wine
3488 ok(!ret &&
3490 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3491 "Expected NTE_BAD_SIGNATURE or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
3492 }
3494 /* A message with no data doesn't have a valid signature */
3498 if (ret)
3499 {
3500 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
3501 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(pubKey);
3503 SetLastError(0xdeadbeef);
3504 /* Crashes on some Win9x */
3506 ok(!ret &&
3508 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3509 "Expected NTE_BAD_SIGNATURE or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
3510 }
3512 /* Finally, this succeeds */
3517 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3518 "CryptMsgControl failed: %08x\n", GetLastError());
3520
3521 /* Test verifying signature of a detached signed message */
3523 NULL, NULL);
3525 sizeof(detachedSignedContent), TRUE);
3526 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3527 /* Can't verify the sig without having updated the data */
3528 SetLastError(0xdeadbeef);
3531 GetLastError() == OSS_DATA_ERROR /* Win9x */),
3532 "expected NTE_BAD_SIGNATURE or OSS_DATA_ERROR, got %08x\n",
3533 GetLastError());
3534 /* Now that the signature's been checked, can't do the final update */
3535 SetLastError(0xdeadbeef);
3536 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3537 todo_wine
3538 ok((!ret &&
3540 GetLastError() == NTE_BAD_ALGID || /* Win9x */
3541 GetLastError() == CRYPT_E_MSG_ERROR)) || /* Vista */
3542 broken(ret), /* Win9x */
3543 "expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, "
3544 "got %08x\n", GetLastError());
3546 /* Updating with the detached portion of the message and the data of the
3547 * the message allows the sig to be verified.
3548 */
3550 NULL, NULL);
3552 sizeof(detachedSignedContent), TRUE);
3553 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3554 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3555 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3557 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3558 "CryptMsgControl failed: %08x\n", GetLastError());
3560
3562 NULL);
3563 decryptPara.cbSize = 0;
3564 SetLastError(0xdeadbeef);
3565 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3567 "expected E_INVALIDARG, got %08x\n", GetLastError());
3568 decryptPara.cbSize = sizeof(decryptPara);
3569 if (!old_crypt32)
3570 {
3571 SetLastError(0xdeadbeef);
3572 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3574 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3575 }
3576 SetLastError(0xdeadbeef);
3579 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3580 SetLastError(0xdeadbeef);
3581 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3583 "expected CRYPT_E_INVALID_INDEX, got %08x\n", GetLastError());
3585
3587 NULL);
3588 SetLastError(0xdeadbeef);
3590 sizeof(envelopedBareMessage), TRUE);
3591 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3592 SetLastError(0xdeadbeef);
3593 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3595 "expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
3597}
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
static BYTE pubKey[]
Definition: msg.c:1214
static BYTE mod_encoded[]
Definition: msg.c:3201
static const BYTE signedWithCertWithPubKeyBareContent[]
Definition: msg.c:1568
static const BYTE signedWithCertBareContent[]
Definition: msg.c:1474
static const BYTE signedWithCertWithValidPubKeyEmptyContent[]
Definition: msg.c:1600
static BYTE aKey[]
Definition: msg.c:3194
static BYTE encodedPubKey[]
Definition: msg.c:3196
static const BYTE signedWithCertWithValidPubKeyContent[]
Definition: msg.c:1623
CERT_PUBLIC_KEY_INFO SubjectPublicKeyInfo
Definition: wincrypt.h:248
CRYPT_BIT_BLOB PublicKey
Definition: wincrypt.h:226
CRYPT_ALGORITHM_IDENTIFIER Algorithm
Definition: wincrypt.h:225
BYTE * pbData
Definition: wincrypt.h:197
#define CMSG_CTRL_VERIFY_HASH
Definition: wincrypt.h:3871
#define CMSG_CTRL_ADD_CMS_SIGNER_INFO
Definition: wincrypt.h:3886
#define szOID_RSA_RSA
Definition: wincrypt.h:3015
#define CMSG_CTRL_VERIFY_SIGNATURE
Definition: wincrypt.h:3869
#define CRYPT_E_HASH_VALUE
Definition: winerror.h:2991
#define TRUST_E_NOSIGNATURE
Definition: winerror.h:3116
#define NTE_BAD_SIGNATURE
Definition: winerror.h:2874
#define CRYPT_E_SIGNER_NOT_FOUND
Definition: winerror.h:2998
#define CRYPT_E_CONTROL_TYPE
Definition: winerror.h:2996
#define CRYPT_E_ASN1_EOD
Definition: winerror.h:3086

Referenced by START_TEST().

◆ test_msg_get_and_verify_signer()

static void test_msg_get_and_verify_signer ( void  )
static

Definition at line 3635 of file msg.c.

3636{
3637 BOOL ret;
3638 HCRYPTMSG msg;
3639 PCCERT_CONTEXT signer;
3640 DWORD signerIndex;
3641 HCERTSTORE store;
3642
3643 /* Crash */
3644 if (0)
3645 {
3647 CryptMsgGetAndVerifySigner(NULL, 0, NULL, 0, NULL, &signerIndex);
3648 }
3649
3651 /* An empty message has no signer */
3652 SetLastError(0xdeadbeef);
3655 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3656 /* The signer is cleared on error */
3657 signer = (PCCERT_CONTEXT)0xdeadbeef;
3658 SetLastError(0xdeadbeef);
3659 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, &signer, NULL);
3661 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3662 ok(!signer, "expected signer to be NULL\n");
3663 /* The signer index is also cleared on error */
3664 signerIndex = 0xdeadbeef;
3665 SetLastError(0xdeadbeef);
3666 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, &signerIndex);
3668 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3669 ok(!signerIndex, "expected 0, got %d\n", signerIndex);
3670 /* An unsigned message (msgData isn't a signed message at all)
3671 * likewise has no signer.
3672 */
3674 SetLastError(0xdeadbeef);
3677 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3679
3681 /* A "signed" message created with no signer cert likewise has no signer */
3683 if (ret)
3684 {
3685 /* Crashes on most Win9x */
3688 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3689 }
3691
3693 /* A signed message succeeds, .. */
3697 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3698 "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3699 /* the signer index can be retrieved, .. */
3700 signerIndex = 0xdeadbeef;
3701 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, &signerIndex);
3702 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3703 "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3704 if (ret)
3705 ok(signerIndex == 0, "expected 0, got %d\n", signerIndex);
3706 /* as can the signer cert. */
3707 signer = (PCCERT_CONTEXT)0xdeadbeef;
3708 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, &signer, NULL);
3709 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3710 "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3711 if (ret)
3712 ok(signer != NULL && signer != (PCCERT_CONTEXT)0xdeadbeef,
3713 "expected a valid signer\n");
3714 if (signer && signer != (PCCERT_CONTEXT)0xdeadbeef)
3716 /* Specifying CMSG_USE_SIGNER_INDEX_FLAG and an invalid signer index fails
3717 */
3718 signerIndex = 0xdeadbeef;
3719 SetLastError(0xdeadbeef);
3721 NULL, &signerIndex);
3723 "expected CRYPT_E_INVALID_INDEX, got 0x%08x\n", GetLastError());
3724 /* Specifying CMSG_TRUSTED_SIGNER_FLAG and no cert stores causes the
3725 * message signer not to be found.
3726 */
3727 SetLastError(0xdeadbeef);
3729 NULL, NULL);
3731 broken(GetLastError() == OSS_DATA_ERROR /* Win9x */)),
3732 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3733 /* Specifying CMSG_TRUSTED_SIGNER_FLAG and an empty cert store also causes
3734 * the message signer not to be found.
3735 */
3738 SetLastError(0xdeadbeef);
3740 NULL, NULL);
3742 broken(GetLastError() == OSS_DATA_ERROR /* Win9x */)),
3743 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3747 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win98 */),
3748 "CertAddEncodedCertificateToStore failed: 0x%08x\n", GetLastError());
3749 /* Specifying CMSG_TRUSTED_SIGNER_FLAG with a cert store that contains
3750 * the signer succeeds.
3751 */
3752 SetLastError(0xdeadbeef);
3754 NULL, NULL);
3755 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3756 "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3757 CertCloseStore(store, 0);
3759}
BOOL WINAPI CertAddEncodedCertificateToStore(HCERTSTORE hCertStore, DWORD dwCertEncodingType, const BYTE *pbCertEncoded, DWORD cbCertEncoded, DWORD dwAddDisposition, PCCERT_CONTEXT *ppCertContext)
Definition: cert.c:58
BOOL WINAPI CryptMsgGetAndVerifySigner(HCRYPTMSG hCryptMsg, DWORD cSignerStore, HCERTSTORE *rghSignerStore, DWORD dwFlags, PCCERT_CONTEXT *ppSigner, DWORD *pdwSignerIndex)
Definition: msg.c:3669
HCERTSTORE WINAPI CertOpenStore(LPCSTR lpszStoreProvider, DWORD dwMsgAndCertEncodingType, HCRYPTPROV_LEGACY hCryptProv, DWORD dwFlags, const void *pvPara)
Definition: store.c:815
BOOL WINAPI CertCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
Definition: store.c:1127
static const BYTE signedEmptyContent[]
Definition: msg.c:1341
#define CERT_STORE_CREATE_NEW_FLAG
Definition: wincrypt.h:2464
#define CERT_STORE_PROV_MEMORY
Definition: wincrypt.h:2251
const CERT_CONTEXT * PCCERT_CONTEXT
Definition: wincrypt.h:485
#define CMSG_USE_SIGNER_INDEX_FLAG
Definition: wincrypt.h:4122
#define CERT_STORE_ADD_ALWAYS
Definition: wincrypt.h:2485
#define CMSG_TRUSTED_SIGNER_FLAG
Definition: wincrypt.h:4120
#define CRYPT_E_NO_TRUSTED_SIGNER
Definition: winerror.h:3035

Referenced by START_TEST().

◆ test_msg_get_param()

static void test_msg_get_param ( void  )
static

Definition at line 164 of file msg.c.

165{
166 BOOL ret;
168 DWORD size, i, value;
169
170 /* Crash
171 ret = CryptMsgGetParam(NULL, 0, 0, NULL, NULL);
172 ret = CryptMsgGetParam(NULL, 0, 0, NULL, &size);
173 ret = CryptMsgGetParam(msg, 0, 0, NULL, NULL);
174 */
175
176 /* Decoded messages */
178 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
179 /* For decoded messages, the type is always available */
180 size = 0;
182 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
183 size = sizeof(value);
185 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
186 /* For this (empty) message, the type isn't set */
187 ok(value == 0, "Expected type 0, got %d\n", value);
189
191 NULL);
192 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
193 /* For explicitly typed messages, the type is known. */
194 size = sizeof(value);
196 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
197 ok(value == CMSG_DATA, "Expected CMSG_DATA, got %d\n", value);
199 {
200 size = 0;
201 ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
202 ok(!ret, "Parameter %d: expected failure\n", i);
203 }
205
207 NULL);
208 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
209 size = sizeof(value);
211 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
212 ok(value == CMSG_ENVELOPED, "Expected CMSG_ENVELOPED, got %d\n", value);
214 {
215 size = 0;
216 ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
217 ok(!ret, "Parameter %d: expected failure\n", i);
218 }
220
222 NULL);
223 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
224 size = sizeof(value);
226 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
227 ok(value == CMSG_HASHED, "Expected CMSG_HASHED, got %d\n", value);
229 {
230