crypt32: Add a stub get param function for data messages and remove stub message...
[wine/gsoc_dplay.git] / dlls / crypt32 / msg.c
blobe392b79cfe6dcad5fabefa1b49cb164b325151f2
1 /*
2 * Copyright 2007 Juan Lang
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 #include <stdarg.h>
19 #include "windef.h"
20 #include "winbase.h"
21 #include "wincrypt.h"
23 #include "wine/debug.h"
25 WINE_DEFAULT_DEBUG_CHANNEL(crypt);
27 /* Called when a message's ref count reaches zero. Free any message-specific
28 * data here.
30 typedef void (*CryptMsgCloseFunc)(HCRYPTMSG msg);
32 typedef BOOL (*CryptMsgGetParamFunc)(HCRYPTMSG hCryptMsg, DWORD dwParamType,
33 DWORD dwIndex, void *pvData, DWORD *pcbData);
35 typedef BOOL (*CryptMsgUpdateFunc)(HCRYPTMSG hCryptMsg, const BYTE *pbData,
36 DWORD cbData, BOOL fFinal);
38 typedef struct _CryptMsgBase
40 LONG ref;
41 DWORD open_flags;
42 PCMSG_STREAM_INFO stream_info;
43 BOOL finalized;
44 CryptMsgCloseFunc close;
45 CryptMsgUpdateFunc update;
46 CryptMsgGetParamFunc get_param;
47 } CryptMsgBase;
49 static inline void CryptMsgBase_Init(CryptMsgBase *msg, DWORD dwFlags,
50 PCMSG_STREAM_INFO pStreamInfo)
52 msg->ref = 1;
53 msg->open_flags = dwFlags;
54 msg->stream_info = pStreamInfo;
55 msg->finalized = FALSE;
58 typedef struct _CDataEncodeMsg
60 CryptMsgBase base;
61 DWORD bare_content_len;
62 LPBYTE bare_content;
63 } CDataEncodeMsg;
65 static const BYTE empty_data_content[] = { 0x04,0x00 };
67 static void CDataEncodeMsg_Close(HCRYPTMSG hCryptMsg)
69 CDataEncodeMsg *msg = (CDataEncodeMsg *)hCryptMsg;
71 if (msg->bare_content != empty_data_content)
72 LocalFree(msg->bare_content);
75 static BOOL CDataEncodeMsg_Update(HCRYPTMSG hCryptMsg, const BYTE *pbData,
76 DWORD cbData, BOOL fFinal)
78 CDataEncodeMsg *msg = (CDataEncodeMsg *)hCryptMsg;
79 BOOL ret = FALSE;
81 if (msg->base.finalized)
82 SetLastError(CRYPT_E_MSG_ERROR);
83 else if (!fFinal)
85 if (msg->base.open_flags & CMSG_DETACHED_FLAG)
86 SetLastError(E_INVALIDARG);
87 else
88 SetLastError(CRYPT_E_MSG_ERROR);
90 else
92 msg->base.finalized = TRUE;
93 if (!cbData)
94 SetLastError(E_INVALIDARG);
95 else
97 CRYPT_DATA_BLOB blob = { cbData, (LPBYTE)pbData };
99 /* data messages don't allow non-final updates, don't bother
100 * checking whether data already exist, they can't.
102 ret = CryptEncodeObjectEx(X509_ASN_ENCODING, X509_OCTET_STRING,
103 &blob, CRYPT_ENCODE_ALLOC_FLAG, NULL, &msg->bare_content,
104 &msg->bare_content_len);
105 if (ret && msg->base.stream_info)
106 FIXME("stream info unimplemented\n");
109 return ret;
112 static BOOL CDataEncodeMsg_GetParam(HCRYPTMSG hCryptMsg, DWORD dwParamType,
113 DWORD dwIndex, void *pvData, DWORD *pcbData)
115 BOOL ret = FALSE;
117 switch (dwParamType)
119 case CMSG_CONTENT_PARAM:
120 case CMSG_BARE_CONTENT_PARAM:
121 FIXME("stub\n");
122 break;
123 default:
124 SetLastError(CRYPT_E_INVALID_MSG_TYPE);
126 return ret;
129 static HCRYPTMSG CDataEncodeMsg_Open(DWORD dwFlags, const void *pvMsgEncodeInfo,
130 LPSTR pszInnerContentObjID, PCMSG_STREAM_INFO pStreamInfo)
132 CDataEncodeMsg *msg;
134 if (pvMsgEncodeInfo)
136 SetLastError(E_INVALIDARG);
137 return NULL;
139 msg = CryptMemAlloc(sizeof(CDataEncodeMsg));
140 if (msg)
142 CryptMsgBase_Init((CryptMsgBase *)msg, dwFlags, pStreamInfo);
143 msg->base.close = CDataEncodeMsg_Close;
144 msg->base.update = CDataEncodeMsg_Update;
145 msg->base.get_param = CDataEncodeMsg_GetParam;
146 msg->bare_content_len = sizeof(empty_data_content);
147 msg->bare_content = (LPBYTE)empty_data_content;
149 return (HCRYPTMSG)msg;
152 static inline const char *MSG_TYPE_STR(DWORD type)
154 switch (type)
156 #define _x(x) case (x): return #x
157 _x(CMSG_DATA);
158 _x(CMSG_SIGNED);
159 _x(CMSG_ENVELOPED);
160 _x(CMSG_SIGNED_AND_ENVELOPED);
161 _x(CMSG_HASHED);
162 _x(CMSG_ENCRYPTED);
163 #undef _x
164 default:
165 return wine_dbg_sprintf("unknown (%d)", type);
169 HCRYPTMSG WINAPI CryptMsgOpenToEncode(DWORD dwMsgEncodingType, DWORD dwFlags,
170 DWORD dwMsgType, const void *pvMsgEncodeInfo, LPSTR pszInnerContentObjID,
171 PCMSG_STREAM_INFO pStreamInfo)
173 HCRYPTMSG msg = NULL;
175 TRACE("(%08x, %08x, %08x, %p, %s, %p)\n", dwMsgEncodingType, dwFlags,
176 dwMsgType, pvMsgEncodeInfo, debugstr_a(pszInnerContentObjID), pStreamInfo);
178 if (GET_CMSG_ENCODING_TYPE(dwMsgEncodingType) != PKCS_7_ASN_ENCODING)
180 SetLastError(E_INVALIDARG);
181 return NULL;
183 switch (dwMsgType)
185 case CMSG_DATA:
186 msg = CDataEncodeMsg_Open(dwFlags, pvMsgEncodeInfo,
187 pszInnerContentObjID, pStreamInfo);
188 break;
189 case CMSG_SIGNED:
190 case CMSG_ENVELOPED:
191 case CMSG_HASHED:
192 FIXME("unimplemented for type %s\n", MSG_TYPE_STR(dwMsgType));
193 break;
194 case CMSG_SIGNED_AND_ENVELOPED:
195 case CMSG_ENCRYPTED:
196 /* defined but invalid, fall through */
197 default:
198 SetLastError(CRYPT_E_INVALID_MSG_TYPE);
200 return msg;
203 HCRYPTMSG WINAPI CryptMsgOpenToDecode(DWORD dwMsgEncodingType, DWORD dwFlags,
204 DWORD dwMsgType, HCRYPTPROV hCryptProv, PCERT_INFO pRecipientInfo,
205 PCMSG_STREAM_INFO pStreamInfo)
207 FIXME("(%08x, %08x, %08x, %08lx, %p, %p): stub\n", dwMsgEncodingType,
208 dwFlags, dwMsgType, hCryptProv, pRecipientInfo, pStreamInfo);
210 if (GET_CMSG_ENCODING_TYPE(dwMsgEncodingType) != PKCS_7_ASN_ENCODING)
212 SetLastError(E_INVALIDARG);
213 return NULL;
215 return NULL;
218 HCRYPTMSG WINAPI CryptMsgDuplicate(HCRYPTMSG hCryptMsg)
220 TRACE("(%p)\n", hCryptMsg);
222 if (hCryptMsg)
224 CryptMsgBase *msg = (CryptMsgBase *)hCryptMsg;
226 InterlockedIncrement(&msg->ref);
228 return hCryptMsg;
231 BOOL WINAPI CryptMsgClose(HCRYPTMSG hCryptMsg)
233 TRACE("(%p)\n", hCryptMsg);
235 if (hCryptMsg)
237 CryptMsgBase *msg = (CryptMsgBase *)hCryptMsg;
239 if (InterlockedDecrement(&msg->ref) == 0)
241 TRACE("freeing %p\n", msg);
242 if (msg->close)
243 msg->close(msg);
244 CryptMemFree(msg);
247 return TRUE;
250 BOOL WINAPI CryptMsgUpdate(HCRYPTMSG hCryptMsg, const BYTE *pbData,
251 DWORD cbData, BOOL fFinal)
253 CryptMsgBase *msg = (CryptMsgBase *)hCryptMsg;
254 BOOL ret = FALSE;
256 TRACE("(%p, %p, %d, %d)\n", hCryptMsg, pbData, cbData, fFinal);
257 if (msg && msg->update)
258 ret = msg->update(hCryptMsg, pbData, cbData, fFinal);
259 return ret;
262 BOOL WINAPI CryptMsgGetParam(HCRYPTMSG hCryptMsg, DWORD dwParamType,
263 DWORD dwIndex, void *pvData, DWORD *pcbData)
265 CryptMsgBase *msg = (CryptMsgBase *)hCryptMsg;
266 BOOL ret = FALSE;
268 TRACE("(%p, %d, %d, %p, %p)\n", hCryptMsg, dwParamType, dwIndex,
269 pvData, pcbData);
270 if (msg && msg->get_param)
271 ret = msg->get_param(hCryptMsg, dwParamType, dwIndex, pvData, pcbData);
272 return ret;