- more fully implement CryptRegisterOIDFunction
[wine] / dlls / crypt32 / encode.c
1 /*
2  * Copyright 2002 Mike McCormack for CodeWeavers
3  * Copyright 2005 Juan Lang
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19 #include <stdarg.h>
20 #include <stdio.h>
21 #include "windef.h"
22 #include "winbase.h"
23 #include "wincrypt.h"
24 #include "winreg.h"
25 #include "wine/debug.h"
26
27 WINE_DEFAULT_DEBUG_CHANNEL(crypt);
28
29 static char *CRYPT_GetKeyName(DWORD dwEncodingType, LPCSTR pszFuncName,
30  LPCSTR pszOID)
31 {
32     static const char szEncodingTypeFmt[] =
33      "Software\\Microsoft\\Cryptography\\OID\\EncodingType %ld\\%s\\%s";
34     UINT len;
35     char numericOID[7]; /* enough for "#65535" */
36     const char *oid;
37     LPSTR szKey;
38
39     /* MSDN says the encoding type is a mask, but it isn't treated that way.
40      * (E.g., if dwEncodingType were 3, the key names "EncodingType 1" and
41      * "EncodingType 2" would be expected if it were a mask.  Instead native
42      * stores values in "EncodingType 3".
43      */
44     if (!HIWORD(pszOID))
45     {
46         snprintf(numericOID, sizeof(numericOID), "#%d", (int)pszOID);
47         oid = numericOID;
48     }
49     else
50         oid = pszOID;
51
52     /* This is enough: the lengths of the two string parameters are explicitly
53      * counted, and we need up to five additional characters for the encoding
54      * type.  These are covered by the "%d", "%s", and "%s" characters in the
55      * format specifier that are removed by sprintf.
56      */
57     len = sizeof(szEncodingTypeFmt) + lstrlenA(pszFuncName) + lstrlenA(oid);
58     szKey = HeapAlloc(GetProcessHeap(), 0, len);
59     if (szKey)
60         sprintf(szKey, szEncodingTypeFmt, dwEncodingType, pszFuncName, oid);
61     return szKey;
62 }
63
64 BOOL WINAPI CryptRegisterOIDFunction(DWORD dwEncodingType, LPCSTR pszFuncName,
65                   LPCSTR pszOID, LPCWSTR pwszDll, LPCSTR pszOverrideFuncName)
66 {
67     LONG r;
68     static const WCHAR szDllName[] = { 'D','l','l',0 };
69     HKEY hKey;
70     LPSTR szKey;
71
72     TRACE("%lx %s %s %s %s\n", dwEncodingType, pszFuncName, pszOID,
73           debugstr_w(pwszDll), pszOverrideFuncName);
74
75     /* MSDN states dwEncodingType is a mask, but it isn't really treated as
76      * such.  Values 65536 or greater are ignored.
77      */
78     if (dwEncodingType >= PKCS_7_ASN_ENCODING)
79         return TRUE;
80
81     /* I'm not matching MS bug for bug here, because I doubt any app depends on
82      * it:
83      * - native does nothing if pwszDll is NULL
84      * - native "succeeds" if pszFuncName is NULL, but the nonsensical entry
85      *   it creates would never be used
86      * - native returns an HRESULT rather than a Win32 error if pszOID is NULL.
87      * Instead I disallow all of these with ERROR_INVALID_PARAMETER.
88      */
89     if (!pszFuncName || !pszOID || !pwszDll)
90     {
91         SetLastError(ERROR_INVALID_PARAMETER);
92         return FALSE;
93     }
94
95     szKey = CRYPT_GetKeyName(dwEncodingType, pszFuncName, pszOID);
96     TRACE("Key name is %s\n", debugstr_a(szKey));
97
98     if (!szKey)
99         return FALSE;
100
101     r = RegCreateKeyA(HKEY_LOCAL_MACHINE, szKey, &hKey);
102     HeapFree(GetProcessHeap(), 0, szKey);
103     if(r != ERROR_SUCCESS)
104         return FALSE;
105
106     /* write the values */
107     if (pszOverrideFuncName)
108         RegSetValueExA(hKey, "FuncName", 0, REG_SZ, pszOverrideFuncName,
109          lstrlenA(pszOverrideFuncName) + 1);
110     RegSetValueExW(hKey, szDllName, 0, REG_SZ, (const BYTE*) pwszDll,
111                     (lstrlenW(pwszDll) + 1) * sizeof (WCHAR));
112
113     RegCloseKey(hKey);
114     return TRUE;
115 }
116
117 BOOL WINAPI CryptUnregisterOIDFunction(DWORD dwEncodingType, LPCSTR pszFuncName,
118  LPCSTR pszOID)
119 {
120     LPSTR szKey;
121     LONG rc;
122
123     TRACE("%lx %s %s\n", dwEncodingType, pszFuncName, pszOID);
124
125     if (dwEncodingType >= PKCS_7_ASN_ENCODING)
126         return TRUE;
127
128     if (!pszFuncName || !pszOID)
129     {
130         SetLastError(ERROR_INVALID_PARAMETER);
131         return FALSE;
132     }
133
134     szKey = CRYPT_GetKeyName(dwEncodingType, pszFuncName, pszOID);
135     rc = RegDeleteKeyA(HKEY_LOCAL_MACHINE, szKey);
136     if (!rc)
137         SetLastError(rc);
138     return rc ? FALSE : TRUE;
139 }
140
141 BOOL WINAPI CryptEncodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType,
142  const void *pvStructInfo, BYTE *pbEncoded, DWORD *pcbEncoded)
143 {
144     FIXME("(0x%08lx, %s, %p, %p, %p): stub\n",
145      dwCertEncodingType, HIWORD(lpszStructType) ? debugstr_a(lpszStructType) :
146      "(integer value)", pvStructInfo, pbEncoded, pcbEncoded);
147     return FALSE;
148 }
149
150 BOOL WINAPI CryptEncodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType,
151  const void *pvStructInfo, DWORD dwFlags, PCRYPT_ENCODE_PARA pEncodePara,
152  BYTE *pbEncoded, DWORD *pcbEncoded)
153 {
154     FIXME("(0x%08lx, %s, %p, 0x%08lx, %p, %p, %p): stub\n",
155      dwCertEncodingType, HIWORD(lpszStructType) ? debugstr_a(lpszStructType) :
156      "(integer value)", pvStructInfo, dwFlags, pEncodePara, pbEncoded,
157      pcbEncoded);
158     return FALSE;
159 }
160
161 BOOL WINAPI CryptDecodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType,
162  const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo,
163  DWORD *pcbStructInfo)
164 {
165     FIXME("(0x%08lx, %s, %p, %ld, 0x%08lx, %p, %p): stub\n",
166      dwCertEncodingType, HIWORD(lpszStructType) ? debugstr_a(lpszStructType) :
167      "(integer value)", pbEncoded, cbEncoded, dwFlags, pvStructInfo,
168      pcbStructInfo);
169     return FALSE;
170 }
171
172 BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType,
173  const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
174  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
175 {
176     FIXME("(0x%08lx, %s, %p, %ld, 0x%08lx, %p, %p, %p): stub\n",
177      dwCertEncodingType, HIWORD(lpszStructType) ? debugstr_a(lpszStructType) :
178      "(integer value)", pbEncoded, cbEncoded, dwFlags, pDecodePara,
179      pvStructInfo, pcbStructInfo);
180     return FALSE;
181 }