ReactOS  0.4.14-dev-556-g4c5b21f
msg.c
Go to the documentation of this file.
1 /*
2  * Copyright 2007 Juan Lang
3  *
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.
8  *
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.
13  *
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
17  */
18 
19 #include "config.h"
20 #include "wine/port.h"
21 
22 #include <stdarg.h>
23 #define NONAMELESSUNION
24 #include "windef.h"
25 #include "winbase.h"
26 #include "wincrypt.h"
27 #include "snmp.h"
28 
29 #include "wine/debug.h"
30 #include "wine/exception.h"
31 #include "crypt32_private.h"
32 
34 
35 /* Called when a message's ref count reaches zero. Free any message-specific
36  * data here.
37  */
39 
40 typedef BOOL (*CryptMsgGetParamFunc)(HCRYPTMSG hCryptMsg, DWORD dwParamType,
41  DWORD dwIndex, void *pvData, DWORD *pcbData);
42 
43 typedef BOOL (*CryptMsgUpdateFunc)(HCRYPTMSG hCryptMsg, const BYTE *pbData,
44  DWORD cbData, BOOL fFinal);
45 
47  DWORD dwCtrlType, const void *pvCtrlPara);
48 
50  DWORD dwCtrlType, const void *pvCtrlPara)
51 {
52  TRACE("(%p, %08x, %d, %p)\n", hCryptMsg, dwFlags, dwCtrlType, pvCtrlPara);
54  return FALSE;
55 }
56 
57 typedef enum _CryptMsgState {
63 
64 typedef struct _CryptMsgBase
65 {
75 } CryptMsgBase;
76 
79  CryptMsgGetParamFunc get_param, CryptMsgUpdateFunc update,
80  CryptMsgControlFunc control)
81 {
82  msg->ref = 1;
83  msg->open_flags = dwFlags;
84  if (pStreamInfo)
85  {
86  msg->streamed = TRUE;
87  msg->stream_info = *pStreamInfo;
88  }
89  else
90  {
91  msg->streamed = FALSE;
92  memset(&msg->stream_info, 0, sizeof(msg->stream_info));
93  }
94  msg->close = close;
95  msg->get_param = get_param;
96  msg->update = update;
97  msg->control = control;
98  msg->state = MsgStateInit;
99 }
100 
101 typedef struct _CDataEncodeMsg
102 {
107 
108 static const BYTE empty_data_content[] = { 0x04,0x00 };
109 
110 static void CDataEncodeMsg_Close(HCRYPTMSG hCryptMsg)
111 {
112  CDataEncodeMsg *msg = hCryptMsg;
113 
114  if (msg->bare_content != empty_data_content)
115  LocalFree(msg->bare_content);
116 }
117 
119  LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
121 {
122  DWORD dataLen = *(DWORD *)pvStructInfo;
123  DWORD lenBytes;
124  BOOL ret = TRUE;
125 
126  /* Trick: report bytes needed based on total message length, even though
127  * the message isn't available yet. The caller will use the length
128  * reported here to encode its length.
129  */
130  CRYPT_EncodeLen(dataLen, NULL, &lenBytes);
131  if (!pbEncoded)
132  *pcbEncoded = 1 + lenBytes + dataLen;
133  else
134  {
135  if ((ret = CRYPT_EncodeEnsureSpace(dwFlags, pEncodePara, pbEncoded,
136  pcbEncoded, 1 + lenBytes)))
137  {
139  pbEncoded = *(BYTE **)pbEncoded;
141  CRYPT_EncodeLen(dataLen, pbEncoded,
142  &lenBytes);
143  }
144  }
145  return ret;
146 }
147 
150 {
151  BOOL ret;
152 
153  if (msg->base.streamed && msg->base.stream_info.cbContent == 0xffffffff)
154  {
155  static const BYTE headerValue[] = { 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,
156  0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x80,0x24,0x80 };
157 
158  header->pbData = LocalAlloc(0, sizeof(headerValue));
159  if (header->pbData)
160  {
161  header->cbData = sizeof(headerValue);
162  memcpy(header->pbData, headerValue, sizeof(headerValue));
163  ret = TRUE;
164  }
165  else
166  ret = FALSE;
167  }
168  else
169  {
170  struct AsnConstructedItem constructed = { 0,
171  &msg->base.stream_info.cbContent, CRYPT_EncodeContentLength };
172  struct AsnEncodeSequenceItem items[2] = {
174  { &constructed, CRYPT_AsnEncodeConstructed, 0 },
175  };
176 
179  (LPBYTE)&header->pbData, &header->cbData);
180  if (ret)
181  {
182  /* Trick: subtract the content length from the reported length,
183  * as the actual content hasn't come yet.
184  */
185  header->cbData -= msg->base.stream_info.cbContent;
186  }
187  }
188  return ret;
189 }
190 
191 static BOOL CDataEncodeMsg_Update(HCRYPTMSG hCryptMsg, const BYTE *pbData,
192  DWORD cbData, BOOL fFinal)
193 {
194  CDataEncodeMsg *msg = hCryptMsg;
195  BOOL ret = FALSE;
196 
197  if (msg->base.state == MsgStateFinalized)
199  else if (msg->base.streamed)
200  {
201  __TRY
202  {
203  if (msg->base.state != MsgStateUpdated)
204  {
206 
208  if (ret)
209  {
210  ret = msg->base.stream_info.pfnStreamOutput(
211  msg->base.stream_info.pvArg, header.pbData, header.cbData,
212  FALSE);
213  LocalFree(header.pbData);
214  }
215  }
216  /* Curiously, every indefinite-length streamed update appears to
217  * get its own tag and length, regardless of fFinal.
218  */
219  if (msg->base.stream_info.cbContent == 0xffffffff)
220  {
221  BYTE *header;
222  DWORD headerLen;
223 
225  &cbData, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&header,
226  &headerLen);
227  if (ret)
228  {
229  ret = msg->base.stream_info.pfnStreamOutput(
230  msg->base.stream_info.pvArg, header, headerLen,
231  FALSE);
232  LocalFree(header);
233  }
234  }
235  if (!fFinal)
236  {
237  ret = msg->base.stream_info.pfnStreamOutput(
238  msg->base.stream_info.pvArg, (BYTE *)pbData, cbData,
239  FALSE);
240  msg->base.state = MsgStateUpdated;
241  }
242  else
243  {
244  msg->base.state = MsgStateFinalized;
245  if (msg->base.stream_info.cbContent == 0xffffffff)
246  {
247  BYTE indefinite_trailer[6] = { 0 };
248 
249  ret = msg->base.stream_info.pfnStreamOutput(
250  msg->base.stream_info.pvArg, (BYTE *)pbData, cbData,
251  FALSE);
252  if (ret)
253  ret = msg->base.stream_info.pfnStreamOutput(
254  msg->base.stream_info.pvArg, indefinite_trailer,
255  sizeof(indefinite_trailer), TRUE);
256  }
257  else
258  ret = msg->base.stream_info.pfnStreamOutput(
259  msg->base.stream_info.pvArg, (BYTE *)pbData, cbData, TRUE);
260  }
261  }
263  {
265  ret = FALSE;
266  }
267  __ENDTRY;
268  }
269  else
270  {
271  if (!fFinal)
272  {
273  if (msg->base.open_flags & CMSG_DETACHED_FLAG)
275  else
277  }
278  else
279  {
280  CRYPT_DATA_BLOB blob = { cbData, (LPBYTE)pbData };
281 
282  msg->base.state = MsgStateFinalized;
283  /* non-streamed data messages don't allow non-final updates,
284  * don't bother checking whether data already exist, they can't.
285  */
287  &blob, CRYPT_ENCODE_ALLOC_FLAG, NULL, &msg->bare_content,
288  &msg->bare_content_len);
289  }
290  }
291  return ret;
292 }
293 
294 static BOOL CRYPT_CopyParam(void *pvData, DWORD *pcbData, const void *src,
295  DWORD len)
296 {
297  BOOL ret = TRUE;
298 
299  if (!pvData)
300  *pcbData = len;
301  else if (*pcbData < len)
302  {
303  *pcbData = len;
305  ret = FALSE;
306  }
307  else
308  {
309  *pcbData = len;
310  memcpy(pvData, src, len);
311  }
312  return ret;
313 }
314 
315 static BOOL CDataEncodeMsg_GetParam(HCRYPTMSG hCryptMsg, DWORD dwParamType,
316  DWORD dwIndex, void *pvData, DWORD *pcbData)
317 {
318  CDataEncodeMsg *msg = hCryptMsg;
319  BOOL ret = FALSE;
320 
321  switch (dwParamType)
322  {
323  case CMSG_CONTENT_PARAM:
324  if (msg->base.streamed)
326  else
327  {
329  char rsa_data[] = "1.2.840.113549.1.7.1";
330 
331  info.pszObjId = rsa_data;
332  info.Content.cbData = msg->bare_content_len;
333  info.Content.pbData = msg->bare_content;
335  pvData, pcbData);
336  }
337  break;
339  if (msg->base.streamed)
341  else
342  ret = CRYPT_CopyParam(pvData, pcbData, msg->bare_content,
343  msg->bare_content_len);
344  break;
345  default:
347  }
348  return ret;
349 }
350 
351 static HCRYPTMSG CDataEncodeMsg_Open(DWORD dwFlags, const void *pvMsgEncodeInfo,
352  LPSTR pszInnerContentObjID, PCMSG_STREAM_INFO pStreamInfo)
353 {
355 
356  if (pvMsgEncodeInfo)
357  {
359  return NULL;
360  }
361  msg = CryptMemAlloc(sizeof(CDataEncodeMsg));
362  if (msg)
363  {
364  CryptMsgBase_Init((CryptMsgBase *)msg, dwFlags, pStreamInfo,
367  msg->bare_content_len = sizeof(empty_data_content);
368  msg->bare_content = (LPBYTE)empty_data_content;
369  }
370  return msg;
371 }
372 
373 typedef struct _CHashEncodeMsg
374 {
380 
381 static void CHashEncodeMsg_Close(HCRYPTMSG hCryptMsg)
382 {
383  CHashEncodeMsg *msg = hCryptMsg;
384 
385  CryptMemFree(msg->data.pbData);
386  CryptDestroyHash(msg->hash);
387  if (msg->base.open_flags & CMSG_CRYPT_RELEASE_CONTEXT_FLAG)
388  CryptReleaseContext(msg->prov, 0);
389 }
390 
392  DWORD *pcbData)
393 {
394  BOOL ret;
395  ALG_ID algID;
396  DWORD size = sizeof(algID);
397 
398  ret = CryptGetHashParam(msg->hash, HP_ALGID, (BYTE *)&algID, &size, 0);
399  if (ret)
400  {
401  CRYPT_DIGESTED_DATA digestedData = { 0 };
402  char oid_rsa_data[] = szOID_RSA_data;
403 
405  digestedData.DigestAlgorithm.pszObjId = (LPSTR)CertAlgIdToOID(algID);
406  /* FIXME: what about digestedData.DigestAlgorithm.Parameters? */
407  /* Quirk: OID is only encoded messages if an update has happened */
408  if (msg->base.state != MsgStateInit)
409  digestedData.ContentInfo.pszObjId = oid_rsa_data;
410  if (!(msg->base.open_flags & CMSG_DETACHED_FLAG) && msg->data.cbData)
411  {
412  ret = CRYPT_AsnEncodeOctets(0, NULL, &msg->data,
414  (LPBYTE)&digestedData.ContentInfo.Content.pbData,
415  &digestedData.ContentInfo.Content.cbData);
416  }
417  if (msg->base.state == MsgStateFinalized)
418  {
419  size = sizeof(DWORD);
421  (LPBYTE)&digestedData.hash.cbData, &size, 0);
422  if (ret)
423  {
424  digestedData.hash.pbData = CryptMemAlloc(
425  digestedData.hash.cbData);
427  digestedData.hash.pbData, &digestedData.hash.cbData, 0);
428  }
429  }
430  if (ret)
431  ret = CRYPT_AsnEncodePKCSDigestedData(&digestedData, pvData,
432  pcbData);
433  CryptMemFree(digestedData.hash.pbData);
434  LocalFree(digestedData.ContentInfo.Content.pbData);
435  }
436  return ret;
437 }
438 
439 static BOOL CHashEncodeMsg_GetParam(HCRYPTMSG hCryptMsg, DWORD dwParamType,
440  DWORD dwIndex, void *pvData, DWORD *pcbData)
441 {
442  CHashEncodeMsg *msg = hCryptMsg;
443  BOOL ret = FALSE;
444 
445  TRACE("(%p, %d, %d, %p, %p)\n", hCryptMsg, dwParamType, dwIndex,
446  pvData, pcbData);
447 
448  switch (dwParamType)
449  {
451  if (msg->base.streamed)
453  else
455  break;
456  case CMSG_CONTENT_PARAM:
457  {
459 
461  &info.Content.cbData);
462  if (ret)
463  {
464  info.Content.pbData = CryptMemAlloc(info.Content.cbData);
465  if (info.Content.pbData)
466  {
468  info.Content.pbData, &info.Content.cbData);
469  if (ret)
470  {
471  char oid_rsa_hashed[] = szOID_RSA_hashedData;
472 
473  info.pszObjId = oid_rsa_hashed;
476  }
477  CryptMemFree(info.Content.pbData);
478  }
479  else
480  ret = FALSE;
481  }
482  break;
483  }
486  break;
487  case CMSG_VERSION_PARAM:
488  if (msg->base.state != MsgStateFinalized)
490  else
491  {
493 
494  /* Since the data are always encoded as octets, the version is
495  * always 0 (see rfc3852, section 7)
496  */
498  }
499  break;
500  default:
502  }
503  return ret;
504 }
505 
506 static BOOL CHashEncodeMsg_Update(HCRYPTMSG hCryptMsg, const BYTE *pbData,
507  DWORD cbData, BOOL fFinal)
508 {
509  CHashEncodeMsg *msg = hCryptMsg;
510  BOOL ret = FALSE;
511 
512  TRACE("(%p, %p, %d, %d)\n", hCryptMsg, pbData, cbData, fFinal);
513 
514  if (msg->base.state == MsgStateFinalized)
516  else if (msg->base.streamed || (msg->base.open_flags & CMSG_DETACHED_FLAG))
517  {
518  /* Doesn't do much, as stream output is never called, and you
519  * can't get the content.
520  */
521  ret = CryptHashData(msg->hash, pbData, cbData, 0);
522  msg->base.state = fFinal ? MsgStateFinalized : MsgStateUpdated;
523  }
524  else
525  {
526  if (!fFinal)
528  else
529  {
530  ret = CryptHashData(msg->hash, pbData, cbData, 0);
531  if (ret)
532  {
533  msg->data.pbData = CryptMemAlloc(cbData);
534  if (msg->data.pbData)
535  {
536  memcpy(msg->data.pbData + msg->data.cbData, pbData, cbData);
537  msg->data.cbData += cbData;
538  }
539  else
540  ret = FALSE;
541  }
542  msg->base.state = MsgStateFinalized;
543  }
544  }
545  return ret;
546 }
547 
548 static HCRYPTMSG CHashEncodeMsg_Open(DWORD dwFlags, const void *pvMsgEncodeInfo,
549  LPSTR pszInnerContentObjID, PCMSG_STREAM_INFO pStreamInfo)
550 {
552  const CMSG_HASHED_ENCODE_INFO *info = pvMsgEncodeInfo;
553  HCRYPTPROV prov;
554  ALG_ID algID;
555 
556  if (info->cbSize != sizeof(CMSG_HASHED_ENCODE_INFO))
557  {
559  return NULL;
560  }
561  if (!(algID = CertOIDToAlgId(info->HashAlgorithm.pszObjId)))
562  {
564  return NULL;
565  }
566  if (info->hCryptProv)
567  prov = info->hCryptProv;
568  else
569  {
570  prov = I_CryptGetDefaultCryptProv(algID);
571  if (!prov)
572  {
574  return NULL;
575  }
577  }
578  msg = CryptMemAlloc(sizeof(CHashEncodeMsg));
579  if (msg)
580  {
581  CryptMsgBase_Init((CryptMsgBase *)msg, dwFlags, pStreamInfo,
584  msg->prov = prov;
585  msg->data.cbData = 0;
586  msg->data.pbData = NULL;
587  if (!CryptCreateHash(prov, algID, 0, 0, &msg->hash))
588  {
590  msg = NULL;
591  }
592  }
593  return msg;
594 }
595 
597 {
612 
614 {
625 
627 {
628  if (signer->cbSize != sizeof(CMSG_SIGNER_ENCODE_INFO) &&
629  signer->cbSize != sizeof(CMSG_SIGNER_ENCODE_INFO_WITH_CMS))
630  {
632  return FALSE;
633  }
634  if (signer->cbSize == sizeof(CMSG_SIGNER_ENCODE_INFO))
635  {
636  if (!signer->pCertInfo->SerialNumber.cbData)
637  {
639  return FALSE;
640  }
641  if (!signer->pCertInfo->Issuer.cbData)
642  {
644  return FALSE;
645  }
646  }
647  else if (signer->cbSize == sizeof(CMSG_SIGNER_ENCODE_INFO_WITH_CMS))
648  {
649  switch (signer->SignerId.dwIdChoice)
650  {
651  case 0:
652  if (!signer->pCertInfo->SerialNumber.cbData)
653  {
655  return FALSE;
656  }
657  if (!signer->pCertInfo->Issuer.cbData)
658  {
660  return FALSE;
661  }
662  break;
665  {
667  return FALSE;
668  }
669  if (!signer->SignerId.u.IssuerSerialNumber.Issuer.cbData)
670  {
672  return FALSE;
673  }
674  break;
676  if (!signer->SignerId.u.KeyId.cbData)
677  {
679  return FALSE;
680  }
681  break;
682  default:
684  }
685  if (signer->HashEncryptionAlgorithm.pszObjId)
686  {
687  FIXME("CMSG_SIGNER_ENCODE_INFO with CMS fields unsupported\n");
688  return FALSE;
689  }
690  }
691  if (!signer->hCryptProv)
692  {
694  return FALSE;
695  }
696  if (!CertOIDToAlgId(signer->HashAlgorithm.pszObjId))
697  {
699  return FALSE;
700  }
701  return TRUE;
702 }
703 
705 {
706  BOOL ret = TRUE;
707 
708  out->cbData = in->cbData;
709  if (out->cbData)
710  {
711  out->pbData = CryptMemAlloc(out->cbData);
712  if (out->pbData)
713  memcpy(out->pbData, in->pbData, out->cbData);
714  else
715  ret = FALSE;
716  }
717  else
718  out->pbData = NULL;
719  return ret;
720 }
721 
723  PCRYPT_DATA_BLOB *outPBlobs, DWORD cBlobs, const CRYPT_DATA_BLOB *pBlobs)
724 {
725  BOOL ret = TRUE;
726 
727  *outCBlobs = cBlobs;
728  if (cBlobs)
729  {
730  *outPBlobs = CryptMemAlloc(cBlobs * sizeof(CRYPT_DATA_BLOB));
731  if (*outPBlobs)
732  {
733  DWORD i;
734 
735  memset(*outPBlobs, 0, cBlobs * sizeof(CRYPT_DATA_BLOB));
736  for (i = 0; ret && i < cBlobs; i++)
737  ret = CRYPT_ConstructBlob(&(*outPBlobs)[i], &pBlobs[i]);
738  }
739  else
740  ret = FALSE;
741  }
742  return ret;
743 }
744 
745 static void CRYPT_FreeBlobArray(DWORD cBlobs, PCRYPT_DATA_BLOB blobs)
746 {
747  DWORD i;
748 
749  for (i = 0; i < cBlobs; i++)
750  CryptMemFree(blobs[i].pbData);
751  CryptMemFree(blobs);
752 }
753 
755  const CRYPT_ATTRIBUTE *in)
756 {
757  BOOL ret;
758 
759  out->pszObjId = CryptMemAlloc(strlen(in->pszObjId) + 1);
760  if (out->pszObjId)
761  {
762  strcpy(out->pszObjId, in->pszObjId);
763  ret = CRYPT_ConstructBlobArray(&out->cValue, &out->rgValue,
764  in->cValue, in->rgValue);
765  }
766  else
767  ret = FALSE;
768  return ret;
769 }
770 
772  const CRYPT_ATTRIBUTES *in)
773 {
774  BOOL ret = TRUE;
775 
776  out->cAttr = in->cAttr;
777  if (out->cAttr)
778  {
779  out->rgAttr = CryptMemAlloc(out->cAttr * sizeof(CRYPT_ATTRIBUTE));
780  if (out->rgAttr)
781  {
782  DWORD i;
783 
784  memset(out->rgAttr, 0, out->cAttr * sizeof(CRYPT_ATTRIBUTE));
785  for (i = 0; ret && i < out->cAttr; i++)
786  ret = CRYPT_ConstructAttribute(&out->rgAttr[i], &in->rgAttr[i]);
787  }
788  else
789  ret = FALSE;
790  }
791  else
792  out->rgAttr = NULL;
793  return ret;
794 }
795 
796 /* Constructs a CMSG_CMS_SIGNER_INFO from a CMSG_SIGNER_ENCODE_INFO_WITH_CMS. */
799 {
800  BOOL ret;
801 
802  if (in->cbSize == sizeof(CMSG_SIGNER_ENCODE_INFO))
803  {
804  info->dwVersion = CMSG_SIGNER_INFO_V1;
805  ret = CRYPT_ConstructBlob(&info->SignerId.u.IssuerSerialNumber.Issuer,
806  &in->pCertInfo->Issuer);
807  if (ret)
809  &info->SignerId.u.IssuerSerialNumber.SerialNumber,
810  &in->pCertInfo->SerialNumber);
811  info->SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
812  info->HashEncryptionAlgorithm.pszObjId =
813  in->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId;
814  if (ret)
815  ret = CRYPT_ConstructBlob(&info->HashEncryptionAlgorithm.Parameters,
816  &in->pCertInfo->SubjectPublicKeyInfo.Algorithm.Parameters);
817  }
818  else
819  {
820  const CRYPT_ALGORITHM_IDENTIFIER *pEncrAlg;
821 
822  /* Implicitly in->cbSize == sizeof(CMSG_SIGNER_ENCODE_INFO_WITH_CMS).
823  * See CRYPT_IsValidSigner.
824  */
825  if (!in->SignerId.dwIdChoice)
826  {
827  info->dwVersion = CMSG_SIGNER_INFO_V1;
828  ret = CRYPT_ConstructBlob(&info->SignerId.u.IssuerSerialNumber.Issuer,
829  &in->pCertInfo->Issuer);
830  if (ret)
832  &info->SignerId.u.IssuerSerialNumber.SerialNumber,
833  &in->pCertInfo->SerialNumber);
834  info->SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
835  }
836  else if (in->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER)
837  {
838  info->dwVersion = CMSG_SIGNER_INFO_V1;
839  info->SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
840  ret = CRYPT_ConstructBlob(&info->SignerId.u.IssuerSerialNumber.Issuer,
841  &in->SignerId.u.IssuerSerialNumber.Issuer);
842  if (ret)
844  &info->SignerId.u.IssuerSerialNumber.SerialNumber,
845  &in->SignerId.u.IssuerSerialNumber.SerialNumber);
846  }
847  else
848  {
849  /* Implicitly dwIdChoice == CERT_ID_KEY_IDENTIFIER */
850  info->dwVersion = CMSG_SIGNER_INFO_V3;
851  info->SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
852  ret = CRYPT_ConstructBlob(&info->SignerId.u.KeyId,
853  &in->SignerId.u.KeyId);
854  }
855  pEncrAlg = in->HashEncryptionAlgorithm.pszObjId ?
856  &in->HashEncryptionAlgorithm :
857  &in->pCertInfo->SubjectPublicKeyInfo.Algorithm;
858  info->HashEncryptionAlgorithm.pszObjId = pEncrAlg->pszObjId;
859  if (ret)
860  ret = CRYPT_ConstructBlob(&info->HashEncryptionAlgorithm.Parameters,
861  &pEncrAlg->Parameters);
862  }
863  /* Assumption: algorithm IDs will point to static strings, not
864  * stack-based ones, so copying the pointer values is safe.
865  */
866  info->HashAlgorithm.pszObjId = in->HashAlgorithm.pszObjId;
867  if (ret)
868  ret = CRYPT_ConstructBlob(&info->HashAlgorithm.Parameters,
869  &in->HashAlgorithm.Parameters);
870  if (ret)
871  ret = CRYPT_ConstructAttributes(&info->AuthAttrs,
872  (CRYPT_ATTRIBUTES *)&in->cAuthAttr);
873  if (ret)
874  ret = CRYPT_ConstructAttributes(&info->UnauthAttrs,
875  (CRYPT_ATTRIBUTES *)&in->cUnauthAttr);
876  return ret;
877 }
878 
880 {
881  DWORD i, j;
882 
883  if (info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER)
884  {
885  CryptMemFree(info->SignerId.u.IssuerSerialNumber.Issuer.pbData);
886  CryptMemFree(info->SignerId.u.IssuerSerialNumber.SerialNumber.pbData);
887  }
888  else
889  CryptMemFree(info->SignerId.u.KeyId.pbData);
890  CryptMemFree(info->HashAlgorithm.Parameters.pbData);
891  CryptMemFree(info->HashEncryptionAlgorithm.Parameters.pbData);
892  CryptMemFree(info->EncryptedHash.pbData);
893  for (i = 0; i < info->AuthAttrs.cAttr; i++)
894  {
895  for (j = 0; j < info->AuthAttrs.rgAttr[i].cValue; j++)
896  CryptMemFree(info->AuthAttrs.rgAttr[i].rgValue[j].pbData);
897  CryptMemFree(info->AuthAttrs.rgAttr[i].rgValue);
898  CryptMemFree(info->AuthAttrs.rgAttr[i].pszObjId);
899  }
900  CryptMemFree(info->AuthAttrs.rgAttr);
901  for (i = 0; i < info->UnauthAttrs.cAttr; i++)
902  {
903  for (j = 0; j < info->UnauthAttrs.rgAttr[i].cValue; j++)
904  CryptMemFree(info->UnauthAttrs.rgAttr[i].rgValue[j].pbData);
905  CryptMemFree(info->UnauthAttrs.rgAttr[i].rgValue);
906  CryptMemFree(info->UnauthAttrs.rgAttr[i].pszObjId);
907  }
908  CryptMemFree(info->UnauthAttrs.rgAttr);
909 }
910 
911 typedef struct _CSignerHandles
912 {
916 
917 typedef struct _CSignedMsgData
918 {
923 
924 /* Constructs the signer handles for the signerIndex'th signer of msg_data.
925  * Assumes signerIndex is a valid idnex, and that msg_data's info has already
926  * been constructed.
927  */
929  DWORD signerIndex, HCRYPTPROV *crypt_prov, DWORD *flags)
930 {
931  ALG_ID algID;
932  BOOL ret;
933 
934  algID = CertOIDToAlgId(
935  msg_data->info->rgSignerInfo[signerIndex].HashAlgorithm.pszObjId);
936 
937  if (!*crypt_prov)
938  {
940  if (!*crypt_prov) return FALSE;
942  }
943 
944  ret = CryptCreateHash(*crypt_prov, algID, 0, 0,
945  &msg_data->signerHandles->contentHash);
946  if (ret && msg_data->info->rgSignerInfo[signerIndex].AuthAttrs.cAttr > 0)
947  ret = CryptCreateHash(*crypt_prov, algID, 0, 0,
948  &msg_data->signerHandles->authAttrHash);
949  return ret;
950 }
951 
952 /* Allocates a CSignedMsgData's handles. Assumes its info has already been
953  * constructed.
954  */
956 {
957  BOOL ret = TRUE;
958 
959  if (msg_data->info->cSignerInfo)
960  {
961  msg_data->signerHandles =
962  CryptMemAlloc(msg_data->info->cSignerInfo * sizeof(CSignerHandles));
963  if (msg_data->signerHandles)
964  {
965  msg_data->cSignerHandle = msg_data->info->cSignerInfo;
966  memset(msg_data->signerHandles, 0,
967  msg_data->info->cSignerInfo * sizeof(CSignerHandles));
968  }
969  else
970  {
971  msg_data->cSignerHandle = 0;
972  ret = FALSE;
973  }
974  }
975  else
976  {
977  msg_data->cSignerHandle = 0;
978  msg_data->signerHandles = NULL;
979  }
980  return ret;
981 }
982 
984 {
985  DWORD i;
986 
987  for (i = 0; i < msg_data->cSignerHandle; i++)
988  {
989  if (msg_data->signerHandles[i].contentHash)
991  if (msg_data->signerHandles[i].authAttrHash)
993  }
994  CryptMemFree(msg_data->signerHandles);
995  msg_data->signerHandles = NULL;
996  msg_data->cSignerHandle = 0;
997 }
998 
1000  const BYTE *pbData, DWORD cbData)
1001 {
1002  DWORD i;
1003  BOOL ret = TRUE;
1004 
1005  for (i = 0; ret && i < msg_data->cSignerHandle; i++)
1007  cbData, 0);
1008  return ret;
1009 }
1010 
1012  const CRYPT_ATTRIBUTE *in)
1013 {
1014  BOOL ret = FALSE;
1015 
1016  out->rgAttr = CryptMemRealloc(out->rgAttr,
1017  (out->cAttr + 1) * sizeof(CRYPT_ATTRIBUTE));
1018  if (out->rgAttr)
1019  {
1020  ret = CRYPT_ConstructAttribute(&out->rgAttr[out->cAttr], in);
1021  if (ret)
1022  out->cAttr++;
1023  }
1024  return ret;
1025 }
1026 
1028  CSignedMsgData *msg_data, DWORD signerIndex)
1029 {
1030  BOOL ret;
1031  DWORD size;
1032  CRYPT_HASH_BLOB hash = { 0, NULL }, encodedHash = { 0, NULL };
1033  char messageDigest[] = szOID_RSA_messageDigest;
1034  CRYPT_ATTRIBUTE messageDigestAttr = { messageDigest, 1, &encodedHash };
1035 
1036  size = sizeof(DWORD);
1038  msg_data->signerHandles[signerIndex].contentHash, HP_HASHSIZE,
1039  (LPBYTE)&hash.cbData, &size, 0);
1040  if (ret)
1041  {
1042  hash.pbData = CryptMemAlloc(hash.cbData);
1044  msg_data->signerHandles[signerIndex].contentHash, HP_HASHVAL,
1045  hash.pbData, &hash.cbData, 0);
1046  if (ret)
1047  {
1049  NULL, (LPBYTE)&encodedHash.pbData, &encodedHash.cbData);
1050  if (ret)
1051  {
1053  &msg_data->info->rgSignerInfo[signerIndex].AuthAttrs,
1054  &messageDigestAttr);
1055  LocalFree(encodedHash.pbData);
1056  }
1057  }
1058  CryptMemFree(hash.pbData);
1059  }
1060  return ret;
1061 }
1062 
1063 typedef enum {
1066 } SignOrVerify;
1067 
1069  CSignedMsgData *msg_data, SignOrVerify flag)
1070 {
1071  DWORD i;
1072  BOOL ret = TRUE;
1073 
1074  TRACE("(%p)\n", msg_data);
1075 
1076  for (i = 0; ret && i < msg_data->info->cSignerInfo; i++)
1077  {
1078  if (msg_data->info->rgSignerInfo[i].AuthAttrs.cAttr)
1079  {
1080  if (flag == Sign)
1081  {
1082  BYTE oid_rsa_data_encoded[] = { 0x06,0x09,0x2a,0x86,0x48,0x86,
1083  0xf7,0x0d,0x01,0x07,0x01 };
1084  CRYPT_DATA_BLOB content = { sizeof(oid_rsa_data_encoded),
1085  oid_rsa_data_encoded };
1086  char contentType[] = szOID_RSA_contentType;
1087  CRYPT_ATTRIBUTE contentTypeAttr = { contentType, 1, &content };
1088 
1089  /* FIXME: does this depend on inner OID? */
1091  &msg_data->info->rgSignerInfo[i].AuthAttrs, &contentTypeAttr);
1092  if (ret)
1094  i);
1095  }
1096  if (ret)
1097  {
1098  LPBYTE encodedAttrs;
1099  DWORD size;
1100 
1102  &msg_data->info->rgSignerInfo[i].AuthAttrs,
1103  CRYPT_ENCODE_ALLOC_FLAG, NULL, &encodedAttrs, &size);
1104  if (ret)
1105  {
1106  ret = CryptHashData(
1107  msg_data->signerHandles[i].authAttrHash, encodedAttrs,
1108  size, 0);
1109  LocalFree(encodedAttrs);
1110  }
1111  }
1112  }
1113  }
1114  TRACE("returning %d\n", ret);
1115  return ret;
1116 }
1117 
1119 {
1120  DWORD i;
1121  BYTE tmp;
1122 
1123  for (i = 0; i < hash->cbData / 2; i++)
1124  {
1125  tmp = hash->pbData[hash->cbData - i - 1];
1126  hash->pbData[hash->cbData - i - 1] = hash->pbData[i];
1127  hash->pbData[i] = tmp;
1128  }
1129 }
1130 
1132 {
1133  DWORD i;
1134  BOOL ret = TRUE;
1135 
1136  TRACE("(%p)\n", msg_data);
1137 
1138  for (i = 0; ret && i < msg_data->info->cSignerInfo; i++)
1139  {
1140  HCRYPTHASH hash;
1141  DWORD keySpec = msg_data->info->signerKeySpec[i];
1142 
1143  if (!keySpec)
1144  keySpec = AT_SIGNATURE;
1145  if (msg_data->info->rgSignerInfo[i].AuthAttrs.cAttr)
1146  hash = msg_data->signerHandles[i].authAttrHash;
1147  else
1148  hash = msg_data->signerHandles[i].contentHash;
1149  ret = CryptSignHashW(hash, keySpec, NULL, 0, NULL,
1150  &msg_data->info->rgSignerInfo[i].EncryptedHash.cbData);
1151  if (ret)
1152  {
1153  msg_data->info->rgSignerInfo[i].EncryptedHash.pbData =
1154  CryptMemAlloc(
1155  msg_data->info->rgSignerInfo[i].EncryptedHash.cbData);
1156  if (msg_data->info->rgSignerInfo[i].EncryptedHash.pbData)
1157  {
1158  ret = CryptSignHashW(hash, keySpec, NULL, 0,
1159  msg_data->info->rgSignerInfo[i].EncryptedHash.pbData,
1160  &msg_data->info->rgSignerInfo[i].EncryptedHash.cbData);
1161  if (ret)
1163  &msg_data->info->rgSignerInfo[i].EncryptedHash);
1164  }
1165  else
1166  ret = FALSE;
1167  }
1168  }
1169  return ret;
1170 }
1171 
1173  const BYTE *pbData, DWORD cbData, BOOL fFinal, SignOrVerify flag)
1174 {
1175  BOOL ret = CSignedMsgData_UpdateHash(msg_data, pbData, cbData);
1176 
1177  if (ret && fFinal)
1178  {
1180  if (ret && flag == Sign)
1181  ret = CSignedMsgData_Sign(msg_data);
1182  }
1183  return ret;
1184 }
1185 
1186 typedef struct _CSignedEncodeMsg
1187 {
1193 
1194 static void CSignedEncodeMsg_Close(HCRYPTMSG hCryptMsg)
1195 {
1196  CSignedEncodeMsg *msg = hCryptMsg;
1197  DWORD i;
1198 
1199  CryptMemFree(msg->innerOID);
1200  CryptMemFree(msg->data.pbData);
1201  CRYPT_FreeBlobArray(msg->msg_data.info->cCertEncoded,
1202  msg->msg_data.info->rgCertEncoded);
1203  CRYPT_FreeBlobArray(msg->msg_data.info->cCrlEncoded,
1204  msg->msg_data.info->rgCrlEncoded);
1205  for (i = 0; i < msg->msg_data.info->cSignerInfo; i++)
1206  CSignerInfo_Free(&msg->msg_data.info->rgSignerInfo[i]);
1207  CSignedMsgData_CloseHandles(&msg->msg_data);
1208  CryptMemFree(msg->msg_data.info->signerKeySpec);
1209  CryptMemFree(msg->msg_data.info->rgSignerInfo);
1210  CryptMemFree(msg->msg_data.info);
1211 }
1212 
1213 static BOOL CSignedEncodeMsg_GetParam(HCRYPTMSG hCryptMsg, DWORD dwParamType,
1214  DWORD dwIndex, void *pvData, DWORD *pcbData)
1215 {
1216  CSignedEncodeMsg *msg = hCryptMsg;
1217  BOOL ret = FALSE;
1218 
1219  switch (dwParamType)
1220  {
1221  case CMSG_CONTENT_PARAM:
1222  {
1224 
1226  &info.Content.cbData);
1227  if (ret)
1228  {
1229  info.Content.pbData = CryptMemAlloc(info.Content.cbData);
1230  if (info.Content.pbData)
1231  {
1233  info.Content.pbData, &info.Content.cbData);
1234  if (ret)
1235  {
1236  char oid_rsa_signed[] = szOID_RSA_signedData;
1237 
1238  info.pszObjId = oid_rsa_signed;
1241  }
1242  CryptMemFree(info.Content.pbData);
1243  }
1244  else
1245  ret = FALSE;
1246  }
1247  break;
1248  }
1250  {
1252  BOOL freeContent = FALSE;
1253 
1254  info = *msg->msg_data.info;
1255  if (!msg->innerOID || !strcmp(msg->innerOID, szOID_RSA_data))
1256  {
1257  char oid_rsa_data[] = szOID_RSA_data;
1258 
1259  /* Quirk: OID is only encoded messages if an update has happened */
1260  if (msg->base.state != MsgStateInit)
1261  info.content.pszObjId = oid_rsa_data;
1262  else
1263  info.content.pszObjId = NULL;
1264  if (msg->data.cbData)
1265  {
1266  CRYPT_DATA_BLOB blob = { msg->data.cbData, msg->data.pbData };
1267 
1270  &info.content.Content.pbData, &info.content.Content.cbData);
1271  freeContent = TRUE;
1272  }
1273  else
1274  {
1275  info.content.Content.cbData = 0;
1276  info.content.Content.pbData = NULL;
1277  ret = TRUE;
1278  }
1279  }
1280  else
1281  {
1282  info.content.pszObjId = msg->innerOID;
1283  info.content.Content.cbData = msg->data.cbData;
1284  info.content.Content.pbData = msg->data.pbData;
1285  ret = TRUE;
1286  }
1287  if (ret)
1288  {
1290  if (freeContent)
1291  LocalFree(info.content.Content.pbData);
1292  }
1293  break;
1294  }
1296  if (dwIndex >= msg->msg_data.cSignerHandle)
1298  else
1300  msg->msg_data.signerHandles[dwIndex].contentHash, HP_HASHVAL,
1301  pvData, pcbData, 0);
1302  break;
1303  case CMSG_ENCODED_SIGNER:
1304  if (dwIndex >= msg->msg_data.info->cSignerInfo)
1306  else
1308  CMS_SIGNER_INFO, &msg->msg_data.info->rgSignerInfo[dwIndex], 0,
1309  NULL, pvData, pcbData);
1310  break;
1311  case CMSG_VERSION_PARAM:
1312  ret = CRYPT_CopyParam(pvData, pcbData, &msg->msg_data.info->version,
1313  sizeof(msg->msg_data.info->version));
1314  break;
1315  default:
1317  }
1318  return ret;
1319 }
1320 
1322  DWORD cbData, BOOL fFinal)
1323 {
1324  CSignedEncodeMsg *msg = hCryptMsg;
1325  BOOL ret = FALSE;
1326 
1327  if (msg->base.state == MsgStateFinalized)
1329  else if (msg->base.streamed || (msg->base.open_flags & CMSG_DETACHED_FLAG))
1330  {
1331  ret = CSignedMsgData_Update(&msg->msg_data, pbData, cbData, fFinal,
1332  Sign);
1333  if (msg->base.streamed)
1334  FIXME("streamed partial stub\n");
1335  msg->base.state = fFinal ? MsgStateFinalized : MsgStateUpdated;
1336  }
1337  else
1338  {
1339  if (!fFinal)
1341  else
1342  {
1343  if (cbData)
1344  {
1345  msg->data.pbData = CryptMemAlloc(cbData);
1346  if (msg->data.pbData)
1347  {
1348  memcpy(msg->data.pbData, pbData, cbData);
1349  msg->data.cbData = cbData;
1350  ret = TRUE;
1351  }
1352  }
1353  else
1354  ret = TRUE;
1355  if (ret)
1356  ret = CSignedMsgData_Update(&msg->msg_data, pbData, cbData,
1357  fFinal, Sign);
1358  msg->base.state = MsgStateFinalized;
1359  }
1360  }
1361  return ret;
1362 }
1363 
1365  const void *pvMsgEncodeInfo, LPCSTR pszInnerContentObjID,
1366  PCMSG_STREAM_INFO pStreamInfo)
1367 {
1368  const CMSG_SIGNED_ENCODE_INFO_WITH_CMS *info = pvMsgEncodeInfo;
1369  DWORD i;
1371 
1372  if (info->cbSize != sizeof(CMSG_SIGNED_ENCODE_INFO) &&
1373  info->cbSize != sizeof(CMSG_SIGNED_ENCODE_INFO_WITH_CMS))
1374  {
1376  return NULL;
1377  }
1378  if (info->cbSize == sizeof(CMSG_SIGNED_ENCODE_INFO_WITH_CMS) &&
1379  info->cAttrCertEncoded)
1380  {
1381  FIXME("CMSG_SIGNED_ENCODE_INFO with CMS fields unsupported\n");
1382  return NULL;
1383  }
1384  for (i = 0; i < info->cSigners; i++)
1385  if (!CRYPT_IsValidSigner(&info->rgSigners[i]))
1386  return NULL;
1387  msg = CryptMemAlloc(sizeof(CSignedEncodeMsg));
1388  if (msg)
1389  {
1390  BOOL ret = TRUE;
1391 
1392  CryptMsgBase_Init((CryptMsgBase *)msg, dwFlags, pStreamInfo,
1395  if (pszInnerContentObjID)
1396  {
1397  msg->innerOID = CryptMemAlloc(strlen(pszInnerContentObjID) + 1);
1398  if (msg->innerOID)
1399  strcpy(msg->innerOID, pszInnerContentObjID);
1400  else
1401  ret = FALSE;
1402  }
1403  else
1404  msg->innerOID = NULL;
1405  msg->data.cbData = 0;
1406  msg->data.pbData = NULL;
1407  if (ret)
1408  msg->msg_data.info = CryptMemAlloc(sizeof(CRYPT_SIGNED_INFO));
1409  else
1410  msg->msg_data.info = NULL;
1411  if (msg->msg_data.info)
1412  {
1413  memset(msg->msg_data.info, 0, sizeof(CRYPT_SIGNED_INFO));
1414  msg->msg_data.info->version = CMSG_SIGNED_DATA_V1;
1415  }
1416  else
1417  ret = FALSE;
1418  if (ret)
1419  {
1420  if (info->cSigners)
1421  {
1422  msg->msg_data.info->rgSignerInfo =
1423  CryptMemAlloc(info->cSigners * sizeof(CMSG_CMS_SIGNER_INFO));
1424  if (msg->msg_data.info->rgSignerInfo)
1425  {
1426  msg->msg_data.info->cSignerInfo = info->cSigners;
1427  memset(msg->msg_data.info->rgSignerInfo, 0,
1428  msg->msg_data.info->cSignerInfo *
1429  sizeof(CMSG_CMS_SIGNER_INFO));
1430  ret = CSignedMsgData_AllocateHandles(&msg->msg_data);
1431  msg->msg_data.info->signerKeySpec = CryptMemAlloc(info->cSigners * sizeof(DWORD));
1432  if (!msg->msg_data.info->signerKeySpec)
1433  ret = FALSE;
1434  for (i = 0; ret && i < msg->msg_data.info->cSignerInfo; i++)
1435  {
1436  if (info->rgSigners[i].SignerId.dwIdChoice ==
1438  msg->msg_data.info->version = CMSG_SIGNED_DATA_V3;
1440  &msg->msg_data.info->rgSignerInfo[i],
1441  &info->rgSigners[i]);
1442  if (ret)
1443  {
1445  &msg->msg_data, i, &info->rgSigners[i].hCryptProv, &dwFlags);
1447  CryptReleaseContext(info->rgSigners[i].hCryptProv,
1448  0);
1449  }
1450  msg->msg_data.info->signerKeySpec[i] =
1451  info->rgSigners[i].dwKeySpec;
1452  }
1453  }
1454  else
1455  ret = FALSE;
1456  }
1457  else
1458  {
1459  msg->msg_data.info->cSignerInfo = 0;
1460  msg->msg_data.signerHandles = NULL;
1461  msg->msg_data.cSignerHandle = 0;
1462  }
1463  }
1464  if (ret)
1465  ret = CRYPT_ConstructBlobArray(&msg->msg_data.info->cCertEncoded,
1466  &msg->msg_data.info->rgCertEncoded, info->cCertEncoded,
1467  info->rgCertEncoded);
1468  if (ret)
1469  ret = CRYPT_ConstructBlobArray(&msg->msg_data.info->cCrlEncoded,
1470  &msg->msg_data.info->rgCrlEncoded, info->cCrlEncoded,
1471  info->rgCrlEncoded);
1472  if (!ret)
1473  {
1475  CryptMemFree(msg);
1476  msg = NULL;
1477  }
1478  }
1479  return msg;
1480 }
1481 
1483 {
1500 
1501 typedef struct _CEnvelopedEncodeMsg
1502 {
1511 
1514 {
1515  out->pszObjId = CryptMemAlloc(strlen(in->pszObjId) + 1);
1516  if (out->pszObjId)
1517  {
1518  strcpy(out->pszObjId, in->pszObjId);
1519  return CRYPT_ConstructBlob(&out->Parameters, &in->Parameters);
1520  }
1521  else
1522  return FALSE;
1523 }
1524 
1526 {
1527  out->cbData = in->cbData;
1528  out->cUnusedBits = in->cUnusedBits;
1529  if (out->cbData)
1530  {
1531  out->pbData = CryptMemAlloc(out->cbData);
1532  if (out->pbData)
1533  memcpy(out->pbData, in->pbData, out->cbData);
1534  else
1535  return FALSE;
1536  }
1537  else
1538  out->pbData = NULL;
1539  return TRUE;
1540 }
1541 
1543 {
1544  static HCRYPTOIDFUNCSET set = NULL;
1546  HCRYPTOIDFUNCADDR hFunc;
1547  BOOL ret;
1548 
1549  if (!set)
1552  info->ContentEncryptionAlgorithm.pszObjId, 0, (void **)&genKeyFunc, &hFunc);
1553  if (genKeyFunc)
1554  {
1555  ret = genKeyFunc(info, 0, NULL);
1556  CryptFreeOIDFunctionAddress(hFunc, 0);
1557  }
1558  else
1559  ret = CryptGenKey(info->hCryptProv, algID, CRYPT_EXPORTABLE,
1560  &info->hContentEncryptKey);
1561  return ret;
1562 }
1563 
1565  PCMSG_CONTENT_ENCRYPT_INFO pContentEncryptInfo,
1566  PCMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO pKeyTransEncodeInfo,
1567  PCMSG_KEY_TRANS_ENCRYPT_INFO pKeyTransEncryptInfo,
1568  DWORD dwFlags, void *pvReserved)
1569 {
1570  CERT_PUBLIC_KEY_INFO keyInfo;
1571  HCRYPTKEY expKey;
1572  BOOL ret;
1573 
1575  &pKeyTransEncodeInfo->KeyEncryptionAlgorithm);
1576  if (ret)
1578  &pKeyTransEncodeInfo->RecipientPublicKey);
1579 
1580  if (ret)
1581  ret = CryptImportPublicKeyInfo(pKeyTransEncodeInfo->hCryptProv,
1582  X509_ASN_ENCODING, &keyInfo, &expKey);
1583  if (ret)
1584  {
1585  DWORD size;
1586 
1587  ret = CryptExportKey(pContentEncryptInfo->hContentEncryptKey, expKey,
1588  SIMPLEBLOB, 0, NULL, &size);
1589  if (ret)
1590  {
1591  BYTE *keyBlob;
1592 
1593  keyBlob = CryptMemAlloc(size);
1594  if (keyBlob)
1595  {
1596  ret = CryptExportKey(pContentEncryptInfo->hContentEncryptKey,
1597  expKey, SIMPLEBLOB, 0, keyBlob, &size);
1598  if (ret)
1599  {
1600  DWORD head = sizeof(BLOBHEADER) + sizeof(ALG_ID);
1601 
1602  pKeyTransEncryptInfo->EncryptedKey.pbData =
1603  CryptMemAlloc(size - head);
1604  if (pKeyTransEncryptInfo->EncryptedKey.pbData)
1605  {
1606  DWORD i, k = 0;
1607 
1608  pKeyTransEncryptInfo->EncryptedKey.cbData = size - head;
1609  for (i = size - 1; i >= head; --i, ++k)
1610  pKeyTransEncryptInfo->EncryptedKey.pbData[k] =
1611  keyBlob[i];
1612  }
1613  else
1614  ret = FALSE;
1615  }
1616  CryptMemFree(keyBlob);
1617  }
1618  else
1619  ret = FALSE;
1620  }
1621  CryptDestroyKey(expKey);
1622  }
1623 
1624  CryptMemFree(keyInfo.PublicKey.pbData);
1625  CryptMemFree(keyInfo.Algorithm.pszObjId);
1627  return ret;
1628 }
1629 
1632 {
1633  static HCRYPTOIDFUNCSET set = NULL;
1634  PFN_CMSG_EXPORT_KEY_TRANS exportKeyFunc = NULL;
1635  HCRYPTOIDFUNCADDR hFunc = NULL;
1637  info->rgCmsRecipients[i].u.pKeyTrans;
1638  CMSG_KEY_TRANS_ENCRYPT_INFO encryptInfo;
1639  BOOL ret;
1640 
1641  memset(&encryptInfo, 0, sizeof(encryptInfo));
1642  encryptInfo.cbSize = sizeof(encryptInfo);
1643  encryptInfo.dwRecipientIndex = i;
1645  &encodeInfo->KeyEncryptionAlgorithm);
1646 
1647  if (!set)
1650  encryptInfo.KeyEncryptionAlgorithm.pszObjId, 0, (void **)&exportKeyFunc,
1651  &hFunc);
1652  if (!exportKeyFunc)
1653  exportKeyFunc = CRYPT_ExportKeyTrans;
1654  if (ret)
1655  {
1656  ret = exportKeyFunc(info, encodeInfo, &encryptInfo, 0, NULL);
1657  if (ret)
1658  {
1659  key->cbData = encryptInfo.EncryptedKey.cbData;
1660  key->pbData = encryptInfo.EncryptedKey.pbData;
1661  }
1662  }
1663  if (hFunc)
1664  CryptFreeOIDFunctionAddress(hFunc, 0);
1665 
1668  return ret;
1669 }
1670 
1671 static LPVOID WINAPI mem_alloc(size_t size)
1672 {
1673  return HeapAlloc(GetProcessHeap(), 0, size);
1674 }
1675 
1677 {
1678  HeapFree(GetProcessHeap(), 0, pv);
1679 }
1680 
1681 
1684 {
1685  BOOL ret;
1686 
1687  info->cbSize = sizeof(CMSG_CONTENT_ENCRYPT_INFO);
1688  info->hCryptProv = prov;
1689  ret = CRYPT_ConstructAlgorithmId(&info->ContentEncryptionAlgorithm,
1690  &in->ContentEncryptionAlgorithm);
1691  info->pvEncryptionAuxInfo = in->pvEncryptionAuxInfo;
1692  info->cRecipients = in->cRecipients;
1693  if (ret)
1694  {
1695  info->rgCmsRecipients = CryptMemAlloc(in->cRecipients *
1696  sizeof(CMSG_RECIPIENT_ENCODE_INFO));
1697  if (info->rgCmsRecipients)
1698  {
1699  DWORD i;
1700 
1701  for (i = 0; ret && i < in->cRecipients; ++i)
1702  {
1704  CERT_INFO *cert = in->rgpRecipientCert[i];
1705 
1706  info->rgCmsRecipients[i].dwRecipientChoice =
1708  encodeInfo = CryptMemAlloc(sizeof(*encodeInfo));
1709  info->rgCmsRecipients[i].u.pKeyTrans = encodeInfo;
1710  if (encodeInfo)
1711  {
1712  encodeInfo->cbSize = sizeof(*encodeInfo);
1714  &encodeInfo->KeyEncryptionAlgorithm,
1715  &cert->SubjectPublicKeyInfo.Algorithm);
1716  encodeInfo->pvKeyEncryptionAuxInfo = NULL;
1717  encodeInfo->hCryptProv = prov;
1718  if (ret)
1720  &encodeInfo->RecipientPublicKey,
1721  &cert->SubjectPublicKeyInfo.PublicKey);
1722  if (ret)
1724  &encodeInfo->RecipientId.u.IssuerSerialNumber.Issuer,
1725  &cert->Issuer);
1726  if (ret)
1729  &cert->SerialNumber);
1730  }
1731  else
1732  ret = FALSE;
1733  }
1734  }
1735  else
1736  ret = FALSE;
1737  }
1738  info->pfnAlloc = mem_alloc;
1739  info->pfnFree = mem_free;
1740  return ret;
1741 }
1742 
1744 {
1745  CryptMemFree(info->ContentEncryptionAlgorithm.pszObjId);
1746  CryptMemFree(info->ContentEncryptionAlgorithm.Parameters.pbData);
1747  if (info->rgCmsRecipients)
1748  {
1749  DWORD i;
1750 
1751  for (i = 0; i < info->cRecipients; ++i)
1752  {
1754  info->rgCmsRecipients[i].u.pKeyTrans;
1755 
1758  CryptMemFree(encodeInfo->RecipientPublicKey.pbData);
1759  CryptMemFree(
1761  CryptMemFree(
1763  CryptMemFree(encodeInfo);
1764  }
1765  CryptMemFree(info->rgCmsRecipients);
1766  }
1767 }
1768 
1770  const CERT_INFO *cert, CRYPT_DATA_BLOB *key)
1771 {
1772  BOOL ret;
1773 
1775  info->RecipientId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
1776  ret = CRYPT_ConstructBlob(&info->RecipientId.u.IssuerSerialNumber.Issuer,
1777  &cert->Issuer);
1778  if (ret)
1780  &info->RecipientId.u.IssuerSerialNumber.SerialNumber,
1781  &cert->SerialNumber);
1782  if (ret)
1783  ret = CRYPT_ConstructAlgorithmId(&info->KeyEncryptionAlgorithm,
1784  &cert->SubjectPublicKeyInfo.Algorithm);
1785  info->EncryptedKey.cbData = key->cbData;
1786  info->EncryptedKey.pbData = key->pbData;
1787  return ret;
1788 }
1789 
1791 {
1792  CryptMemFree(info->RecipientId.u.IssuerSerialNumber.Issuer.pbData);
1793  CryptMemFree(info->RecipientId.u.IssuerSerialNumber.SerialNumber.pbData);
1794  CryptMemFree(info->KeyEncryptionAlgorithm.pszObjId);
1795  CryptMemFree(info->KeyEncryptionAlgorithm.Parameters.pbData);
1796  CryptMemFree(info->EncryptedKey.pbData);
1797 }
1798 
1799 static void CEnvelopedEncodeMsg_Close(HCRYPTMSG hCryptMsg)
1800 {
1801  CEnvelopedEncodeMsg *msg = hCryptMsg;
1802 
1803  CryptMemFree(msg->algo.pszObjId);
1804  CryptMemFree(msg->algo.Parameters.pbData);
1805  if (msg->base.open_flags & CMSG_CRYPT_RELEASE_CONTEXT_FLAG)
1806  CryptReleaseContext(msg->prov, 0);
1807  CryptDestroyKey(msg->key);
1808  if (msg->recipientInfo)
1809  {
1810  DWORD i;
1811 
1812  for (i = 0; i < msg->cRecipientInfo; ++i)
1813  CRecipientInfo_Free(&msg->recipientInfo[i]);
1814  CryptMemFree(msg->recipientInfo);
1815  }
1816  CryptMemFree(msg->data.pbData);
1817 }
1818 
1819 static BOOL CEnvelopedEncodeMsg_GetParam(HCRYPTMSG hCryptMsg, DWORD dwParamType,
1820  DWORD dwIndex, void *pvData, DWORD *pcbData)
1821 {
1822  CEnvelopedEncodeMsg *msg = hCryptMsg;
1823  BOOL ret = FALSE;
1824 
1825  switch (dwParamType)
1826  {
1828  if (msg->base.streamed)
1830  else
1831  {
1832  char oid_rsa_data[] = szOID_RSA_data;
1833  CRYPT_ENVELOPED_DATA envelopedData = {
1834  CMSG_ENVELOPED_DATA_PKCS_1_5_VERSION, msg->cRecipientInfo,
1835  msg->recipientInfo, { oid_rsa_data, {
1836  msg->algo.pszObjId,
1837  { msg->algo.Parameters.cbData, msg->algo.Parameters.pbData }
1838  },
1839  { msg->data.cbData, msg->data.pbData }
1840  }
1841  };
1842 
1843  ret = CRYPT_AsnEncodePKCSEnvelopedData(&envelopedData, pvData,
1844  pcbData);
1845  }
1846  break;
1847  case CMSG_CONTENT_PARAM:
1848  {
1850 
1852  &info.Content.cbData);
1853  if (ret)
1854  {
1855  info.Content.pbData = CryptMemAlloc(info.Content.cbData);
1856  if (info.Content.pbData)
1857  {
1859  info.Content.pbData, &info.Content.cbData);
1860  if (ret)
1861  {
1862  char oid_rsa_enveloped[] = szOID_RSA_envelopedData;
1863 
1864  info.pszObjId = oid_rsa_enveloped;
1867  }
1868  CryptMemFree(info.Content.pbData);
1869  }
1870  else
1871  ret = FALSE;
1872  }
1873  break;
1874  }
1875  default:
1877  }
1878  return ret;
1879 }
1880 
1882  DWORD cbData, BOOL fFinal)
1883 {
1884  CEnvelopedEncodeMsg *msg = hCryptMsg;
1885  BOOL ret = FALSE;
1886 
1887  if (msg->base.state == MsgStateFinalized)
1889  else if (msg->base.streamed)
1890  {
1891  FIXME("streamed stub\n");
1892  msg->base.state = fFinal ? MsgStateFinalized : MsgStateUpdated;
1893  ret = TRUE;
1894  }
1895  else
1896  {
1897  if (!fFinal)
1898  {
1899  if (msg->base.open_flags & CMSG_DETACHED_FLAG)
1901  else
1903  }
1904  else
1905  {
1906  if (cbData)
1907  {
1908  DWORD dataLen = cbData;
1909 
1910  msg->data.cbData = cbData;
1911  msg->data.pbData = CryptMemAlloc(cbData);
1912  if (msg->data.pbData)
1913  {
1914  memcpy(msg->data.pbData, pbData, cbData);
1915  ret = CryptEncrypt(msg->key, 0, TRUE, 0, msg->data.pbData,
1916  &dataLen, msg->data.cbData);
1917  msg->data.cbData = dataLen;
1918  if (dataLen > cbData)
1919  {
1920  msg->data.pbData = CryptMemRealloc(msg->data.pbData,
1921  dataLen);
1922  if (msg->data.pbData)
1923  {
1924  dataLen = cbData;
1925  ret = CryptEncrypt(msg->key, 0, TRUE, 0,
1926  msg->data.pbData, &dataLen, msg->data.cbData);
1927  }
1928  else
1929  ret = FALSE;
1930  }
1931  if (!ret)
1932  CryptMemFree(msg->data.pbData);
1933  }
1934  else
1935  ret = FALSE;
1936  if (!ret)
1937  {
1938  msg->data.cbData = 0;
1939  msg->data.pbData = NULL;
1940  }
1941  }
1942  else
1943  ret = TRUE;
1944  msg->base.state = MsgStateFinalized;
1945  }
1946  }
1947  return ret;
1948 }
1949 
1951  const void *pvMsgEncodeInfo, LPCSTR pszInnerContentObjID,
1952  PCMSG_STREAM_INFO pStreamInfo)
1953 {
1955  const CMSG_ENVELOPED_ENCODE_INFO_WITH_CMS *info = pvMsgEncodeInfo;
1956  HCRYPTPROV prov;
1957  ALG_ID algID;
1958 
1959  if (info->cbSize != sizeof(CMSG_ENVELOPED_ENCODE_INFO) &&
1960  info->cbSize != sizeof(CMSG_ENVELOPED_ENCODE_INFO_WITH_CMS))
1961  {
1963  return NULL;
1964  }
1965  if (info->cbSize == sizeof(CMSG_ENVELOPED_ENCODE_INFO_WITH_CMS))
1966  FIXME("CMS fields unsupported\n");
1967  if (!(algID = CertOIDToAlgId(info->ContentEncryptionAlgorithm.pszObjId)))
1968  {
1970  return NULL;
1971  }
1972  if (info->cRecipients && !info->rgpRecipientCert)
1973  {
1975  return NULL;
1976  }
1977  if (info->hCryptProv)
1978  prov = info->hCryptProv;
1979  else
1980  {
1981  prov = I_CryptGetDefaultCryptProv(0);
1983  }
1985  if (msg)
1986  {
1987  CRYPT_DATA_BLOB encryptedKey = { 0, NULL };
1988  CMSG_CONTENT_ENCRYPT_INFO encryptInfo;
1989  BOOL ret;
1990  DWORD i;
1991 
1992  CryptMsgBase_Init((CryptMsgBase *)msg, dwFlags, pStreamInfo,
1996  &info->ContentEncryptionAlgorithm);
1997  msg->prov = prov;
1998  msg->data.cbData = 0;
1999  msg->data.pbData = NULL;
2000  msg->cRecipientInfo = info->cRecipients;
2001  msg->recipientInfo = CryptMemAlloc(info->cRecipients *
2003  if (!msg->recipientInfo)
2004  ret = FALSE;
2005  memset(&encryptInfo, 0, sizeof(encryptInfo));
2006  if (ret)
2007  {
2008  ret = CContentEncryptInfo_Construct(&encryptInfo, info, prov);
2009  if (ret)
2010  {
2011  ret = CRYPT_GenKey(&encryptInfo, algID);
2012  if (ret)
2013  msg->key = encryptInfo.hContentEncryptKey;
2014  }
2015  }
2016  for (i = 0; ret && i < msg->cRecipientInfo; ++i)
2017  {
2018  ret = CRYPT_ExportEncryptedKey(&encryptInfo, i, &encryptedKey);
2019  if (ret)
2020  ret = CRecipientInfo_Construct(&msg->recipientInfo[i],
2021  info->rgpRecipientCert[i], &encryptedKey);
2022  }
2023  CContentEncryptInfo_Free(&encryptInfo);
2024  if (!ret)
2025  {
2026  CryptMsgClose(msg);
2027  msg = NULL;
2028  }
2029  }
2031  CryptReleaseContext(prov, 0);
2032  return msg;
2033 }
2034 
2036  DWORD dwMsgType, const void *pvMsgEncodeInfo, LPSTR pszInnerContentObjID,
2037  PCMSG_STREAM_INFO pStreamInfo)
2038 {
2039  HCRYPTMSG msg = NULL;
2040 
2041  TRACE("(%08x, %08x, %08x, %p, %s, %p)\n", dwMsgEncodingType, dwFlags,
2042  dwMsgType, pvMsgEncodeInfo, debugstr_a(pszInnerContentObjID), pStreamInfo);
2043 
2044  if (GET_CMSG_ENCODING_TYPE(dwMsgEncodingType) != PKCS_7_ASN_ENCODING)
2045  {
2047  return NULL;
2048  }
2049  switch (dwMsgType)
2050  {
2051  case CMSG_DATA:
2052  msg = CDataEncodeMsg_Open(dwFlags, pvMsgEncodeInfo,
2053  pszInnerContentObjID, pStreamInfo);
2054  break;
2055  case CMSG_HASHED:
2056  msg = CHashEncodeMsg_Open(dwFlags, pvMsgEncodeInfo,
2057  pszInnerContentObjID, pStreamInfo);
2058  break;
2059  case CMSG_SIGNED:
2060  msg = CSignedEncodeMsg_Open(dwFlags, pvMsgEncodeInfo,
2061  pszInnerContentObjID, pStreamInfo);
2062  break;
2063  case CMSG_ENVELOPED:
2064  msg = CEnvelopedEncodeMsg_Open(dwFlags, pvMsgEncodeInfo,
2065  pszInnerContentObjID, pStreamInfo);
2066  break;
2068  case CMSG_ENCRYPTED:
2069  /* defined but invalid, fall through */
2070  default:
2072  }
2073  return msg;
2074 }
2075 
2076 typedef struct _CEnvelopedDecodeMsg
2077 {
2083 
2084 typedef struct _CDecodeMsg
2085 {
2089  union {
2093  } u;
2097 } CDecodeMsg;
2098 
2099 static void CDecodeMsg_Close(HCRYPTMSG hCryptMsg)
2100 {
2101  CDecodeMsg *msg = hCryptMsg;
2102 
2103  if (msg->crypt_prov && msg->base.open_flags & CMSG_CRYPT_RELEASE_CONTEXT_FLAG)
2104  CryptReleaseContext(msg->crypt_prov, 0);
2105  switch (msg->type)
2106  {
2107  case CMSG_HASHED:
2108  if (msg->u.hash)
2109  CryptDestroyHash(msg->u.hash);
2110  break;
2111  case CMSG_ENVELOPED:
2112  if (msg->u.enveloped_data.crypt_prov)
2113  CryptReleaseContext(msg->u.enveloped_data.crypt_prov, 0);
2114  LocalFree(msg->u.enveloped_data.data);
2115  CryptMemFree(msg->u.enveloped_data.content.pbData);
2116  break;
2117  case CMSG_SIGNED:
2118  if (msg->u.signed_data.info)
2119  {
2120  LocalFree(msg->u.signed_data.info);
2121  CSignedMsgData_CloseHandles(&msg->u.signed_data);
2122  }
2123  break;
2124  }
2125  CryptMemFree(msg->msg_data.pbData);
2126  CryptMemFree(msg->detached_data.pbData);
2127  ContextPropertyList_Free(msg->properties);
2128 }
2129 
2131  DWORD cbData)
2132 {
2133  BOOL ret = TRUE;
2134 
2135  if (cbData)
2136  {
2137  if (blob->cbData)
2138  blob->pbData = CryptMemRealloc(blob->pbData,
2139  blob->cbData + cbData);
2140  else
2141  blob->pbData = CryptMemAlloc(cbData);
2142  if (blob->pbData)
2143  {
2144  memcpy(blob->pbData + blob->cbData, pbData, cbData);
2145  blob->cbData += cbData;
2146  }
2147  else
2148  ret = FALSE;
2149  }
2150  return ret;
2151 }
2152 
2154 {
2155  BOOL ret;
2157  DWORD size;
2158 
2160  blob->pbData, blob->cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, &data, &size);
2161  if (ret)
2162  {
2163  ret = ContextPropertyList_SetProperty(msg->properties,
2164  CMSG_CONTENT_PARAM, data->pbData, data->cbData);
2165  LocalFree(data);
2166  }
2167  return ret;
2168 }
2169 
2171  const CRYPT_ALGORITHM_IDENTIFIER *id)
2172 {
2173  static const BYTE nullParams[] = { ASN_NULL, 0 };
2176 
2177  /* Linearize algorithm id */
2178  len += strlen(id->pszObjId) + 1;
2179  len += id->Parameters.cbData;
2180  copy = CryptMemAlloc(len);
2181  if (copy)
2182  {
2183  copy->pszObjId =
2184  (LPSTR)((BYTE *)copy + sizeof(CRYPT_ALGORITHM_IDENTIFIER));
2185  strcpy(copy->pszObjId, id->pszObjId);
2186  copy->Parameters.pbData = (BYTE *)copy->pszObjId + strlen(id->pszObjId)
2187  + 1;
2188  /* Trick: omit NULL parameters */
2189  if (id->Parameters.cbData == sizeof(nullParams) &&
2190  !memcmp(id->Parameters.pbData, nullParams, sizeof(nullParams)))
2191  {
2192  copy->Parameters.cbData = 0;
2193  len -= sizeof(nullParams);
2194  }
2195  else
2196  copy->Parameters.cbData = id->Parameters.cbData;
2197  if (copy->Parameters.cbData)
2198  memcpy(copy->Parameters.pbData, id->Parameters.pbData,
2199  id->Parameters.cbData);
2201  len);
2202  CryptMemFree(copy);
2203  }
2204 }
2205 
2207 {
2208  id->pszObjId = (LPSTR)((BYTE *)id + sizeof(CRYPT_ALGORITHM_IDENTIFIER));
2209  id->Parameters.pbData = (BYTE *)id->pszObjId + strlen(id->pszObjId) + 1;
2210 }
2211 
2213  const CRYPT_DER_BLOB *blob)
2214 {
2215  BOOL ret;
2216  CRYPT_DIGESTED_DATA *digestedData;
2217  DWORD size;
2218 
2219  ret = CRYPT_AsnDecodePKCSDigestedData(blob->pbData, blob->cbData,
2221  &size);
2222  if (ret)
2223  {
2225  (const BYTE *)&digestedData->version, sizeof(digestedData->version));
2227  &digestedData->DigestAlgorithm);
2230  (const BYTE *)digestedData->ContentInfo.pszObjId,
2231  digestedData->ContentInfo.pszObjId ?
2232  strlen(digestedData->ContentInfo.pszObjId) + 1 : 0);
2233  if (!(msg->base.open_flags & CMSG_DETACHED_FLAG))
2234  {
2235  if (digestedData->ContentInfo.Content.cbData)
2237  &digestedData->ContentInfo.Content);
2238  else
2240  CMSG_CONTENT_PARAM, NULL, 0);
2241  }
2243  digestedData->hash.pbData, digestedData->hash.cbData);
2244  LocalFree(digestedData);
2245  }
2246  return ret;
2247 }
2248 
2250  const CRYPT_DER_BLOB *blob)
2251 {
2252  BOOL ret;
2253  CRYPT_ENVELOPED_DATA *envelopedData;
2254  DWORD size;
2255 
2256  ret = CRYPT_AsnDecodePKCSEnvelopedData(blob->pbData, blob->cbData,
2258  &size);
2259  if (ret)
2260  msg->u.enveloped_data.data = envelopedData;
2261  return ret;
2262 }
2263 
2265  const CRYPT_DER_BLOB *blob)
2266 {
2267  BOOL ret;
2268  CRYPT_SIGNED_INFO *signedInfo;
2269  DWORD size;
2270 
2271  ret = CRYPT_AsnDecodeCMSSignedInfo(blob->pbData, blob->cbData,
2273  &size);
2274  if (ret)
2275  msg->u.signed_data.info = signedInfo;
2276  return ret;
2277 }
2278 
2279 /* Decodes the content in blob as the type given, and updates the value
2280  * (type, parameters, etc.) of msg based on what blob contains.
2281  * It doesn't just use msg's type, to allow a recursive call from an implicitly
2282  * typed message once the outer content info has been decoded.
2283  */
2285  DWORD type)
2286 {
2287  BOOL ret;
2288 
2289  switch (type)
2290  {
2291  case CMSG_DATA:
2293  msg->type = CMSG_DATA;
2294  break;
2295  case CMSG_HASHED:
2297  msg->type = CMSG_HASHED;
2298  break;
2299  case CMSG_ENVELOPED:
2301  msg->type = CMSG_ENVELOPED;
2302  break;
2303  case CMSG_SIGNED:
2305  msg->type = CMSG_SIGNED;
2306  break;
2307  default:
2308  {
2310  DWORD size;
2311 
2313  msg->msg_data.pbData, msg->msg_data.cbData, CRYPT_DECODE_ALLOC_FLAG,
2314  NULL, &info, &size);
2315  if (ret)
2316  {
2317  if (!strcmp(info->pszObjId, szOID_RSA_data))
2319  else if (!strcmp(info->pszObjId, szOID_RSA_digestedData))
2320  ret = CDecodeMsg_DecodeContent(msg, &info->Content,
2321  CMSG_HASHED);
2322  else if (!strcmp(info->pszObjId, szOID_RSA_envelopedData))
2323  ret = CDecodeMsg_DecodeContent(msg, &info->Content,
2324  CMSG_ENVELOPED);
2325  else if (!strcmp(info->pszObjId, szOID_RSA_signedData))
2326  ret = CDecodeMsg_DecodeContent(msg, &info->Content,
2327  CMSG_SIGNED);
2328  else
2329  {
2331  ret = FALSE;
2332  }
2333  LocalFree(info);
2334  }
2335  }
2336  }
2337  return ret;
2338 }
2339 
2342 {
2343  CRYPT_ALGORITHM_IDENTIFIER *hashAlgoID = NULL;
2344  DWORD size = 0;
2345  ALG_ID algID = 0;
2346  BOOL ret;
2347 
2349  hashAlgoID = CryptMemAlloc(size);
2351  &size);
2352  if (ret)
2353  algID = CertOIDToAlgId(hashAlgoID->pszObjId);
2354 
2355  if (!msg->crypt_prov)
2356  {
2357  msg->crypt_prov = I_CryptGetDefaultCryptProv(algID);
2358  if (msg->crypt_prov)
2359  msg->base.open_flags &= ~CMSG_CRYPT_RELEASE_CONTEXT_FLAG;
2360  }
2361 
2362  ret = CryptCreateHash(msg->crypt_prov, algID, 0, 0, &msg->u.hash);
2363  if (ret)
2364  {
2366 
2367  if (msg->base.open_flags & CMSG_DETACHED_FLAG)
2368  {
2369  /* Unlike for non-detached messages, the data were never stored as
2370  * the content param, but were saved in msg->detached_data instead.
2371  */
2372  content.pbData = msg->detached_data.pbData;
2373  content.cbData = msg->detached_data.cbData;
2374  }
2375  else
2378  if (ret)
2379  ret = CryptHashData(msg->u.hash, content.pbData, content.cbData, 0);
2380  }
2381  CryptMemFree(hashAlgoID);
2382  return ret;
2383 }
2384 
2387 {
2389 
2390  if (msg->base.open_flags & CMSG_DETACHED_FLAG)
2391  content = &msg->detached_data;
2392  else
2393  content =
2394  &msg->u.enveloped_data.data->encryptedContentInfo.encryptedContent;
2395 
2396  return CRYPT_ConstructBlob(&msg->u.enveloped_data.content, content);
2397 }
2398 
2401 {
2402  BOOL ret;
2403  DWORD i, size;
2404 
2405  ret = CSignedMsgData_AllocateHandles(&msg->u.signed_data);
2406  for (i = 0; ret && i < msg->u.signed_data.info->cSignerInfo; i++)
2407  ret = CSignedMsgData_ConstructSignerHandles(&msg->u.signed_data, i,
2408  &msg->crypt_prov, &msg->base.open_flags);
2409  if (ret)
2410  {
2412 
2413  /* Now that we have all the content, update the hash handles with
2414  * it. If the message is a detached message, the content is stored
2415  * in msg->detached_data rather than in the signed message's
2416  * content.
2417  */
2418  if (msg->base.open_flags & CMSG_DETACHED_FLAG)
2419  content = &msg->detached_data;
2420  else
2421  content = &msg->u.signed_data.info->content.Content;
2422  if (content->cbData)
2423  {
2424  /* If the message is not detached, have to decode the message's
2425  * content if the type is szOID_RSA_data.
2426  */
2427  if (!(msg->base.open_flags & CMSG_DETACHED_FLAG) &&
2428  !strcmp(msg->u.signed_data.info->content.pszObjId,
2429  szOID_RSA_data))
2430  {
2431  CRYPT_DATA_BLOB *rsa_blob;
2432 
2434  X509_OCTET_STRING, content->pbData, content->cbData,
2435  CRYPT_DECODE_ALLOC_FLAG, NULL, &rsa_blob, &size);
2436  if (ret)
2437  {
2438  ret = CSignedMsgData_Update(&msg->u.signed_data,
2439  rsa_blob->pbData, rsa_blob->cbData, TRUE, Verify);
2440  LocalFree(rsa_blob);
2441  }
2442  }
2443  else
2444  ret = CSignedMsgData_Update(&msg->u.signed_data,
2445  content->pbData, content->cbData, TRUE, Verify);
2446  }
2447  }
2448  return ret;
2449 }
2450 
2452 {
2453  BOOL ret = FALSE;
2454 
2455  switch (msg->type)
2456  {
2457  case CMSG_HASHED:
2459  break;
2460  case CMSG_ENVELOPED:
2462  break;
2463  case CMSG_SIGNED:
2465  break;
2466  default:
2467  ret = TRUE;
2468  }
2469  return ret;
2470 }
2471 
2472 static BOOL CDecodeMsg_Update(HCRYPTMSG hCryptMsg, const BYTE *pbData,
2473  DWORD cbData, BOOL fFinal)
2474 {
2475  CDecodeMsg *msg = hCryptMsg;
2476  BOOL ret = FALSE;
2477 
2478  TRACE("(%p, %p, %d, %d)\n", hCryptMsg, pbData, cbData, fFinal);
2479 
2480  if (msg->base.state == MsgStateFinalized)
2482  else if (msg->base.streamed)
2483  {
2484  FIXME("(%p, %p, %d, %d): streamed update stub\n", hCryptMsg, pbData,
2485  cbData, fFinal);
2486  switch (msg->base.state)
2487  {
2488  case MsgStateInit:
2489  ret = CDecodeMsg_CopyData(&msg->msg_data, pbData, cbData);
2490  if (fFinal)
2491  {
2492  if (msg->base.open_flags & CMSG_DETACHED_FLAG)
2493  msg->base.state = MsgStateDataFinalized;
2494  else
2495  msg->base.state = MsgStateFinalized;
2496  }
2497  else
2498  msg->base.state = MsgStateUpdated;
2499  break;
2500  case MsgStateUpdated:
2501  ret = CDecodeMsg_CopyData(&msg->msg_data, pbData, cbData);
2502  if (fFinal)
2503  {
2504  if (msg->base.open_flags & CMSG_DETACHED_FLAG)
2505  msg->base.state = MsgStateDataFinalized;
2506  else
2507  msg->base.state = MsgStateFinalized;
2508  }
2509  break;
2510  case MsgStateDataFinalized:
2511  ret = CDecodeMsg_CopyData(&msg->detached_data, pbData, cbData);
2512  if (fFinal)
2513  msg->base.state = MsgStateFinalized;
2514  break;
2515  default:
2517  break;
2518  }
2519  }
2520  else
2521  {
2522  if (!fFinal)
2524  else
2525  {
2526  switch (msg->base.state)
2527  {
2528  case MsgStateInit:
2529  ret = CDecodeMsg_CopyData(&msg->msg_data, pbData, cbData);
2530  if (msg->base.open_flags & CMSG_DETACHED_FLAG)
2531  msg->base.state = MsgStateDataFinalized;
2532  else
2533  msg->base.state = MsgStateFinalized;
2534  break;
2535  case MsgStateDataFinalized:
2536  ret = CDecodeMsg_CopyData(&msg->detached_data, pbData, cbData);
2537  msg->base.state = MsgStateFinalized;
2538  break;
2539  default:
2541  }
2542  }
2543  }
2544  if (ret && fFinal &&
2545  ((msg->base.open_flags & CMSG_DETACHED_FLAG && msg->base.state ==
2547  (!(msg->base.open_flags & CMSG_DETACHED_FLAG) && msg->base.state ==
2549  ret = CDecodeMsg_DecodeContent(msg, &msg->msg_data, msg->type);
2550  if (ret && msg->base.state == MsgStateFinalized)
2551  ret = CDecodeMsg_FinalizeContent(msg, &msg->msg_data);
2552  return ret;
2553 }
2554 
2556  DWORD dwIndex, void *pvData, DWORD *pcbData)
2557 {
2558  BOOL ret = FALSE;
2559 
2560  switch (dwParamType)
2561  {
2562  case CMSG_TYPE_PARAM:
2563  ret = CRYPT_CopyParam(pvData, pcbData, &msg->type, sizeof(msg->type));
2564  break;
2566  {
2568 
2569  ret = ContextPropertyList_FindProperty(msg->properties, dwParamType,
2570  &blob);
2571  if (ret)
2572  {
2573  ret = CRYPT_CopyParam(pvData, pcbData, blob.pbData, blob.cbData);
2574  if (ret && pvData)
2576  }
2577  else
2579  break;
2580  }
2582  ret = CryptGetHashParam(msg->u.hash, HP_HASHVAL, pvData, pcbData, 0);
2583  break;
2584  default:
2585  {
2587 
2588  ret = ContextPropertyList_FindProperty(msg->properties, dwParamType,
2589  &blob);
2590  if (ret)
2591  ret = CRYPT_CopyParam(pvData, pcbData, blob.pbData, blob.cbData);
2592  else
2594  }
2595  }
2596  return ret;
2597 }
2598 
2599 /* nextData is an in/out parameter - on input it's the memory location in
2600  * which a copy of in's data should be made, and on output it's the memory
2601  * location immediately after out's copy of in's data.
2602  */
2603 static inline void CRYPT_CopyBlob(CRYPT_DATA_BLOB *out,
2604  const CRYPT_DATA_BLOB *in, LPBYTE *nextData)
2605 {
2606  out->cbData = in->cbData;
2607  if (in->cbData)
2608  {
2609  out->pbData = *nextData;
2610  memcpy(out->pbData, in->pbData, in->cbData);
2611  *nextData += in->cbData;
2612  }
2613 }
2614 
2616  const CRYPT_ALGORITHM_IDENTIFIER *in, LPBYTE *nextData)
2617 {
2618  if (in->pszObjId)
2619  {
2620  out->pszObjId = (LPSTR)*nextData;
2621  strcpy(out->pszObjId, in->pszObjId);
2622  *nextData += strlen(out->pszObjId) + 1;
2623  }
2624  CRYPT_CopyBlob(&out->Parameters, &in->Parameters, nextData);
2625 }
2626 
2628  const CRYPT_ATTRIBUTES *in, LPBYTE *nextData)
2629 {
2630  out->cAttr = in->cAttr;
2631  if (in->cAttr)
2632  {
2633  DWORD i;
2634 
2635  *nextData = POINTER_ALIGN_DWORD_PTR(*nextData);
2636  out->rgAttr = (CRYPT_ATTRIBUTE *)*nextData;
2637  *nextData += in->cAttr * sizeof(CRYPT_ATTRIBUTE);
2638  for (i = 0; i < in->cAttr; i++)
2639  {
2640  if (in->rgAttr[i].pszObjId)
2641  {
2642  out->rgAttr[i].pszObjId = (LPSTR)*nextData;
2643  strcpy(out->rgAttr[i].pszObjId, in->rgAttr[i].pszObjId);
2644  *nextData += strlen(in->rgAttr[i].pszObjId) + 1;
2645  }
2646  if (in->rgAttr[i].cValue)
2647  {
2648  DWORD j;
2649 
2650  out->rgAttr[i].cValue = in->rgAttr[i].cValue;
2651  *nextData = POINTER_ALIGN_DWORD_PTR(*nextData);
2652  out->rgAttr[i].rgValue = (PCRYPT_DATA_BLOB)*nextData;
2653  *nextData += in->rgAttr[i].cValue * sizeof(CRYPT_DATA_BLOB);
2654  for (j = 0; j < in->rgAttr[i].cValue; j++)
2655  CRYPT_CopyBlob(&out->rgAttr[i].rgValue[j],
2656  &in->rgAttr[i].rgValue[j], nextData);
2657  }
2658  }
2659  }
2660 }
2661 
2663 {
2664  DWORD size = attr->cAttr * sizeof(CRYPT_ATTRIBUTE), i, j;
2665 
2666  for (i = 0; i < attr->cAttr; i++)
2667  {
2668  if (attr->rgAttr[i].pszObjId)
2669  size += strlen(attr->rgAttr[i].pszObjId) + 1;
2670  /* align pointer */
2672  size += attr->rgAttr[i].cValue * sizeof(CRYPT_DATA_BLOB);
2673  for (j = 0; j < attr->rgAttr[i].cValue; j++)
2674  size += attr->rgAttr[i].rgValue[j].cbData;
2675  }
2676  /* align pointer again to be conservative */
2678  return size;
2679 }
2680 
2682 {
2683  static char oid_key_rdn[] = szOID_KEYID_RDN;
2684  DWORD size = 0;
2686  CERT_RDN rdn = { 1, &attr };
2687  CERT_NAME_INFO name = { 1, &rdn };
2688 
2689  attr.pszObjId = oid_key_rdn;
2690  attr.dwValueType = CERT_RDN_OCTET_STRING;
2691  attr.Value.cbData = keyId->cbData;
2692  attr.Value.pbData = keyId->pbData;
2694  size++; /* Only include size of special zero serial number on success */
2695  return size;
2696 }
2697 
2700  LPBYTE *nextData)
2701 {
2702  static char oid_key_rdn[] = szOID_KEYID_RDN;
2704  CERT_RDN rdn = { 1, &attr };
2705  CERT_NAME_INFO name = { 1, &rdn };
2706  BOOL ret;
2707 
2708  /* Encode special zero serial number */
2709  serialNumber->cbData = 1;
2710  serialNumber->pbData = *nextData;
2711  **nextData = 0;
2712  (*nextData)++;
2713  /* Encode issuer */
2714  issuer->pbData = *nextData;
2715  attr.pszObjId = oid_key_rdn;
2716  attr.dwValueType = CERT_RDN_OCTET_STRING;
2717  attr.Value.cbData = keyId->cbData;
2718  attr.Value.pbData = keyId->pbData;
2720  &encodedLen);
2721  if (ret)
2722  {
2723  *nextData += encodedLen;
2724  issuer->cbData = encodedLen;
2725  }
2726  return ret;
2727 }
2728 
2730  const CMSG_CMS_SIGNER_INFO *in)
2731 {
2732  DWORD size = sizeof(CMSG_SIGNER_INFO), rdnSize = 0;
2733  BOOL ret;
2734 
2735  TRACE("(%p, %d, %p)\n", pvData, pvData ? *pcbData : 0, in);
2736 
2737  if (in->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER)
2738  {
2739  size += in->SignerId.u.IssuerSerialNumber.Issuer.cbData;
2740  size += in->SignerId.u.IssuerSerialNumber.SerialNumber.cbData;
2741  }
2742  else
2743  {
2744  rdnSize = CRYPT_SizeOfKeyIdAsIssuerAndSerial(&in->SignerId.u.KeyId);
2745  size += rdnSize;
2746  }
2747  if (in->HashAlgorithm.pszObjId)
2748  size += strlen(in->HashAlgorithm.pszObjId) + 1;
2749  size += in->HashAlgorithm.Parameters.cbData;
2750  if (in->HashEncryptionAlgorithm.pszObjId)
2751  size += strlen(in->HashEncryptionAlgorithm.pszObjId) + 1;
2752  size += in->HashEncryptionAlgorithm.Parameters.cbData;
2753  size += in->EncryptedHash.cbData;
2754  /* align pointer */
2756  size += CRYPT_SizeOfAttributes(&in->AuthAttrs);
2757  size += CRYPT_SizeOfAttributes(&in->UnauthAttrs);
2758  if (!pvData)
2759  {
2760  ret = TRUE;
2761  }
2762  else if (*pcbData < size)
2763  {
2765  ret = FALSE;
2766  }
2767  else
2768  {
2769  LPBYTE nextData = (BYTE *)pvData + sizeof(CMSG_SIGNER_INFO);
2771 
2772  ret = TRUE;
2773  out->dwVersion = in->dwVersion;
2774  if (in->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER)
2775  {
2776  CRYPT_CopyBlob(&out->Issuer,
2777  &in->SignerId.u.IssuerSerialNumber.Issuer, &nextData);
2778  CRYPT_CopyBlob(&out->SerialNumber,
2779  &in->SignerId.u.IssuerSerialNumber.SerialNumber, &nextData);
2780  }
2781  else
2782  ret = CRYPT_CopyKeyIdAsIssuerAndSerial(&out->Issuer, &out->SerialNumber,
2783  &in->SignerId.u.KeyId, rdnSize, &nextData);
2784  if (ret)
2785  {
2786  CRYPT_CopyAlgorithmId(&out->HashAlgorithm, &in->HashAlgorithm,
2787  &nextData);
2788  CRYPT_CopyAlgorithmId(&out->HashEncryptionAlgorithm,
2789  &in->HashEncryptionAlgorithm, &nextData);
2790  CRYPT_CopyBlob(&out->EncryptedHash, &in->EncryptedHash, &nextData);
2791  nextData = POINTER_ALIGN_DWORD_PTR(nextData);
2792  CRYPT_CopyAttributes(&out->AuthAttrs, &in->AuthAttrs, &nextData);
2793  CRYPT_CopyAttributes(&out->UnauthAttrs, &in->UnauthAttrs, &nextData);
2794  }
2795  }
2796  *pcbData = size;
2797  TRACE("returning %d\n", ret);
2798  return ret;
2799 }
2800 
2802  const CMSG_CMS_SIGNER_INFO *in)
2803 {
2804  DWORD size = sizeof(CMSG_CMS_SIGNER_INFO);
2805  BOOL ret;
2806 
2807  TRACE("(%p, %d, %p)\n", pvData, pvData ? *pcbData : 0, in);
2808 
2809  if (in->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER)
2810  {
2811  size += in->SignerId.u.IssuerSerialNumber.Issuer.cbData;
2812  size += in->SignerId.u.IssuerSerialNumber.SerialNumber.cbData;
2813  }
2814  else
2815  size += in->SignerId.u.KeyId.cbData;
2816  if (in->HashAlgorithm.pszObjId)
2817  size += strlen(in->HashAlgorithm.pszObjId) + 1;
2818  size += in->HashAlgorithm.Parameters.cbData;
2819  if (in->HashEncryptionAlgorithm.pszObjId)
2820  size += strlen(in->HashEncryptionAlgorithm.pszObjId) + 1;
2821  size += in->HashEncryptionAlgorithm.Parameters.cbData;
2822  size += in->EncryptedHash.cbData;
2823  /* align pointer */
2825  size += CRYPT_SizeOfAttributes(&in->AuthAttrs);
2826  size += CRYPT_SizeOfAttributes(&in->UnauthAttrs);
2827  if (!pvData)
2828  {
2829  *pcbData = size;
2830  ret = TRUE;
2831  }
2832  else if (*pcbData < size)
2833  {
2834  *pcbData = size;
2836  ret = FALSE;
2837  }
2838  else
2839  {
2840  LPBYTE nextData = (BYTE *)pvData + sizeof(CMSG_CMS_SIGNER_INFO);
2842 
2843  out->dwVersion = in->dwVersion;
2844  out->SignerId.dwIdChoice = in->SignerId.dwIdChoice;
2845  if (in->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER)
2846  {
2847  CRYPT_CopyBlob(&out->SignerId.u.IssuerSerialNumber.Issuer,
2848  &in->SignerId.u.IssuerSerialNumber.Issuer, &nextData);
2849  CRYPT_CopyBlob(&out->SignerId.u.IssuerSerialNumber.SerialNumber,
2850  &in->SignerId.u.IssuerSerialNumber.SerialNumber, &nextData);
2851  }
2852  else
2853  CRYPT_CopyBlob(&out->SignerId.u.KeyId, &in->SignerId.u.KeyId, &nextData);
2854  CRYPT_CopyAlgorithmId(&out->HashAlgorithm, &in->HashAlgorithm,
2855  &nextData);
2856  CRYPT_CopyAlgorithmId(&out->HashEncryptionAlgorithm,
2857  &in->HashEncryptionAlgorithm, &nextData);
2858  CRYPT_CopyBlob(&out->EncryptedHash, &in->EncryptedHash, &nextData);
2859  nextData = POINTER_ALIGN_DWORD_PTR(nextData);
2860  CRYPT_CopyAttributes(&out->AuthAttrs, &in->AuthAttrs, &nextData);
2861  CRYPT_CopyAttributes(&out->UnauthAttrs, &in->UnauthAttrs, &nextData);
2862  ret = TRUE;
2863  }
2864  TRACE("returning %d\n", ret);
2865  return ret;
2866 }
2867 
2869  const CMSG_CMS_SIGNER_INFO *in)
2870 {
2871  DWORD size = sizeof(CERT_INFO), rdnSize = 0;
2872  BOOL ret;
2873 
2874  TRACE("(%p, %d, %p)\n", pvData, pvData ? *pcbData : 0, in);
2875 
2876  if (in->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER)
2877  {
2878  size += in->SignerId.u.IssuerSerialNumber.Issuer.cbData;
2879  size += in->SignerId.u.IssuerSerialNumber.SerialNumber.cbData;
2880  }
2881  else
2882  {
2883  rdnSize = CRYPT_SizeOfKeyIdAsIssuerAndSerial(&in->SignerId.u.KeyId);
2884  size += rdnSize;
2885  }
2886  if (!pvData)
2887  {
2888  *pcbData = size;
2889  ret = TRUE;
2890  }
2891  else if (*pcbData < size)
2892  {
2893  *pcbData = size;
2895  ret = FALSE;
2896  }
2897  else
2898  {
2899  LPBYTE nextData = (BYTE *)pvData + sizeof(CERT_INFO);
2900  CERT_INFO *out = pvData;
2901 
2902  memset(out, 0, sizeof(CERT_INFO));
2903  if (in->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER)
2904  {
2905  CRYPT_CopyBlob(&out->Issuer,
2906  &in->SignerId.u.IssuerSerialNumber.Issuer, &nextData);
2907  CRYPT_CopyBlob(&out->SerialNumber,
2908  &in->SignerId.u.IssuerSerialNumber.SerialNumber, &nextData);
2909  ret = TRUE;
2910  }
2911  else
2912  ret = CRYPT_CopyKeyIdAsIssuerAndSerial(&out->Issuer, &out->SerialNumber,
2913  &in->SignerId.u.KeyId, rdnSize, &nextData);
2914  }
2915  TRACE("returning %d\n", ret);
2916  return ret;
2917 }
2918 
2921 {
2922  DWORD size = sizeof(CERT_INFO);
2923  BOOL ret;
2924 
2925  TRACE("(%p, %d, %p)\n", pvData, pvData ? *pcbData : 0, in);
2926 
2927  size += in->SerialNumber.cbData;
2928  size += in->Issuer.cbData;
2929  if (!pvData)
2930  {
2931  *pcbData = size;
2932  ret = TRUE;
2933  }
2934  else if (*pcbData < size)
2935  {
2936  *pcbData = size;
2938  ret = FALSE;
2939  }
2940  else
2941  {
2942  LPBYTE nextData = (BYTE *)pvData + sizeof(CERT_INFO);
2943  CERT_INFO *out = pvData;
2944 
2945  CRYPT_CopyBlob(&out->SerialNumber, &in->SerialNumber, &nextData);
2946  CRYPT_CopyBlob(&out->Issuer, &in->Issuer, &nextData);
2947  ret = TRUE;
2948  }
2949  TRACE("returning %d\n", ret);
2950  return ret;
2951 }
2952 
2954  DWORD dwIndex, void *pvData, DWORD *pcbData)
2955 {
2956  BOOL ret = FALSE;
2957 
2958  switch (dwParamType)
2959  {
2960  case CMSG_TYPE_PARAM:
2961  ret = CRYPT_CopyParam(pvData, pcbData, &msg->type, sizeof(msg->type));
2962  break;
2963  case CMSG_CONTENT_PARAM:
2964  if (msg->u.enveloped_data.data)
2966  msg->u.enveloped_data.content.pbData,
2967  msg->u.enveloped_data.content.cbData);
2968  else
2970  break;
2972  if (msg->u.enveloped_data.data)
2974  &msg->u.enveloped_data.data->cRecipientInfo, sizeof(DWORD));
2975  else
2977  break;
2979  if (msg->u.enveloped_data.data)
2980  {
2981  if (dwIndex < msg->u.enveloped_data.data->cRecipientInfo)
2982  {
2983  PCMSG_KEY_TRANS_RECIPIENT_INFO recipientInfo =
2984  &msg->u.enveloped_data.data->rgRecipientInfo[dwIndex];
2985 
2987  &recipientInfo->RecipientId.u.IssuerSerialNumber);
2988  }
2989  else
2991  }
2992  else
2994  break;
2995  default:
2996  FIXME("unimplemented for %d\n", dwParamType);
2998  }
2999  return ret;
3000 }
3001 
3003  DWORD dwIndex, void *pvData, DWORD *pcbData)
3004 {
3005  BOOL ret = FALSE;
3006 
3007  switch (dwParamType)
3008  {
3009  case CMSG_TYPE_PARAM:
3010  ret = CRYPT_CopyParam(pvData, pcbData, &msg->type, sizeof(msg->type));
3011  break;
3012  case CMSG_CONTENT_PARAM:
3013  if (msg->u.signed_data.info)
3014  {
3015  if (!strcmp(msg->u.signed_data.info->content.pszObjId,
3016  szOID_RSA_data))
3017  {
3019  DWORD size;
3020 
3022  msg->u.signed_data.info->content.Content.pbData,
3023  msg->u.signed_data.info->content.Content.cbData,
3025  if (ret)
3026  {
3027  ret = CRYPT_CopyParam(pvData, pcbData, blob->pbData,
3028  blob->cbData);
3029  LocalFree(blob);
3030  }
3031  }
3032  else
3034  msg->u.signed_data.info->content.Content.pbData,
3035  msg->u.signed_data.info->content.Content.cbData);
3036  }
3037  else
3039  break;
3041  if (msg->u.signed_data.info)
3043  msg->u.signed_data.info->content.pszObjId,
3044  strlen(msg->u.signed_data.info->content.pszObjId) + 1);
3045  else
3047  break;
3049  if (msg->u.signed_data.info)
3051  &msg->u.signed_data.info->cSignerInfo, sizeof(DWORD));
3052  else
3054  break;
3056  if (msg->u.signed_data.info)
3057  {
3058  if (dwIndex >= msg->u.signed_data.info->cSignerInfo)
3060  else
3062  &msg->u.signed_data.info->rgSignerInfo[dwIndex]);
3063  }
3064  else
3066  break;
3068  if (msg->u.signed_data.info)
3069  {
3070  if (dwIndex >= msg->u.signed_data.info->cSignerInfo)
3072  else
3074  &msg->u.signed_data.info->rgSignerInfo[dwIndex]);
3075  }
3076  else
3078  break;
3079  case CMSG_CERT_COUNT_PARAM:
3080  if (msg->u.signed_data.info)
3082  &msg->u.signed_data.info->cCertEncoded, sizeof(DWORD));
3083  else
3085  break;
3086  case CMSG_CERT_PARAM:
3087  if (msg->u.signed_data.info)
3088  {
3089  if (dwIndex >= msg->u.signed_data.info->cCertEncoded)
3091  else
3093  msg->u.signed_data.info->rgCertEncoded[dwIndex].pbData,
3094  msg->u.signed_data.info->rgCertEncoded[dwIndex].cbData);
3095  }
3096  else
3098  break;
3099  case CMSG_CRL_COUNT_PARAM:
3100  if (msg->u.signed_data.info)
3102  &msg->u.signed_data.info->cCrlEncoded, sizeof(DWORD));
3103  else
3105  break;
3106  case CMSG_CRL_PARAM:
3107  if (msg->u.signed_data.info)
3108  {
3109  if (dwIndex >= msg->u.signed_data.info->cCrlEncoded)
3111  else
3113  msg->u.signed_data.info->rgCrlEncoded[dwIndex].pbData,
3114  msg->u.signed_data.info->rgCrlEncoded[dwIndex].cbData);
3115  }
3116  else
3118  break;
3120  if (msg->u.signed_data.info)
3121  {
3122  if (dwIndex >= msg->u.signed_data.cSignerHandle)
3124  else
3126  msg->u.signed_data.signerHandles[dwIndex].contentHash,
3127  HP_HASHVAL, pvData, pcbData, 0);
3128  }
3129  else
3131  break;
3132  case CMSG_ENCODED_SIGNER:
3133  if (msg->u.signed_data.info)
3134  {
3135  if (dwIndex >= msg->u.signed_data.info->cSignerInfo)
3137  else
3140  &msg->u.signed_data.info->rgSignerInfo[dwIndex], 0, NULL,
3141  pvData, pcbData);
3142  }
3143  else
3145  break;
3147  if (msg->u.signed_data.info)
3148  {
3149  DWORD attrCertCount = 0;
3150 
3152  &attrCertCount, sizeof(DWORD));
3153  }
3154  else
3156  break;
3157  case CMSG_ATTR_CERT_PARAM:
3158  if (msg->u.signed_data.info)
3160  else
3162  break;
3164  if (msg->u.signed_data.info)
3165  {
3166  if (dwIndex >= msg->u.signed_data.info->cSignerInfo)
3168  else
3170  &msg->u.signed_data.info->rgSignerInfo[dwIndex]);
3171  }
3172  else
3174  break;
3175  default:
3176  FIXME("unimplemented for %d\n", dwParamType);
3178  }
3179  return ret;
3180 }
3181 
3182 static BOOL CDecodeMsg_GetParam(HCRYPTMSG hCryptMsg, DWORD dwParamType,
3183  DWORD dwIndex, void *pvData, DWORD *pcbData)
3184 {
3185  CDecodeMsg *msg = hCryptMsg;
3186  BOOL ret = FALSE;
3187 
3188  switch (msg->type)
3189  {
3190  case CMSG_HASHED:
3191  ret = CDecodeHashMsg_GetParam(msg, dwParamType, dwIndex, pvData,
3192  pcbData);
3193  break;
3194  case CMSG_ENVELOPED:
3195  ret = CDecodeEnvelopedMsg_GetParam(msg, dwParamType, dwIndex, pvData,
3196  pcbData);
3197  break;
3198  case CMSG_SIGNED:
3199  ret = CDecodeSignedMsg_GetParam(msg, dwParamType, dwIndex, pvData,
3200  pcbData);
3201  break;
3202  default:
3203  switch (dwParamType)
3204  {
3205  case CMSG_TYPE_PARAM:
3206  ret = CRYPT_CopyParam(pvData, pcbData, &msg->type,
3207  sizeof(msg->type));
3208  break;
3209  default:
3210  {
3212 
3213  ret = ContextPropertyList_FindProperty(msg->properties, dwParamType,
3214  &blob);
3215  if (ret)
3216  ret = CRYPT_CopyParam(pvData, pcbData, blob.pbData,
3217  blob.cbData);
3218  else
3220  }
3221  }
3222  }
3223  return ret;
3224 }
3225 
3227 {
3228  BOOL ret;
3230 
3233  if (ret)
3234  {
3235  DWORD computedHashSize = 0;
3236 
3238  &computedHashSize);
3239  if (hashBlob.cbData == computedHashSize)
3240  {
3241  LPBYTE computedHash = CryptMemAlloc(computedHashSize);
3242 
3243  if (computedHash)
3244  {
3246  computedHash, &computedHashSize);
3247  if (ret)
3248  {
3249  if (memcmp(hashBlob.pbData, computedHash, hashBlob.cbData))
3250  {
3252  ret = FALSE;
3253  }
3254  }
3255  CryptMemFree(computedHash);
3256  }
3257  else
3258  {
3260  ret = FALSE;
3261  }
3262  }
3263  else
3264  {
3266  ret = FALSE;
3267  }
3268  }
3269  return ret;
3270 }
3271 
3273  HCRYPTPROV prov, DWORD signerIndex, PCERT_PUBLIC_KEY_INFO keyInfo)
3274 {
3275  HCRYPTKEY key;
3276  BOOL ret;
3277 
3278  if (!prov)
3279  prov = msg->crypt_prov;
3280  ret = CryptImportPublicKeyInfo(prov, X509_ASN_ENCODING, keyInfo, &key);
3281  if (ret)
3282  {
3283  HCRYPTHASH hash;
3284  CRYPT_HASH_BLOB reversedHash;
3285 
3286  if (msg->u.signed_data.info->rgSignerInfo[signerIndex].AuthAttrs.cAttr)
3287  hash = msg->u.signed_data.signerHandles[signerIndex].authAttrHash;
3288  else
3289  hash = msg->u.signed_data.signerHandles[signerIndex].contentHash;
3290  ret = CRYPT_ConstructBlob(&reversedHash,
3291  &msg->u.signed_data.info->rgSignerInfo[signerIndex].EncryptedHash);
3292  if (ret)
3293  {
3294  CRYPT_ReverseBytes(&reversedHash);
3295  ret = CryptVerifySignatureW(hash, reversedHash.pbData,
3296  reversedHash.cbData, key, NULL, 0);
3297  CryptMemFree(reversedHash.pbData);
3298  }
3300  }
3301  return ret;
3302 }
3303 
3305 {
3306  BOOL ret = FALSE;
3307  DWORD i;
3308 
3309  if (!msg->u.signed_data.signerHandles)
3310  {
3312  return FALSE;
3313  }
3314  for (i = 0; !ret && i < msg->u.signed_data.info->cSignerInfo; i++)
3315  {
3316  PCMSG_CMS_SIGNER_INFO signerInfo =
3317  &msg->u.signed_data.info->rgSignerInfo[i];
3318 
3320  {
3322  &signerInfo->SignerId.u.IssuerSerialNumber.Issuer,
3323  &info->Issuer);
3324  if (ret)
3325  {
3327  &signerInfo->SignerId.u.IssuerSerialNumber.SerialNumber,
3328  &info->SerialNumber);
3329  if (ret)
3330  break;
3331  }
3332  }
3333  else
3334  {
3335  FIXME("signer %d: unimplemented for key id\n", i);
3336  }
3337  }
3338  if (ret)
3340  &info->SubjectPublicKeyInfo);
3341  else
3343 
3344  return ret;
3345 }
3346 
3349 {
3350  BOOL ret = FALSE;
3351 
3352  if (para->cbSize != sizeof(CMSG_CTRL_VERIFY_SIGNATURE_EX_PARA))
3354  else if (para->dwSignerIndex >= msg->u.signed_data.info->cSignerInfo)
3356  else if (!msg->u.signed_data.signerHandles)
3358  else
3359  {
3360  switch (para->dwSignerType)
3361  {
3364  para->hCryptProv, para->dwSignerIndex, para->pvSigner);
3365  break;
3367  {
3368  PCCERT_CONTEXT cert = para->pvSigner;
3369 
3371  para->dwSignerIndex, &cert->pCertInfo->SubjectPublicKeyInfo);
3372  break;
3373  }
3374  default:
3375  FIXME("unimplemented for signer type %d\n", para->dwSignerType);
3377  }
3378  }
3379  return ret;
3380 }
3381 
3383  PCRYPT_ALGORITHM_IDENTIFIER pContentEncryptionAlgorithm,
3384  PCMSG_CTRL_KEY_TRANS_DECRYPT_PARA pKeyTransDecryptPara, DWORD dwFlags,
3385  void *pvReserved, HCRYPTKEY *phContentEncryptKey)
3386 {
3387  BOOL ret;
3388  HCRYPTKEY key;
3389 
3390  ret = CryptGetUserKey(pKeyTransDecryptPara->hCryptProv,
3391  pKeyTransDecryptPara->dwKeySpec ? pKeyTransDecryptPara->dwKeySpec :
3392  AT_KEYEXCHANGE, &key);
3393  if (ret)
3394  {
3396  &pKeyTransDecryptPara->pKeyTrans[pKeyTransDecryptPara->dwRecipientIndex];
3397  CRYPT_DATA_BLOB *encryptedKey = &info->EncryptedKey;
3398  DWORD size = encryptedKey->cbData + sizeof(BLOBHEADER) + sizeof(ALG_ID);
3399  BYTE *keyBlob = CryptMemAlloc(size);
3400 
3401  if (keyBlob)
3402  {
3403  DWORD i, k = size - 1;
3404  BLOBHEADER *blobHeader = (BLOBHEADER *)keyBlob;
3405  ALG_ID *algID = (ALG_ID *)(keyBlob + sizeof(BLOBHEADER));
3406 
3407  blobHeader->bType = SIMPLEBLOB;
3408  blobHeader->bVersion = CUR_BLOB_VERSION;
3409  blobHeader->reserved = 0;
3410  blobHeader->aiKeyAlg = CertOIDToAlgId(
3411  pContentEncryptionAlgorithm->pszObjId);
3412  *algID = CertOIDToAlgId(info->KeyEncryptionAlgorithm.pszObjId);
3413  for (i = 0; i < encryptedKey->cbData; ++i, --k)
3414  keyBlob[k] = encryptedKey->pbData[i];
3415 
3416  ret = CryptImportKey(pKeyTransDecryptPara->hCryptProv, keyBlob,
3417  size, key, 0, phContentEncryptKey);
3418  CryptMemFree(keyBlob);
3419  }
3420  else
3421  ret = FALSE;
3423  }
3424  return ret;
3425 }
3426 
3429  HCRYPTKEY *key)
3430 {
3431  static HCRYPTOIDFUNCSET set = NULL;
3432  PFN_CMSG_IMPORT_KEY_TRANS importKeyFunc = NULL;
3433  HCRYPTOIDFUNCADDR hFunc = NULL;
3435  BOOL ret;
3436 
3437  memset(&decryptPara, 0, sizeof(decryptPara));
3438  decryptPara.cbSize = sizeof(decryptPara);
3439  decryptPara.hCryptProv = para->hCryptProv;
3440  decryptPara.dwKeySpec = para->dwKeySpec;
3441  decryptPara.pKeyTrans = info;
3442  decryptPara.dwRecipientIndex = para->dwRecipientIndex;
3443 
3444  if (!set)
3447  (void **)&importKeyFunc, &hFunc);
3448  if (!importKeyFunc)
3449  importKeyFunc = CRYPT_ImportKeyTrans;
3450  ret = importKeyFunc(contEncrAlg, &decryptPara, 0, NULL, key);
3451  if (hFunc)
3452  CryptFreeOIDFunctionAddress(hFunc, 0);
3453  return ret;
3454 }
3455 
3458 {
3459  BOOL ret = FALSE;
3460  CEnvelopedDecodeMsg *enveloped_data = &msg->u.enveloped_data;
3461  CRYPT_ENVELOPED_DATA *data = enveloped_data->data;
3462 
3463  if (para->cbSize != sizeof(CMSG_CTRL_DECRYPT_PARA))
3465  else if (!data)
3467  else if (para->dwRecipientIndex >= data->cRecipientInfo)
3469  else if (enveloped_data->decrypted)
3471  else if (!para->hCryptProv)
3473  else if (enveloped_data->content.cbData)
3474  {
3475  HCRYPTKEY key;
3476 
3478  &data->encryptedContentInfo.contentEncryptionAlgorithm, para,
3479  data->rgRecipientInfo, &key);
3480  if (ret)
3481  {
3482  ret = CryptDecrypt(key, 0, TRUE, 0, enveloped_data->content.pbData,
3483  &enveloped_data->content.cbData);
3485  }
3486  }
3487  else
3488  ret = TRUE;
3489  if (ret)
3490  enveloped_data->decrypted = TRUE;
3491  return ret;
3492 }
3493 
3495  DWORD dwCtrlType, const void *pvCtrlPara)
3496 {
3497  CDecodeMsg *msg = hCryptMsg;
3498  BOOL ret = FALSE;
3499 
3500  switch (dwCtrlType)
3501  {
3503  switch (msg->type)
3504  {
3505  case CMSG_SIGNED:
3507  break;
3508  default:
3510  }
3511  break;
3512  case CMSG_CTRL_DECRYPT:
3513  switch (msg->type)
3514  {
3515  case CMSG_ENVELOPED:
3517  (PCMSG_CTRL_DECRYPT_PARA)pvCtrlPara);
3519  msg->u.enveloped_data.crypt_prov =
3520  ((PCMSG_CTRL_DECRYPT_PARA)pvCtrlPara)->hCryptProv;
3521  break;
3522  default:
3524  }
3525  break;
3526  case CMSG_CTRL_VERIFY_HASH:
3527  switch (msg->type)
3528  {
3529  case CMSG_HASHED:
3531  break;
3532  default:
3534  }
3535  break;
3537  switch (msg->type)
3538  {
3539  case CMSG_SIGNED:
3542  break;
3543  default:
3545  }
3546  break;
3547  default:
3549  }
3550  return ret;
3551 }
3552 
3554  DWORD dwMsgType, HCRYPTPROV_LEGACY hCryptProv, PCERT_INFO pRecipientInfo,
3555  PCMSG_STREAM_INFO pStreamInfo)
3556 {
3557  CDecodeMsg *msg;
3558 
3559  TRACE("(%08x, %08x, %08x, %08lx, %p, %p)\n", dwMsgEncodingType,
3560  dwFlags, dwMsgType, hCryptProv, pRecipientInfo, pStreamInfo);
3561 
3562  if (GET_CMSG_ENCODING_TYPE(dwMsgEncodingType) != PKCS_7_ASN_ENCODING)
3563  {
3565  return NULL;
3566  }
3567  msg = CryptMemAlloc(sizeof(CDecodeMsg));
3568  if (msg)
3569  {
3570  CryptMsgBase_Init((CryptMsgBase *)msg, dwFlags, pStreamInfo,
3573  msg->type = dwMsgType;
3574  msg->crypt_prov = hCryptProv;
3575  memset(&msg->u, 0, sizeof(msg->u));
3576  msg->msg_data.cbData = 0;
3577  msg->msg_data.pbData = NULL;
3578  msg->detached_data.cbData = 0;
3579  msg->detached_data.pbData = NULL;
3580  msg->properties = ContextPropertyList_Create();
3581  }
3582  return msg;
3583 }
3584 
3586 {
3587  TRACE("(%p)\n", hCryptMsg);
3588 
3589  if (hCryptMsg)
3590  {
3591  CryptMsgBase *msg = hCryptMsg;
3592 
3593  InterlockedIncrement(&msg->ref);
3594  }
3595  return hCryptMsg;
3596 }
3597 
3599 {
3600  TRACE("(%p)\n", hCryptMsg);
3601 
3602  if (hCryptMsg)
3603  {
3604  CryptMsgBase *msg = hCryptMsg;
3605 
3606  if (InterlockedDecrement(&msg->ref) == 0)
3607  {
3608  TRACE("freeing %p\n", msg);
3609  if (msg->close)
3610  msg->close(msg);
3611  CryptMemFree(msg);
3612  }
3613  }
3614  return TRUE;
3615 }
3616 
3618  DWORD cbData, BOOL fFinal)
3619 {
3620  CryptMsgBase *msg = hCryptMsg;
3621 
3622  TRACE("(%p, %p, %d, %d)\n", hCryptMsg, pbData, cbData, fFinal);
3623 
3624  return msg->update(hCryptMsg, pbData, cbData, fFinal);
3625 }
3626 
3627 BOOL WINAPI CryptMsgGetParam(HCRYPTMSG hCryptMsg, DWORD dwParamType,
3628  DWORD dwIndex, void *pvData, DWORD *pcbData)
3629 {
3630  CryptMsgBase *msg = hCryptMsg;
3631 
3632  TRACE("(%p, %d, %d, %p, %p)\n", hCryptMsg, dwParamType, dwIndex,
3633  pvData, pcbData);
3634  return msg->get_param(hCryptMsg, dwParamType, dwIndex, pvData, pcbData);
3635 }
3636 
3638  DWORD dwCtrlType, const void *pvCtrlPara)
3639 {
3640  CryptMsgBase *msg = hCryptMsg;
3641 
3642  TRACE("(%p, %08x, %d, %p)\n", hCryptMsg, dwFlags, dwCtrlType,
3643  pvCtrlPara);
3644  return msg->control(hCryptMsg, dwFlags, dwCtrlType, pvCtrlPara);
3645 }
3646 
3648  DWORD dwSignerIndex)
3649 {
3650  CERT_INFO *certInfo = NULL;
3651  DWORD size;
3652 
3654  &size))
3655  {
3656  certInfo = CryptMemAlloc(size);
3657  if (certInfo)
3658  {
3660  dwSignerIndex, certInfo, &size))
3661  {
3662  CryptMemFree(certInfo);
3663  certInfo = NULL;
3664  }
3665  }
3666  }
3667  return certInfo;
3668 }
3669 
3671  HCERTSTORE *rghSignerStore, DWORD dwFlags, PCCERT_CONTEXT *ppSigner,
3673 {
3674  HCERTSTORE store;
3675  DWORD i, signerIndex = 0;
3676  PCCERT_CONTEXT signerCert = NULL;
3677  BOOL ret = FALSE;
3678 
3679  TRACE("(%p, %d, %p, %08x, %p, %p)\n", hCryptMsg, cSignerStore,
3680  rghSignerStore, dwFlags, ppSigner, pdwSignerIndex);
3681 
3682  /* Clear output parameters */
3683  if (ppSigner)
3684  *ppSigner = NULL;
3686  *pdwSignerIndex = 0;
3687 
3688  /* Create store to search for signer certificates */
3692  {
3693  HCERTSTORE msgStore = CertOpenStore(CERT_STORE_PROV_MSG, 0, 0, 0,
3694  hCryptMsg);
3695 
3696  CertAddStoreToCollection(store, msgStore, 0, 0);
3697  CertCloseStore(msgStore, 0);
3698  }
3699  for (i = 0; i < cSignerStore; i++)
3700  CertAddStoreToCollection(store, rghSignerStore[i], 0, 0);
3701 
3702  /* Find signer cert */
3704  {
3705  CERT_INFO *signer = CRYPT_GetSignerCertInfoFromMsg(hCryptMsg,
3706  *pdwSignerIndex);
3707 
3708  if (signer)
3709  {
3710  signerIndex = *pdwSignerIndex;
3711  signerCert = CertFindCertificateInStore(store, X509_ASN_ENCODING,
3712  0, CERT_FIND_SUBJECT_CERT, signer, NULL);
3713  CryptMemFree(signer);
3714  }
3715  }
3716  else
3717  {
3718  DWORD count, size = sizeof(count);
3719 
3720  if (CryptMsgGetParam(hCryptMsg, CMSG_SIGNER_COUNT_PARAM, 0, &count,
3721  &size))
3722  {
3723  for (i = 0; !signerCert && i < count; i++)
3724  {
3725  CERT_INFO *signer = CRYPT_GetSignerCertInfoFromMsg(hCryptMsg,
3726  i);
3727 
3728  if (signer)
3729  {
3730  signerCert = CertFindCertificateInStore(store,
3732  NULL);
3733  if (signerCert)
3734  signerIndex = i;
3735  CryptMemFree(signer);
3736  }
3737  }
3738  }
3739  if (!signerCert)
3741  }
3742  if (signerCert)
3743  {
3744  if (!(dwFlags & CMSG_SIGNER_ONLY_FLAG))
3746  signerCert->pCertInfo);
3747  else
3748  ret = TRUE;
3749  if (ret)
3750  {
3751  if (ppSigner)
3753  if (pdwSignerIndex)
3754  *pdwSignerIndex = signerIndex;
3755  }
3756  CertFreeCertificateContext(signerCert);
3757  }
3758 
3759  CertCloseStore(store, 0);
3760  return ret;
3761 }
3762 
3764  DWORD dwEncodingType, BYTE *pbSignerInfo, DWORD cbSignerInfo,
3765  PBYTE pbSignerInfoCountersignature, DWORD cbSignerInfoCountersignature,
3766  CERT_INFO *pciCountersigner)
3767 {
3768  FIXME("(%08lx, %08x, %p, %d, %p, %d, %p): stub\n", hCryptProv,
3769  dwEncodingType, pbSignerInfo, cbSignerInfo, pbSignerInfoCountersignature,
3770  cbSignerInfoCountersignature, pciCountersigner);
3771  return FALSE;
3772 }
3773 
3775  DWORD dwEncodingType, PBYTE pbSignerInfo, DWORD cbSignerInfo,
3776  PBYTE pbSignerInfoCountersignature, DWORD cbSignerInfoCountersignature,
3777  DWORD dwSignerType, void *pvSigner, DWORD dwFlags, void *pvReserved)
3778 {
3779  FIXME("(%08lx, %08x, %p, %d, %p, %d, %d, %p, %08x, %p): stub\n", hCryptProv,
3780  dwEncodingType, pbSignerInfo, cbSignerInfo, pbSignerInfoCountersignature,
3781  cbSignerInfoCountersignature, dwSignerType, pvSigner, dwFlags, pvReserved);
3782  return FALSE;
3783 }
3784 
3786  PCTL_INFO pCtlInfo, PCMSG_SIGNED_ENCODE_INFO pSignInfo, DWORD dwFlags,
3788 {
3789  BOOL ret;
3790  BYTE *pbCtlContent;
3791  DWORD cbCtlContent;
3792 
3793  TRACE("(%08x, %p, %p, %08x, %p, %p)\n", dwMsgEncodingType, pCtlInfo,
3794  pSignInfo, dwFlags, pbEncoded, pcbEncoded);
3795 
3796  if (dwFlags)
3797  {
3798  FIXME("unimplemented for flags %08x\n", dwFlags);
3799  return FALSE;
3800  }
3801  if ((ret = CryptEncodeObjectEx(dwMsgEncodingType, PKCS_CTL, pCtlInfo,
3802  CRYPT_ENCODE_ALLOC_FLAG, NULL, &pbCtlContent, &cbCtlContent)))
3803  {
3804  ret = CryptMsgSignCTL(dwMsgEncodingType, pbCtlContent, cbCtlContent,
3805  pSignInfo, dwFlags, pbEncoded, pcbEncoded);
3806  LocalFree(pbCtlContent);
3807  }
3808  return ret;
3809 }
3810 
3811 BOOL WINAPI CryptMsgSignCTL(DWORD dwMsgEncodingType, BYTE *pbCtlContent,
3812  DWORD cbCtlContent, PCMSG_SIGNED_ENCODE_INFO pSignInfo, DWORD dwFlags,
3814 {
3815  static char oid_ctl[] = szOID_CTL;
3816  BOOL ret;
3817  HCRYPTMSG msg;
3818 
3819  TRACE("(%08x, %p, %d, %p, %08x, %p, %p)\n", dwMsgEncodingType,
3820  pbCtlContent, cbCtlContent, pSignInfo, dwFlags, pbEncoded, pcbEncoded);
3821 
3822  if (dwFlags)
3823  {
3824  FIXME("unimplemented for flags %08x\n", dwFlags);
3825  return FALSE;
3826  }
3827  msg = CryptMsgOpenToEncode(dwMsgEncodingType, 0, CMSG_SIGNED, pSignInfo,
3828  oid_ctl, NULL);
3829  if (msg)
3830  {
3831  ret = CryptMsgUpdate(msg, pbCtlContent, cbCtlContent, TRUE);
3832  if (ret)
3834  pcbEncoded);
3835  CryptMsgClose(msg);
3836  }
3837  else
3838  ret = FALSE;
3839  return ret;
3840 }
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 * u
Definition: glfuncs.h:240
CRYPT_ALGORITHM_IDENTIFIER algo
Definition: msg.c:1504
static void CSignerInfo_Free(CMSG_CMS_SIGNER_INFO *info)
Definition: msg.c:879
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
PCCERT_CONTEXT WINAPI CertFindCertificateInStore(HCERTSTORE hCertStore, DWORD dwCertEncodingType, DWORD dwFlags, DWORD dwType, const void *pvPara, PCCERT_CONTEXT pPrevCertContext)
Definition: cert.c:1765
CRYPT_DATA_BLOB content
Definition: msg.c:2080
HCRYPTPROV prov
Definition: msg.c:1505
HCRYPTHASH contentHash
Definition: msg.c:913
HCRYPTMSG WINAPI CryptMsgDuplicate(HCRYPTMSG hCryptMsg)
Definition: msg.c:3585
static void CRecipientInfo_Free(CMSG_KEY_TRANS_RECIPIENT_INFO *info)
Definition: msg.c:1790
HCRYPTOIDFUNCSET WINAPI CryptInitOIDFunctionSet(LPCSTR pszFuncName, DWORD dwFlags)
Definition: oid.c:114
enum _CryptMsgState CryptMsgState
_In_ DWORD _In_ DWORD _Outptr_opt_ PCCERT_CONTEXT * ppSigner
Definition: wincrypt.h:5779
#define CRYPT_E_MSG_ERROR
Definition: winerror.h:2985
static BOOL CDecodeMsg_DecodeSignedContent(CDecodeMsg *msg, const CRYPT_DER_BLOB *blob)
Definition: msg.c:2264
static HCRYPTPROV crypt_prov
Definition: dib.c:29
#define CMSG_SIGNED_DATA_V1
Definition: wincrypt.h:3973
BOOL CRYPT_AsnEncodePKCSDigestedData(const CRYPT_DIGESTED_DATA *digestedData, void *pvData, DWORD *pcbData) DECLSPEC_HIDDEN
Definition: encode.c:1952
#define TRUE
Definition: types.h:120
HCRYPTPROV crypt_prov
Definition: msg.c:2079
Definition: msg.c:1065
#define CMSG_ATTR_CERT_COUNT_PARAM
Definition: wincrypt.h:3951
#define NTE_BAD_SIGNATURE
Definition: winerror.h:2874
#define ASN_OCTETSTRING
Definition: snmp.h:105
void(* CryptMsgCloseFunc)(HCRYPTMSG msg)
Definition: msg.c:38
CRYPT_DATA_BLOB data
Definition: msg.c:1509
CryptMsgBase base
Definition: msg.c:1188
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define PKCS_ATTRIBUTES
Definition: wincrypt.h:3418
CRYPT_DATA_BLOB EncryptedHash
Definition: wincrypt.h:3966
#define CMSG_HASH_ALGORITHM_PARAM
Definition: wincrypt.h:3943
static HCRYPTMSG CDataEncodeMsg_Open(DWORD dwFlags, const void *pvMsgEncodeInfo, LPSTR pszInnerContentObjID, PCMSG_STREAM_INFO pStreamInfo)
Definition: msg.c:351
CRYPT_SIGNED_INFO * info
Definition: msg.c:919
unsigned int ALG_ID
Definition: wincrypt.h:45
static BYTE keyId[]
Definition: encode.c:4920
CRYPT_DATA_BLOB msg_data
Definition: msg.c:2094
BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
Definition: decode.c:6286
CryptMsgCloseFunc close
Definition: msg.c:71
static BOOL CDecodeEnvelopedMsg_CrtlDecrypt(CDecodeMsg *msg, PCMSG_CTRL_DECRYPT_PARA para)
Definition: msg.c:3456
#define CMSG_CRL_PARAM
Definition: wincrypt.h:3938
Definition: image.c:133
static const BYTE serialNumber[]
Definition: msg.c:2848
struct _CEnvelopedDecodeMsg CEnvelopedDecodeMsg
static void CRYPT_CopyBlob(CRYPT_DATA_BLOB *out, const CRYPT_DATA_BLOB *in, LPBYTE *nextData)
Definition: msg.c:2603
#define ALIGN_DWORD_PTR(x)
HCRYPTHASH authAttrHash
Definition: msg.c:914
static BOOL WINAPI CRYPT_ExportKeyTrans(PCMSG_CONTENT_ENCRYPT_INFO pContentEncryptInfo, PCMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO pKeyTransEncodeInfo, PCMSG_KEY_TRANS_ENCRYPT_INFO pKeyTransEncryptInfo, DWORD dwFlags, void *pvReserved)
Definition: msg.c:1564
struct outqueuenode * head
Definition: adnsresfilter.c:66
static BOOL CSignedMsgData_AllocateHandles(CSignedMsgData *msg_data)
Definition: msg.c:955
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
static void void SIZE_T *static void(WINAPI *pReleaseActCtx)(HANDLE)
struct _CMSG_SIGNER_INFO CMSG_SIGNER_INFO
BOOL(* CryptMsgControlFunc)(HCRYPTMSG hCryptMsg, DWORD dwFlags, DWORD dwCtrlType, const void *pvCtrlPara)
Definition: msg.c:46
static BOOL CHashEncodeMsg_Update(HCRYPTMSG hCryptMsg, const BYTE *pbData, DWORD cbData, BOOL fFinal)
Definition: msg.c:506
#define CMSG_CERT_PARAM
Definition: wincrypt.h:3936
static void CContentEncryptInfo_Free(CMSG_CONTENT_ENCRYPT_INFO *info)
Definition: msg.c:1743
DWORD cRecipientInfo
Definition: msg.c:1507
BOOL ContextPropertyList_SetProperty(CONTEXT_PROPERTY_LIST *list, DWORD id, const BYTE *pbData, size_t cbData) DECLSPEC_HIDDEN
Definition: proplist.c:95
struct _CryptMsgBase CryptMsgBase
#define CMSG_CMS_SIGNER_INFO_PARAM
Definition: wincrypt.h:3959
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define CMSG_SIGNED
Definition: wincrypt.h:3680
BOOL ContextPropertyList_FindProperty(CONTEXT_PROPERTY_LIST *list, DWORD id, PCRYPT_DATA_BLOB blob) DECLSPEC_HIDDEN
Definition: proplist.c:72
BOOL WINAPI CertFreeCertificateContext(PCCERT_CONTEXT pCertContext)
Definition: cert.c:371
CRYPT_DATA_BLOB EncryptedKey
Definition: wincrypt.h:4069
CryptMsgBase base
Definition: msg.c:375
ALG_ID aiKeyAlg
Definition: wincrypt.h:139
#define POINTER_ALIGN_DWORD_PTR(p)
static LPVOID WINAPI mem_alloc(size_t size)
Definition: msg.c:1671
PCRYPT_ATTRIBUTE rgUnauthAttr
Definition: msg.c:607
#define CMSG_HASHED_DATA_PKCS_1_5_VERSION
Definition: wincrypt.h:3985
#define CERT_STORE_PROV_MSG
Definition: wincrypt.h:2250
static CERT_INFO * CRYPT_GetSignerCertInfoFromMsg(HCRYPTMSG msg, DWORD dwSignerIndex)
Definition: msg.c:3647
struct _CSignedEncodeMsg CSignedEncodeMsg
#define CMSG_CTRL_VERIFY_SIGNATURE_EX
Definition: wincrypt.h:3885
static VOID WINAPI mem_free(LPVOID pv)
Definition: msg.c:1676
CRYPT_ATTRIBUTES AuthAttrs
Definition: wincrypt.h:3967
static const BYTE hashBlob[]
Definition: message.c:644
BOOL WINAPI CryptEncodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags, PCRYPT_ENCODE_PARA pEncodePara, void *pvEncoded, DWORD *pcbEncoded)
Definition: encode.c:4696
#define CMSG_CTRL_DECRYPT
Definition: wincrypt.h:3870
#define CMSG_TRUSTED_SIGNER_FLAG
Definition: wincrypt.h:4120
_In_ DWORD cSignerStore
Definition: wincrypt.h:5777
#define CMSG_ATTR_CERT_PARAM
Definition: wincrypt.h:3952
#define CMSG_DATA
Definition: wincrypt.h:3679
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
static BOOL CHashEncodeMsg_GetParam(HCRYPTMSG hCryptMsg, DWORD dwParamType, DWORD dwIndex, void *pvData, DWORD *pcbData)
Definition: msg.c:439
CRYPT_INTEGER_BLOB SerialNumber
Definition: wincrypt.h:242
#define CMSG_KEY_TRANS_RECIPIENT
Definition: wincrypt.h:3812
HCRYPTHASH hash
Definition: msg.c:377
BOOL WINAPI CRYPT_AsnEncodeSequence(DWORD dwCertEncodingType, struct AsnEncodeSequenceItem items[], DWORD cItem, DWORD dwFlags, PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded) DECLSPEC_HIDDEN
Definition: encode.c:180
Definition: msg.c:1064
#define PKCS_7_ASN_ENCODING
Definition: wincrypt.h:2299
static BOOL CRYPT_CopySignerInfo(void *pvData, DWORD *pcbData, const CMSG_CMS_SIGNER_INFO *in)
Definition: msg.c:2729
#define GET_CMSG_ENCODING_TYPE(x)
Definition: wincrypt.h:2293
static void CHashEncodeMsg_Close(HCRYPTMSG hCryptMsg)
Definition: msg.c:381
BOOL WINAPI CertAddStoreToCollection(HCERTSTORE hCollectionStore, HCERTSTORE hSiblingStore, DWORD dwUpdateFlags, DWORD dwPriority)
static void CRYPT_FixUpAlgorithmID(CRYPT_ALGORITHM_IDENTIFIER *id)
Definition: msg.c:2206
void ContextPropertyList_Free(CONTEXT_PROPERTY_LIST *list) DECLSPEC_HIDDEN
Definition: proplist.c:56
char * LPSTR
Definition: xmlstorage.h:182
struct _CERT_INFO CERT_INFO
#define CMSG_COMPUTED_HASH_PARAM
Definition: wincrypt.h:3945
BOOL CRYPT_EncodeLen(DWORD len, BYTE *pbEncoded, DWORD *pcbEncoded) DECLSPEC_HIDDEN
Definition: encode.c:138