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
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
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
42 PCMSG_STREAM_INFO stream_info;
43 CryptMsgCloseFunc close;
44 CryptMsgUpdateFunc update;
45 CryptMsgGetParamFunc get_param;
48 static inline void CryptMsgBase_Init(CryptMsgBase *msg, DWORD dwFlags,
49 PCMSG_STREAM_INFO pStreamInfo)
52 msg->open_flags = dwFlags;
53 msg->stream_info = pStreamInfo;
56 typedef struct _CDataEncodeMsg
61 static HCRYPTMSG CDataEncodeMsg_Open(DWORD dwFlags, const void *pvMsgEncodeInfo,
62 LPSTR pszInnerContentObjID, PCMSG_STREAM_INFO pStreamInfo)
68 SetLastError(E_INVALIDARG);
72 msg = CryptMemAlloc(sizeof(CDataEncodeMsg));
75 CryptMsgBase_Init((CryptMsgBase *)msg, dwFlags, pStreamInfo);
77 return (HCRYPTMSG)msg;
80 static inline const char *MSG_TYPE_STR(DWORD type)
84 #define _x(x) case (x): return #x
88 _x(CMSG_SIGNED_AND_ENVELOPED);
93 return wine_dbg_sprintf("unknown (%d)", type);
97 HCRYPTMSG WINAPI CryptMsgOpenToEncode(DWORD dwMsgEncodingType, DWORD dwFlags,
98 DWORD dwMsgType, const void *pvMsgEncodeInfo, LPSTR pszInnerContentObjID,
99 PCMSG_STREAM_INFO pStreamInfo)
101 HCRYPTMSG msg = NULL;
103 TRACE("(%08x, %08x, %08x, %p, %s, %p)\n", dwMsgEncodingType, dwFlags,
104 dwMsgType, pvMsgEncodeInfo, debugstr_a(pszInnerContentObjID), pStreamInfo);
106 if (GET_CMSG_ENCODING_TYPE(dwMsgEncodingType) != PKCS_7_ASN_ENCODING)
108 SetLastError(E_INVALIDARG);
114 msg = CDataEncodeMsg_Open(dwFlags, pvMsgEncodeInfo,
115 pszInnerContentObjID, pStreamInfo);
120 FIXME("unimplemented for type %s\n", MSG_TYPE_STR(dwMsgType));
122 case CMSG_SIGNED_AND_ENVELOPED:
124 /* defined but invalid, fall through */
126 SetLastError(CRYPT_E_INVALID_MSG_TYPE);
131 HCRYPTMSG WINAPI CryptMsgOpenToDecode(DWORD dwMsgEncodingType, DWORD dwFlags,
132 DWORD dwMsgType, HCRYPTPROV hCryptProv, PCERT_INFO pRecipientInfo,
133 PCMSG_STREAM_INFO pStreamInfo)
135 FIXME("(%08x, %08x, %08x, %08lx, %p, %p): stub\n", dwMsgEncodingType,
136 dwFlags, dwMsgType, hCryptProv, pRecipientInfo, pStreamInfo);
138 if (GET_CMSG_ENCODING_TYPE(dwMsgEncodingType) != PKCS_7_ASN_ENCODING)
140 SetLastError(E_INVALIDARG);
146 HCRYPTMSG WINAPI CryptMsgDuplicate(HCRYPTMSG hCryptMsg)
148 TRACE("(%p)\n", hCryptMsg);
152 CryptMsgBase *msg = (CryptMsgBase *)hCryptMsg;
154 InterlockedIncrement(&msg->ref);
159 BOOL WINAPI CryptMsgClose(HCRYPTMSG hCryptMsg)
161 TRACE("(%p)\n", hCryptMsg);
165 CryptMsgBase *msg = (CryptMsgBase *)hCryptMsg;
167 if (InterlockedDecrement(&msg->ref) == 0)
169 TRACE("freeing %p\n", msg);
178 BOOL WINAPI CryptMsgUpdate(HCRYPTMSG hCryptMsg, const BYTE *pbData,
179 DWORD cbData, BOOL fFinal)
181 CryptMsgBase *msg = (CryptMsgBase *)hCryptMsg;
184 TRACE("(%p, %p, %d, %d)\n", hCryptMsg, pbData, cbData, fFinal);
185 if (msg && msg->update)
186 ret = msg->update(hCryptMsg, pbData, cbData, fFinal);
190 BOOL WINAPI CryptMsgGetParam(HCRYPTMSG hCryptMsg, DWORD dwParamType,
191 DWORD dwIndex, void *pvData, DWORD *pcbData)
193 CryptMsgBase *msg = (CryptMsgBase *)hCryptMsg;
196 TRACE("(%p, %d, %d, %p, %p)\n", hCryptMsg, dwParamType, dwIndex,
198 if (msg && msg->get_param)
199 ret = msg->get_param(hCryptMsg, dwParamType, dwIndex, pvData, pcbData);