Don't open device if already open.
[wine] / dlls / crypt32 / tests / encode.c
1 /*
2  * Unit test suite for crypt32.dll's CryptEncodeObjectEx
3  *
4  * Copyright 2005 Juan Lang
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20 #include <stdio.h>
21 #include <stdarg.h>
22 #include <windef.h>
23 #include <winbase.h>
24 #include <winerror.h>
25 #include <wincrypt.h>
26
27 #include "wine/test.h"
28
29 struct encodedInt
30 {
31     int val;
32     BYTE encoded[6];
33 };
34
35 static const struct encodedInt ints[] = {
36  { 1,          { 2, 1, 1 } },
37  { 127,        { 2, 1, 0x7f } },
38  { 128,        { 2, 2, 0x00, 0x80 } },
39  { 256,        { 2, 2, 0x01, 0x00 } },
40  { -128,       { 2, 1, 0x80 } },
41  { -129,       { 2, 2, 0xff, 0x7f } },
42  { 0xbaddf00d, { 2, 4, 0xba, 0xdd, 0xf0, 0x0d } },
43 };
44
45 static void test_encodeint(void)
46 {
47     DWORD bufSize = 0;
48     int i;
49     BOOL ret;
50
51     /* CryptEncodeObjectEx with NULL bufSize crashes..
52     ret = CryptEncodeObjectEx(3, X509_INTEGER, &ints[0].val, 0, NULL, NULL,
53      NULL);
54      */
55     /* check bogus encoding */
56     ret = CryptEncodeObjectEx(0, X509_INTEGER, &ints[0].val, 0, NULL, NULL,
57      &bufSize);
58     ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
59      "Expected ERROR_FILE_NOT_FOUND, got %ld\n", GetLastError());
60     /* check with NULL integer buffer.  Windows XP incorrectly returns an
61      * NTSTATUS.
62      */
63     ret = CryptEncodeObjectEx(X509_ASN_ENCODING, X509_INTEGER, NULL, 0, NULL,
64      NULL, &bufSize);
65     ok(!ret && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() ==
66      STATUS_ACCESS_VIOLATION), "Unexpected error code %ld\n", GetLastError());
67     for (i = 0; i < sizeof(ints) / sizeof(ints[0]); i++)
68     {
69         BYTE *buf = NULL;
70
71         ret = CryptEncodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
72          X509_INTEGER, &ints[i].val, 0, NULL, NULL, &bufSize);
73         ok(ret || GetLastError() == ERROR_MORE_DATA,
74          "Expected success or ERROR_MORE_DATA, got %ld\n", GetLastError());
75         ret = CryptEncodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
76          X509_INTEGER, &ints[i].val, CRYPT_ENCODE_ALLOC_FLAG, NULL,
77          (BYTE *)&buf, &bufSize);
78         ok(ret, "CryptEncodeObjectEx failed: %ld\n", GetLastError());
79         ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
80          buf[0]);
81         ok(!memcmp(buf + 1, ints[i].encoded + 1, ints[i].encoded[1] + 1),
82          "Encoded value of 0x%08x didn't match expected\n", ints[i].val);
83         LocalFree(buf);
84     }
85 }
86
87 static void test_decodeint(void)
88 {
89     static const char bigInt[] = { 2, 5, 0xff, 0xfe, 0xff, 0xfe, 0xff };
90     static const char testStr[] = { 16, 4, 't', 'e', 's', 't' };
91     BYTE *buf = NULL;
92     DWORD bufSize = 0;
93     int i;
94     BOOL ret;
95
96     /* CryptDecodeObjectEx with NULL bufSize crashes..
97     ret = CryptDecodeObjectEx(3, X509_INTEGER, &ints[0].encoded, 
98      ints[0].encoded[1] + 2, 0, NULL, NULL, NULL);
99      */
100     /* check bogus encoding */
101     ret = CryptDecodeObjectEx(3, X509_INTEGER, (BYTE *)&ints[0].encoded, 
102      ints[0].encoded[1] + 2, 0, NULL, NULL, &bufSize);
103     ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
104      "Expected ERROR_FILE_NOT_FOUND, got %ld\n", GetLastError());
105     /* check with NULL integer buffer.  Windows XP returns an apparently random
106      * error code (0x01c567df).
107      */
108     ret = CryptDecodeObjectEx(X509_ASN_ENCODING, X509_INTEGER, NULL, 0, 0,
109      NULL, NULL, &bufSize);
110     ok(!ret, "Expected failure, got success\n");
111     /* check with a valid, but too large, integer */
112     ret = CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
113      X509_INTEGER, bigInt, bigInt[1] + 2, CRYPT_ENCODE_ALLOC_FLAG, NULL,
114      (BYTE *)&buf, &bufSize);
115     ok(!ret && GetLastError() == CRYPT_E_ASN1_LARGE,
116      "Expected CRYPT_E_ASN1_LARGE, got %ld\n", GetLastError());
117     /* check with a DER-encoded string */
118     ret = CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
119      X509_INTEGER, testStr, testStr[1] + 2, CRYPT_ENCODE_ALLOC_FLAG, NULL,
120      (BYTE *)&buf, &bufSize);
121     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
122      "Expected CRYPT_E_ASN1_BADTAG, got %ld\n", GetLastError());
123     for (i = 0; i < sizeof(ints) / sizeof(ints[0]); i++)
124     {
125         /* WinXP succeeds rather than failing with ERROR_MORE_DATA */
126         ret = CryptDecodeObjectEx(X509_ASN_ENCODING, X509_INTEGER,
127          (BYTE *)&ints[i].encoded, ints[i].encoded[1] + 2, 0, NULL, NULL,
128          &bufSize);
129         ok(ret || GetLastError() == ERROR_MORE_DATA,
130          "Expected success or ERROR_MORE_DATA, got %ld\n", GetLastError());
131         ret = CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
132          X509_INTEGER, (BYTE *)&ints[i].encoded, ints[i].encoded[1] + 2,
133          CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
134         ok(ret, "CryptDecodeObjectEx failed: %ld\n", GetLastError());
135         ok(bufSize == sizeof(int), "Expected size %d, got %ld\n", sizeof(int),
136          bufSize);
137         ok(buf != NULL, "Expected allocated buffer\n");
138         if (buf)
139         {
140             ok(!memcmp(buf, &ints[i].val, bufSize), "Expected %d, got %d\n",
141              ints[i].val, *(int *)buf);
142             LocalFree(buf);
143         }
144     }
145 }
146
147 static void test_registerOIDFunction(void)
148 {
149     static const WCHAR bogusDll[] = { 'b','o','g','u','s','.','d','l','l',0 };
150     BOOL ret;
151
152     /* oddly, this succeeds under WinXP; the function name key is merely
153      * omitted.  This may be a side effect of the registry code, I don't know.
154      * I don't check it because I doubt anyone would depend on it.
155     ret = CryptRegisterOIDFunction(X509_ASN_ENCODING, NULL,
156      "1.2.3.4.5.6.7.8.9.10", bogusDll, NULL);
157      */
158     /* On windows XP, GetLastError is incorrectly being set with an HRESULT,
159      * HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER)
160      */
161     ret = CryptRegisterOIDFunction(X509_ASN_ENCODING, "foo", NULL, bogusDll,
162      NULL);
163     ok(!ret && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() ==
164      HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER)),
165      "Expected ERROR_INVALID_PARAMETER: %ld\n", GetLastError());
166     /* This has no effect, but "succeeds" on XP */
167     ret = CryptRegisterOIDFunction(X509_ASN_ENCODING, "foo",
168      "1.2.3.4.5.6.7.8.9.10", NULL, NULL);
169     ok(ret, "Expected pseudo-success, got %ld\n", GetLastError());
170     ret = CryptRegisterOIDFunction(X509_ASN_ENCODING, "CryptDllEncodeObject",
171      "1.2.3.4.5.6.7.8.9.10", bogusDll, NULL);
172     ok(ret, "CryptRegisterOIDFunction failed: %ld\n", GetLastError());
173     ret = CryptUnregisterOIDFunction(X509_ASN_ENCODING, "CryptDllEncodeObject",
174      "1.2.3.4.5.6.7.8.9.10");
175     ok(ret, "CryptUnregisterOIDFunction failed: %ld\n", GetLastError());
176     ret = CryptRegisterOIDFunction(X509_ASN_ENCODING, "bogus",
177      "1.2.3.4.5.6.7.8.9.10", bogusDll, NULL);
178     ok(ret, "CryptRegisterOIDFunction failed: %ld\n", GetLastError());
179     ret = CryptUnregisterOIDFunction(X509_ASN_ENCODING, "bogus",
180      "1.2.3.4.5.6.7.8.9.10");
181     ok(ret, "CryptUnregisterOIDFunction failed: %ld\n", GetLastError());
182     /* This has no effect */
183     ret = CryptRegisterOIDFunction(PKCS_7_ASN_ENCODING, "CryptDllEncodeObject",
184      "1.2.3.4.5.6.7.8.9.10", bogusDll, NULL);
185     ok(ret, "CryptRegisterOIDFunction failed: %ld\n", GetLastError());
186     /* Check with bogus encoding type: */
187     ret = CryptRegisterOIDFunction(0, "CryptDllEncodeObject",
188      "1.2.3.4.5.6.7.8.9.10", bogusDll, NULL);
189     ok(ret, "CryptRegisterOIDFunction failed: %ld\n", GetLastError());
190     /* This is written with value 3 verbatim.  Thus, the encoding type isn't
191      * (for now) treated as a mask.
192      */
193     ret = CryptRegisterOIDFunction(3, "CryptDllEncodeObject",
194      "1.2.3.4.5.6.7.8.9.10", bogusDll, NULL);
195     ok(ret, "CryptRegisterOIDFunction failed: %ld\n", GetLastError());
196     ret = CryptUnregisterOIDFunction(3, "CryptDllEncodeObject",
197      "1.2.3.4.5.6.7.8.9.10");
198     ok(ret, "CryptUnregisterOIDFunction failed: %ld\n", GetLastError());
199 }
200
201 START_TEST(encode)
202 {
203     test_encodeint();
204     test_decodeint();
205     test_registerOIDFunction();
206 }