ReactOS  0.4.15-dev-483-ga77a65a
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  if (ret)
1580  ret = CryptImportPublicKeyInfo(pKeyTransEncodeInfo->hCryptProv,
1581  X509_ASN_ENCODING, &keyInfo, &expKey);
1582  if (ret)
1583  {
1584  DWORD size;
1585 
1586  ret = CryptExportKey(pContentEncryptInfo->hContentEncryptKey, expKey,
1587  SIMPLEBLOB, 0, NULL, &size);
1588  if (ret)
1589  {
1590  BYTE *keyBlob;
1591 
1592  keyBlob = CryptMemAlloc(size);
1593  if (keyBlob)
1594  {
1595  ret = CryptExportKey(pContentEncryptInfo->hContentEncryptKey,
1596  expKey, SIMPLEBLOB, 0, keyBlob, &size);
1597  if (ret)
1598  {
1599  DWORD head = sizeof(BLOBHEADER) + sizeof(ALG_ID);
1600 
1601  pKeyTransEncryptInfo->EncryptedKey.pbData =
1602  CryptMemAlloc(size - head);
1603  if (pKeyTransEncryptInfo->EncryptedKey.pbData)
1604  {
1605  DWORD i, k = 0;
1606 
1607  pKeyTransEncryptInfo->EncryptedKey.cbData = size - head;
1608  for (i = size - 1; i >= head; --i, ++k)
1609  pKeyTransEncryptInfo->EncryptedKey.pbData[k] =
1610  keyBlob[i];
1611  }
1612  else
1613  ret = FALSE;
1614  }
1615  CryptMemFree(keyBlob);
1616  }
1617  else
1618  ret = FALSE;
1619  }
1620  CryptDestroyKey(expKey);
1621  }
1622 
1623  CryptMemFree(keyInfo.PublicKey.pbData);
1624  CryptMemFree(keyInfo.Algorithm.pszObjId);
1626  return ret;
1627 }
1628 
1631 {
1632  static HCRYPTOIDFUNCSET set = NULL;
1633  PFN_CMSG_EXPORT_KEY_TRANS exportKeyFunc = NULL;
1634  HCRYPTOIDFUNCADDR hFunc = NULL;
1636  info->rgCmsRecipients[i].u.pKeyTrans;
1637  CMSG_KEY_TRANS_ENCRYPT_INFO encryptInfo;
1638  BOOL ret;
1639 
1640  memset(&encryptInfo, 0, sizeof(encryptInfo));
1641  encryptInfo.cbSize = sizeof(encryptInfo);
1642  encryptInfo.dwRecipientIndex = i;
1644  &encodeInfo->KeyEncryptionAlgorithm);
1645 
1646  if (!set)
1649  encryptInfo.KeyEncryptionAlgorithm.pszObjId, 0, (void **)&exportKeyFunc,
1650  &hFunc);
1651  if (!exportKeyFunc)
1652  exportKeyFunc = CRYPT_ExportKeyTrans;
1653  if (ret)
1654  {
1655  ret = exportKeyFunc(info, encodeInfo, &encryptInfo, 0, NULL);
1656  if (ret)
1657  {
1658  key->cbData = encryptInfo.EncryptedKey.cbData;
1659  key->pbData = encryptInfo.EncryptedKey.pbData;
1660  }
1661  }
1662  if (hFunc)
1663  CryptFreeOIDFunctionAddress(hFunc, 0);
1664 
1667  return ret;
1668 }
1669 
1670 static LPVOID WINAPI mem_alloc(size_t size)
1671 {
1672  return HeapAlloc(GetProcessHeap(), 0, size);
1673 }
1674 
1676 {
1677  HeapFree(GetProcessHeap(), 0, pv);
1678 }
1679 
1680 
1683 {
1684  BOOL ret;
1685 
1686  info->cbSize = sizeof(CMSG_CONTENT_ENCRYPT_INFO);
1687  info->hCryptProv = prov;
1688  ret = CRYPT_ConstructAlgorithmId(&info->ContentEncryptionAlgorithm,
1689  &in->ContentEncryptionAlgorithm);
1690  info->pvEncryptionAuxInfo = in->pvEncryptionAuxInfo;
1691  info->cRecipients = in->cRecipients;
1692  if (ret)
1693  {
1694  info->rgCmsRecipients = CryptMemAlloc(in->cRecipients *
1695  sizeof(CMSG_RECIPIENT_ENCODE_INFO));
1696  if (info->rgCmsRecipients)
1697  {
1698  DWORD i;
1699 
1700  for (i = 0; ret && i < in->cRecipients; ++i)
1701  {
1703  CERT_INFO *cert = in->rgpRecipientCert[i];
1704 
1705  info->rgCmsRecipients[i].dwRecipientChoice =
1707  encodeInfo = CryptMemAlloc(sizeof(*encodeInfo));
1708  info->rgCmsRecipients[i].u.pKeyTrans = encodeInfo;
1709  if (encodeInfo)
1710  {
1711  encodeInfo->cbSize = sizeof(*encodeInfo);
1713  &encodeInfo->KeyEncryptionAlgorithm,
1714  &cert->SubjectPublicKeyInfo.Algorithm);
1715  encodeInfo->pvKeyEncryptionAuxInfo = NULL;
1716  encodeInfo->hCryptProv = prov;
1717  if (ret)
1719  &encodeInfo->RecipientPublicKey,
1720  &cert->SubjectPublicKeyInfo.PublicKey);
1721  if (ret)
1723  &encodeInfo->RecipientId.u.IssuerSerialNumber.Issuer,
1724  &cert->Issuer);
1725  if (ret)
1728  &cert->SerialNumber);
1729  }
1730  else
1731  ret = FALSE;
1732  }
1733  }
1734  else
1735  ret = FALSE;
1736  }
1737  info->pfnAlloc = mem_alloc;
1738  info->pfnFree = mem_free;
1739  return ret;
1740 }
1741 
1743 {
1744  CryptMemFree(info->ContentEncryptionAlgorithm.pszObjId);
1745  CryptMemFree(info->ContentEncryptionAlgorithm.Parameters.pbData);
1746  if (info->rgCmsRecipients)
1747  {
1748  DWORD i;
1749 
1750  for (i = 0; i < info->cRecipients; ++i)
1751  {
1753  info->rgCmsRecipients[i].u.pKeyTrans;
1754 
1757  CryptMemFree(encodeInfo->RecipientPublicKey.pbData);
1758  CryptMemFree(
1760  CryptMemFree(
1762  CryptMemFree(encodeInfo);
1763  }
1764  CryptMemFree(info->rgCmsRecipients);
1765  }
1766 }
1767 
1769  const CERT_INFO *cert, CRYPT_DATA_BLOB *key)
1770 {
1771  BOOL ret;
1772 
1774  info->RecipientId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
1775  ret = CRYPT_ConstructBlob(&info->RecipientId.u.IssuerSerialNumber.Issuer,
1776  &cert->Issuer);
1777  if (ret)
1779  &info->RecipientId.u.IssuerSerialNumber.SerialNumber,
1780  &cert->SerialNumber);
1781  if (ret)
1782  ret = CRYPT_ConstructAlgorithmId(&info->KeyEncryptionAlgorithm,
1783  &cert->SubjectPublicKeyInfo.Algorithm);
1784  info->EncryptedKey.cbData = key->cbData;
1785  info->EncryptedKey.pbData = key->pbData;
1786  return ret;
1787 }
1788 
1790 {
1791  CryptMemFree(info->RecipientId.u.IssuerSerialNumber.Issuer.pbData);
1792  CryptMemFree(info->RecipientId.u.IssuerSerialNumber.SerialNumber.pbData);
1793  CryptMemFree(info->KeyEncryptionAlgorithm.pszObjId);
1794  CryptMemFree(info->KeyEncryptionAlgorithm.Parameters.pbData);
1795  CryptMemFree(info->EncryptedKey.pbData);
1796 }
1797 
1798 static void CEnvelopedEncodeMsg_Close(HCRYPTMSG hCryptMsg)
1799 {
1800  CEnvelopedEncodeMsg *msg = hCryptMsg;
1801 
1802  CryptMemFree(msg->algo.pszObjId);
1803  CryptMemFree(msg->algo.Parameters.pbData);
1804  if (msg->base.open_flags & CMSG_CRYPT_RELEASE_CONTEXT_FLAG)
1805  CryptReleaseContext(msg->prov, 0);
1806  CryptDestroyKey(msg->key);
1807  if (msg->recipientInfo)
1808  {
1809  DWORD i;
1810 
1811  for (i = 0; i < msg->cRecipientInfo; ++i)
1812  CRecipientInfo_Free(&msg->recipientInfo[i]);
1813  CryptMemFree(msg->recipientInfo);
1814  }
1815  CryptMemFree(msg->data.pbData);
1816 }
1817 
1818 static BOOL CEnvelopedEncodeMsg_GetParam(HCRYPTMSG hCryptMsg, DWORD dwParamType,
1819  DWORD dwIndex, void *pvData, DWORD *pcbData)
1820 {
1821  CEnvelopedEncodeMsg *msg = hCryptMsg;
1822  BOOL ret = FALSE;
1823 
1824  switch (dwParamType)
1825  {
1827  if (msg->base.streamed)
1829  else
1830  {
1831  char oid_rsa_data[] = szOID_RSA_data;
1832  CRYPT_ENVELOPED_DATA envelopedData = {
1833  CMSG_ENVELOPED_DATA_PKCS_1_5_VERSION, msg->cRecipientInfo,
1834  msg->recipientInfo, { oid_rsa_data, {
1835  msg->algo.pszObjId,
1836  { msg->algo.Parameters.cbData, msg->algo.Parameters.pbData }
1837  },
1838  { msg->data.cbData, msg->data.pbData }
1839  }
1840  };
1841 
1842  ret = CRYPT_AsnEncodePKCSEnvelopedData(&envelopedData, pvData,
1843  pcbData);
1844  }
1845  break;
1846  case CMSG_CONTENT_PARAM:
1847  {
1849 
1851  &info.Content.cbData);
1852  if (ret)
1853  {
1854  info.Content.pbData = CryptMemAlloc(info.Content.cbData);
1855  if (info.Content.pbData)
1856  {
1858  info.Content.pbData, &info.Content.cbData);
1859  if (ret)
1860  {
1861  char oid_rsa_enveloped[] = szOID_RSA_envelopedData;
1862 
1863  info.pszObjId = oid_rsa_enveloped;
1866  }
1867  CryptMemFree(info.Content.pbData);
1868  }
1869  else
1870  ret = FALSE;
1871  }
1872  break;
1873  }
1874  default:
1876  }
1877  return ret;
1878 }
1879 
1881  DWORD cbData, BOOL fFinal)
1882 {
1883  CEnvelopedEncodeMsg *msg = hCryptMsg;
1884  BOOL ret = FALSE;
1885 
1886  if (msg->base.state == MsgStateFinalized)
1888  else if (msg->base.streamed)
1889  {
1890  FIXME("streamed stub\n");
1891  msg->base.state = fFinal ? MsgStateFinalized : MsgStateUpdated;
1892  ret = TRUE;
1893  }
1894  else
1895  {
1896  if (!fFinal)
1897  {
1898  if (msg->base.open_flags & CMSG_DETACHED_FLAG)
1900  else
1902  }
1903  else
1904  {
1905  if (cbData)
1906  {
1907  DWORD dataLen = cbData;
1908 
1909  msg->data.cbData = cbData;
1910  msg->data.pbData = CryptMemAlloc(cbData);
1911  if (msg->data.pbData)
1912  {
1913  memcpy(msg->data.pbData, pbData, cbData);
1914  ret = CryptEncrypt(msg->key, 0, TRUE, 0, msg->data.pbData,
1915  &dataLen, msg->data.cbData);
1916  msg->data.cbData = dataLen;
1917  if (dataLen > cbData)
1918  {
1919  msg->data.pbData = CryptMemRealloc(msg->data.pbData,
1920  dataLen);
1921  if (msg->data.pbData)
1922  {
1923  dataLen = cbData;
1924  ret = CryptEncrypt(msg->key, 0, TRUE, 0,
1925  msg->data.pbData, &dataLen, msg->data.cbData);
1926  }
1927  else
1928  ret = FALSE;
1929  }
1930  if (!ret)
1931  CryptMemFree(msg->data.pbData);
1932  }
1933  else
1934  ret = FALSE;
1935  if (!ret)
1936  {
1937  msg->data.cbData = 0;
1938  msg->data.pbData = NULL;
1939  }
1940  }
1941  else
1942  ret = TRUE;
1943  msg->base.state = MsgStateFinalized;
1944  }
1945  }
1946  return ret;
1947 }
1948 
1950  const void *pvMsgEncodeInfo, LPCSTR pszInnerContentObjID,
1951  PCMSG_STREAM_INFO pStreamInfo)
1952 {
1954  const CMSG_ENVELOPED_ENCODE_INFO_WITH_CMS *info = pvMsgEncodeInfo;
1955  HCRYPTPROV prov;
1956  ALG_ID algID;
1957 
1958  if (info->cbSize != sizeof(CMSG_ENVELOPED_ENCODE_INFO) &&
1959  info->cbSize != sizeof(CMSG_ENVELOPED_ENCODE_INFO_WITH_CMS))
1960  {
1962  return NULL;
1963  }
1964  if (info->cbSize == sizeof(CMSG_ENVELOPED_ENCODE_INFO_WITH_CMS))
1965  FIXME("CMS fields unsupported\n");
1966  if (!(algID = CertOIDToAlgId(info->ContentEncryptionAlgorithm.pszObjId)))
1967  {
1969  return NULL;
1970  }
1971  if (info->cRecipients && !info->rgpRecipientCert)
1972  {
1974  return NULL;
1975  }
1976  if (info->hCryptProv)
1977  prov = info->hCryptProv;
1978  else
1979  {
1980  prov = I_CryptGetDefaultCryptProv(0);
1982  }
1984  if (msg)
1985  {
1986  CRYPT_DATA_BLOB encryptedKey = { 0, NULL };
1987  CMSG_CONTENT_ENCRYPT_INFO encryptInfo;
1988  BOOL ret;
1989  DWORD i;
1990 
1991  CryptMsgBase_Init((CryptMsgBase *)msg, dwFlags, pStreamInfo,
1995  &info->ContentEncryptionAlgorithm);
1996  msg->prov = prov;
1997  msg->data.cbData = 0;
1998  msg->data.pbData = NULL;
1999  msg->cRecipientInfo = info->cRecipients;
2000  msg->recipientInfo = CryptMemAlloc(info->cRecipients *
2002  if (!msg->recipientInfo)
2003  ret = FALSE;
2004  memset(&encryptInfo, 0, sizeof(encryptInfo));
2005  if (ret)
2006  {
2007  ret = CContentEncryptInfo_Construct(&encryptInfo, info, prov);
2008  if (ret)
2009  {
2010  ret = CRYPT_GenKey(&encryptInfo, algID);
2011  if (ret)
2012  msg->key = encryptInfo.hContentEncryptKey;
2013  }
2014  }
2015  for (i = 0; ret && i < msg->cRecipientInfo; ++i)
2016  {
2017  ret = CRYPT_ExportEncryptedKey(&encryptInfo, i, &encryptedKey);
2018  if (ret)
2019  ret = CRecipientInfo_Construct(&msg->recipientInfo[i],
2020  info->rgpRecipientCert[i], &encryptedKey);
2021  }
2022  CContentEncryptInfo_Free(&encryptInfo);
2023  if (!ret)
2024  {
2025  CryptMsgClose(msg);
2026  msg = NULL;
2027  }
2028  }
2030  CryptReleaseContext(prov, 0);
2031  return msg;
2032 }
2033 
2035  DWORD dwMsgType, const void *pvMsgEncodeInfo, LPSTR pszInnerContentObjID,
2036  PCMSG_STREAM_INFO pStreamInfo)
2037 {
2038  HCRYPTMSG msg = NULL;
2039 
2040  TRACE("(%08x, %08x, %08x, %p, %s, %p)\n", dwMsgEncodingType, dwFlags,
2041  dwMsgType, pvMsgEncodeInfo, debugstr_a(pszInnerContentObjID), pStreamInfo);
2042 
2043  if (GET_CMSG_ENCODING_TYPE(dwMsgEncodingType) != PKCS_7_ASN_ENCODING)
2044  {
2046  return NULL;
2047  }
2048  switch (dwMsgType)
2049  {
2050  case CMSG_DATA:
2051  msg = CDataEncodeMsg_Open(dwFlags, pvMsgEncodeInfo,
2052  pszInnerContentObjID, pStreamInfo);
2053  break;
2054  case CMSG_HASHED:
2055  msg = CHashEncodeMsg_Open(dwFlags, pvMsgEncodeInfo,
2056  pszInnerContentObjID, pStreamInfo);
2057  break;
2058  case CMSG_SIGNED:
2059  msg = CSignedEncodeMsg_Open(dwFlags, pvMsgEncodeInfo,
2060  pszInnerContentObjID, pStreamInfo);
2061  break;
2062  case CMSG_ENVELOPED:
2063  msg = CEnvelopedEncodeMsg_Open(dwFlags, pvMsgEncodeInfo,
2064  pszInnerContentObjID, pStreamInfo);
2065  break;
2067  case CMSG_ENCRYPTED:
2068  /* defined but invalid, fall through */
2069  default:
2071  }
2072  return msg;
2073 }
2074 
2075 typedef struct _CEnvelopedDecodeMsg
2076 {
2082 
2083 typedef struct _CDecodeMsg
2084 {
2088  union {
2092  } u;
2096 } CDecodeMsg;
2097 
2098 static void CDecodeMsg_Close(HCRYPTMSG hCryptMsg)
2099 {
2100  CDecodeMsg *msg = hCryptMsg;
2101 
2102  if (msg->crypt_prov && msg->base.open_flags & CMSG_CRYPT_RELEASE_CONTEXT_FLAG)
2103  CryptReleaseContext(msg->crypt_prov, 0);
2104  switch (msg->type)
2105  {
2106  case CMSG_HASHED:
2107  if (msg->u.hash)
2108  CryptDestroyHash(msg->u.hash);
2109  break;
2110  case CMSG_ENVELOPED:
2111  if (msg->u.enveloped_data.crypt_prov)
2112  CryptReleaseContext(msg->u.enveloped_data.crypt_prov, 0);
2113  LocalFree(msg->u.enveloped_data.data);
2114  CryptMemFree(msg->u.enveloped_data.content.pbData);
2115  break;
2116  case CMSG_SIGNED:
2117  if (msg->u.signed_data.info)
2118  {
2119  LocalFree(msg->u.signed_data.info);
2120  CSignedMsgData_CloseHandles(&msg->u.signed_data);
2121  }
2122  break;
2123  }
2124  CryptMemFree(msg->msg_data.pbData);
2125  CryptMemFree(msg->detached_data.pbData);
2126  ContextPropertyList_Free(msg->properties);
2127 }
2128 
2130  DWORD cbData)
2131 {
2132  BOOL ret = TRUE;
2133 
2134  if (cbData)
2135  {
2136  if (blob->cbData)
2137  blob->pbData = CryptMemRealloc(blob->pbData,
2138  blob->cbData + cbData);
2139  else
2140  blob->pbData = CryptMemAlloc(cbData);
2141  if (blob->pbData)
2142  {
2143  memcpy(blob->pbData + blob->cbData, pbData, cbData);
2144  blob->cbData += cbData;
2145  }
2146  else
2147  ret = FALSE;
2148  }
2149  return ret;
2150 }
2151 
2153 {
2154  BOOL ret;
2156  DWORD size;
2157 
2159  blob->pbData, blob->cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, &data, &size);
2160  if (ret)
2161  {
2162  ret = ContextPropertyList_SetProperty(msg->properties,
2163  CMSG_CONTENT_PARAM, data->pbData, data->cbData);
2164  LocalFree(data);
2165  }
2166  return ret;
2167 }
2168 
2170  const CRYPT_ALGORITHM_IDENTIFIER *id)
2171 {
2172  static const BYTE nullParams[] = { ASN_NULL, 0 };
2175 
2176  /* Linearize algorithm id */
2177  len += strlen(id->pszObjId) + 1;
2178  len += id->Parameters.cbData;
2179  copy = CryptMemAlloc(len);
2180  if (copy)
2181  {
2182  copy->pszObjId =
2183  (LPSTR)((BYTE *)copy + sizeof(CRYPT_ALGORITHM_IDENTIFIER));
2184  strcpy(copy->pszObjId, id->pszObjId);
2185  copy->Parameters.pbData = (BYTE *)copy->pszObjId + strlen(id->pszObjId)
2186  + 1;
2187  /* Trick: omit NULL parameters */
2188  if (id->Parameters.cbData == sizeof(nullParams) &&
2189  !memcmp(id->Parameters.pbData, nullParams, sizeof(nullParams)))
2190  {
2191  copy->Parameters.cbData = 0;
2192  len -= sizeof(nullParams);
2193  }
2194  else
2195  copy->Parameters.cbData = id->Parameters.cbData;
2196  if (copy->Parameters.cbData)
2197  memcpy(copy->Parameters.pbData, id->Parameters.pbData,
2198  id->Parameters.cbData);
2200  len);
2201  CryptMemFree(copy);
2202  }
2203 }
2204 
2206 {
2207  id->pszObjId = (LPSTR)((BYTE *)id + sizeof(CRYPT_ALGORITHM_IDENTIFIER));
2208  id->Parameters.pbData = (BYTE *)id->pszObjId + strlen(id->pszObjId) + 1;
2209 }
2210 
2212  const CRYPT_DER_BLOB *blob)
2213 {
2214  BOOL ret;
2215  CRYPT_DIGESTED_DATA *digestedData;
2216  DWORD size;
2217 
2218  ret = CRYPT_AsnDecodePKCSDigestedData(blob->pbData, blob->cbData,
2220  &size);
2221  if (ret)
2222  {
2224  (const BYTE *)&digestedData->version, sizeof(digestedData->version));
2226  &digestedData->DigestAlgorithm);
2229  (const BYTE *)digestedData->ContentInfo.pszObjId,
2230  digestedData->ContentInfo.pszObjId ?
2231  strlen(digestedData->ContentInfo.pszObjId) + 1 : 0);
2232  if (!(msg->base.open_flags & CMSG_DETACHED_FLAG))
2233  {
2234  if (digestedData->ContentInfo.Content.cbData)
2236  &digestedData->ContentInfo.Content);
2237  else
2239  CMSG_CONTENT_PARAM, NULL, 0);
2240  }
2242  digestedData->hash.pbData, digestedData->hash.cbData);
2243  LocalFree(digestedData);
2244  }
2245  return ret;
2246 }
2247 
2249  const CRYPT_DER_BLOB *blob)
2250 {
2251  BOOL ret;
2252  CRYPT_ENVELOPED_DATA *envelopedData;
2253  DWORD size;
2254 
2255  ret = CRYPT_AsnDecodePKCSEnvelopedData(blob->pbData, blob->cbData,
2257  &size);
2258  if (ret)
2259  msg->u.enveloped_data.data = envelopedData;
2260  return ret;
2261 }
2262 
2264  const CRYPT_DER_BLOB *blob)
2265 {
2266  BOOL ret;
2267  CRYPT_SIGNED_INFO *signedInfo;
2268  DWORD size;
2269 
2270  ret = CRYPT_AsnDecodeCMSSignedInfo(blob->pbData, blob->cbData,
2272  &size);
2273  if (ret)
2274  msg->u.signed_data.info = signedInfo;
2275  return ret;
2276 }
2277 
2278 /* Decodes the content in blob as the type given, and updates the value
2279  * (type, parameters, etc.) of msg based on what blob contains.
2280  * It doesn't just use msg's type, to allow a recursive call from an implicitly
2281  * typed message once the outer content info has been decoded.
2282  */
2284  DWORD type)
2285 {
2286  BOOL ret;
2287 
2288  switch (type)
2289  {
2290  case CMSG_DATA:
2292  msg->type = CMSG_DATA;
2293  break;
2294  case CMSG_HASHED:
2296  msg->type = CMSG_HASHED;
2297  break;
2298  case CMSG_ENVELOPED:
2300  msg->type = CMSG_ENVELOPED;
2301  break;
2302  case CMSG_SIGNED:
2304  msg->type = CMSG_SIGNED;
2305  break;
2306  default:
2307  {
2309  DWORD size;
2310 
2312  msg->msg_data.pbData, msg->msg_data.cbData, CRYPT_DECODE_ALLOC_FLAG,
2313  NULL, &info, &size);
2314  if (ret)
2315  {
2316  if (!strcmp(info->pszObjId, szOID_RSA_data))
2318  else if (!strcmp(info->pszObjId, szOID_RSA_digestedData))
2319  ret = CDecodeMsg_DecodeContent(msg, &info->Content,
2320  CMSG_HASHED);
2321  else if (!strcmp(info->pszObjId, szOID_RSA_envelopedData))
2322  ret = CDecodeMsg_DecodeContent(msg, &info->Content,
2323  CMSG_ENVELOPED);
2324  else if (!strcmp(info->pszObjId, szOID_RSA_signedData))
2325  ret = CDecodeMsg_DecodeContent(msg, &info->Content,
2326  CMSG_SIGNED);
2327  else
2328  {
2330  ret = FALSE;
2331  }
2332  LocalFree(info);
2333  }
2334  }
2335  }
2336  return ret;
2337 }
2338 
2341 {
2342  CRYPT_ALGORITHM_IDENTIFIER *hashAlgoID = NULL;
2343  DWORD size = 0;
2344  ALG_ID algID = 0;
2345  BOOL ret;
2346 
2348  hashAlgoID = CryptMemAlloc(size);
2350  &size);
2351  if (ret)
2352  algID = CertOIDToAlgId(hashAlgoID->pszObjId);
2353 
2354  if (!msg->crypt_prov)
2355  {
2356  msg->crypt_prov = I_CryptGetDefaultCryptProv(algID);
2357  if (msg->crypt_prov)
2358  msg->base.open_flags &= ~CMSG_CRYPT_RELEASE_CONTEXT_FLAG;
2359  }
2360 
2361  ret = CryptCreateHash(msg->crypt_prov, algID, 0, 0, &msg->u.hash);
2362  if (ret)
2363  {
2365 
2366  if (msg->base.open_flags & CMSG_DETACHED_FLAG)
2367  {
2368  /* Unlike for non-detached messages, the data were never stored as
2369  * the content param, but were saved in msg->detached_data instead.
2370  */
2371  content.pbData = msg->detached_data.pbData;
2372  content.cbData = msg->detached_data.cbData;
2373  }
2374  else
2377  if (ret)
2378  ret = CryptHashData(msg->u.hash, content.pbData, content.cbData, 0);
2379  }
2380  CryptMemFree(hashAlgoID);
2381  return ret;
2382 }
2383 
2386 {
2388 
2389  if (msg->base.open_flags & CMSG_DETACHED_FLAG)
2390  content = &msg->detached_data;
2391  else
2392  content =
2393  &msg->u.enveloped_data.data->encryptedContentInfo.encryptedContent;
2394 
2395  return CRYPT_ConstructBlob(&msg->u.enveloped_data.content, content);
2396 }
2397 
2400 {
2401  BOOL ret;
2402  DWORD i, size;
2403 
2404  ret = CSignedMsgData_AllocateHandles(&msg->u.signed_data);
2405  for (i = 0; ret && i < msg->u.signed_data.info->cSignerInfo; i++)
2406  ret = CSignedMsgData_ConstructSignerHandles(&msg->u.signed_data, i,
2407  &msg->crypt_prov, &msg->base.open_flags);
2408  if (ret)
2409  {
2411 
2412  /* Now that we have all the content, update the hash handles with
2413  * it. If the message is a detached message, the content is stored
2414  * in msg->detached_data rather than in the signed message's
2415  * content.
2416  */
2417  if (msg->base.open_flags & CMSG_DETACHED_FLAG)
2418  content = &msg->detached_data;
2419  else
2420  content = &msg->u.signed_data.info->content.Content;
2421  if (content->cbData)
2422  {
2423  /* If the message is not detached, have to decode the message's
2424  * content if the type is szOID_RSA_data.
2425  */
2426  if (!(msg->base.open_flags & CMSG_DETACHED_FLAG) &&
2427  !strcmp(msg->u.signed_data.info->content.pszObjId,
2428  szOID_RSA_data))
2429  {
2430  CRYPT_DATA_BLOB *rsa_blob;
2431 
2433  X509_OCTET_STRING, content->pbData, content->cbData,
2434  CRYPT_DECODE_ALLOC_FLAG, NULL, &rsa_blob, &size);
2435  if (ret)
2436  {
2437  ret = CSignedMsgData_Update(&msg->u.signed_data,
2438  rsa_blob->pbData, rsa_blob->cbData, TRUE, Verify);
2439  LocalFree(rsa_blob);
2440  }
2441  }
2442  else
2443  ret = CSignedMsgData_Update(&msg->u.signed_data,
2444  content->pbData, content->cbData, TRUE, Verify);
2445  }
2446  }
2447  return ret;
2448 }
2449 
2451 {
2452  BOOL ret = FALSE;
2453 
2454  switch (msg->type)
2455  {
2456  case CMSG_HASHED:
2458  break;
2459  case CMSG_ENVELOPED:
2461  break;
2462  case CMSG_SIGNED:
2464  break;
2465  default:
2466  ret = TRUE;
2467  }
2468  return ret;
2469 }
2470 
2471 static BOOL CDecodeMsg_Update(HCRYPTMSG hCryptMsg, const BYTE *pbData,
2472  DWORD cbData, BOOL fFinal)
2473 {
2474  CDecodeMsg *msg = hCryptMsg;
2475  BOOL ret = FALSE;
2476 
2477  TRACE("(%p, %p, %d, %d)\n", hCryptMsg, pbData, cbData, fFinal);
2478 
2479  if (msg->base.state == MsgStateFinalized)
2481  else if (msg->base.streamed)
2482  {
2483  FIXME("(%p, %p, %d, %d): streamed update stub\n", hCryptMsg, pbData,
2484  cbData, fFinal);
2485  switch (msg->base.state)
2486  {
2487  case MsgStateInit:
2488  ret = CDecodeMsg_CopyData(&msg->msg_data, pbData, cbData);
2489  if (fFinal)
2490  {
2491  if (msg->base.open_flags & CMSG_DETACHED_FLAG)
2492  msg->base.state = MsgStateDataFinalized;
2493  else
2494  msg->base.state = MsgStateFinalized;
2495  }
2496  else
2497  msg->base.state = MsgStateUpdated;
2498  break;
2499  case MsgStateUpdated:
2500  ret = CDecodeMsg_CopyData(&msg->msg_data, pbData, cbData);
2501  if (fFinal)
2502  {
2503  if (msg->base.open_flags & CMSG_DETACHED_FLAG)
2504  msg->base.state = MsgStateDataFinalized;
2505  else
2506  msg->base.state = MsgStateFinalized;
2507  }
2508  break;
2509  case MsgStateDataFinalized:
2510  ret = CDecodeMsg_CopyData(&msg->detached_data, pbData, cbData);
2511  if (fFinal)
2512  msg->base.state = MsgStateFinalized;
2513  break;
2514  default:
2516  break;
2517  }
2518  }
2519  else
2520  {
2521  if (!fFinal)
2523  else
2524  {
2525  switch (msg->base.state)
2526  {
2527  case MsgStateInit:
2528  ret = CDecodeMsg_CopyData(&msg->msg_data, pbData, cbData);
2529  if (msg->base.open_flags & CMSG_DETACHED_FLAG)
2530  msg->base.state = MsgStateDataFinalized;
2531  else
2532  msg->base.state = MsgStateFinalized;
2533  break;
2534  case MsgStateDataFinalized:
2535  ret = CDecodeMsg_CopyData(&msg->detached_data, pbData, cbData);
2536  msg->base.state = MsgStateFinalized;
2537  break;
2538  default:
2540  }
2541  }
2542  }
2543  if (ret && fFinal &&
2544  ((msg->base.open_flags & CMSG_DETACHED_FLAG && msg->base.state ==
2546  (!(msg->base.open_flags & CMSG_DETACHED_FLAG) && msg->base.state ==
2548  ret = CDecodeMsg_DecodeContent(msg, &msg->msg_data, msg->type);
2549  if (ret && msg->base.state == MsgStateFinalized)
2550  ret = CDecodeMsg_FinalizeContent(msg, &msg->msg_data);
2551  return ret;
2552 }
2553 
2555  DWORD dwIndex, void *pvData, DWORD *pcbData)
2556 {
2557  BOOL ret = FALSE;
2558 
2559  switch (dwParamType)
2560  {
2561  case CMSG_TYPE_PARAM:
2562  ret = CRYPT_CopyParam(pvData, pcbData, &msg->type, sizeof(msg->type));
2563  break;
2565  {
2567 
2568  ret = ContextPropertyList_FindProperty(msg->properties, dwParamType,
2569  &blob);
2570  if (ret)
2571  {
2572  ret = CRYPT_CopyParam(pvData, pcbData, blob.pbData, blob.cbData);
2573  if (ret && pvData)
2575  }
2576  else
2578  break;
2579  }
2581  ret = CryptGetHashParam(msg->u.hash, HP_HASHVAL, pvData, pcbData, 0);
2582  break;
2583  default:
2584  {
2586 
2587  ret = ContextPropertyList_FindProperty(msg->properties, dwParamType,
2588  &blob);
2589  if (ret)
2590  ret = CRYPT_CopyParam(pvData, pcbData, blob.pbData, blob.cbData);
2591  else
2593  }
2594  }
2595  return ret;
2596 }
2597 
2598 /* nextData is an in/out parameter - on input it's the memory location in
2599  * which a copy of in's data should be made, and on output it's the memory
2600  * location immediately after out's copy of in's data.
2601  */
2602 static inline void CRYPT_CopyBlob(CRYPT_DATA_BLOB *out,
2603  const CRYPT_DATA_BLOB *in, LPBYTE *nextData)
2604 {
2605  out->cbData = in->cbData;
2606  if (in->cbData)
2607  {
2608  out->pbData = *nextData;
2609  memcpy(out->pbData, in->pbData, in->cbData);
2610  *nextData += in->cbData;
2611  }
2612 }
2613 
2615  const CRYPT_ALGORITHM_IDENTIFIER *in, LPBYTE *nextData)
2616 {
2617  if (in->pszObjId)
2618  {
2619  out->pszObjId = (LPSTR)*nextData;
2620  strcpy(out->pszObjId, in->pszObjId);
2621  *nextData += strlen(out->pszObjId) + 1;
2622  }
2623  CRYPT_CopyBlob(&out->Parameters, &in->Parameters, nextData);
2624 }
2625 
2627  const CRYPT_ATTRIBUTES *in, LPBYTE *nextData)
2628 {
2629  out->cAttr = in->cAttr;
2630  if (in->cAttr)
2631  {
2632  DWORD i;
2633 
2634  *nextData = POINTER_ALIGN_DWORD_PTR(*nextData);
2635  out->rgAttr = (CRYPT_ATTRIBUTE *)*nextData;
2636  *nextData += in->cAttr * sizeof(CRYPT_ATTRIBUTE);
2637  for (i = 0; i < in->cAttr; i++)
2638  {
2639  if (in->rgAttr[i].pszObjId)
2640  {
2641  out->rgAttr[i].pszObjId = (LPSTR)*nextData;
2642  strcpy(out->rgAttr[i].pszObjId, in->rgAttr[i].pszObjId);
2643  *nextData += strlen(in->rgAttr[i].pszObjId) + 1;
2644  }
2645  if (in->rgAttr[i].cValue)
2646  {
2647  DWORD j;
2648 
2649  out->rgAttr[i].cValue = in->rgAttr[i].cValue;
2650  *nextData = POINTER_ALIGN_DWORD_PTR(*nextData);
2651  out->rgAttr[i].rgValue = (PCRYPT_DATA_BLOB)*nextData;
2652  *nextData += in->rgAttr[i].cValue * sizeof(CRYPT_DATA_BLOB);
2653  for (j = 0; j < in->rgAttr[i].cValue; j++)
2654  CRYPT_CopyBlob(&out->rgAttr[i].rgValue[j],
2655  &in->rgAttr[i].rgValue[j], nextData);
2656  }
2657  }
2658  }
2659 }
2660 
2662 {
2663  DWORD size = attr->cAttr * sizeof(CRYPT_ATTRIBUTE), i, j;
2664 
2665  for (i = 0; i < attr->cAttr; i++)
2666  {
2667  if (attr->rgAttr[i].pszObjId)
2668  size += strlen(attr->rgAttr[i].pszObjId) + 1;
2669  /* align pointer */
2671  size += attr->rgAttr[i].cValue * sizeof(CRYPT_DATA_BLOB);
2672  for (j = 0; j < attr->rgAttr[i].cValue; j++)
2673  size += attr->rgAttr[i].rgValue[j].cbData;
2674  }
2675  /* align pointer again to be conservative */
2677  return size;
2678 }
2679 
2681 {
2682  static char oid_key_rdn[] = szOID_KEYID_RDN;
2683  DWORD size = 0;
2685  CERT_RDN rdn = { 1, &attr };
2686  CERT_NAME_INFO name = { 1, &rdn };
2687 
2688  attr.pszObjId = oid_key_rdn;
2689  attr.dwValueType = CERT_RDN_OCTET_STRING;
2690  attr.Value.cbData = keyId->cbData;
2691  attr.Value.pbData = keyId->pbData;
2693  size++; /* Only include size of special zero serial number on success */
2694  return size;
2695 }
2696 
2699  LPBYTE *nextData)
2700 {
2701  static char oid_key_rdn[] = szOID_KEYID_RDN;
2703  CERT_RDN rdn = { 1, &attr };
2704  CERT_NAME_INFO name = { 1, &rdn };
2705  BOOL ret;
2706 
2707  /* Encode special zero serial number */
2708  serialNumber->cbData = 1;
2709  serialNumber->pbData = *nextData;
2710  **nextData = 0;
2711  (*nextData)++;
2712  /* Encode issuer */
2713  issuer->pbData = *nextData;
2714  attr.pszObjId = oid_key_rdn;
2715  attr.dwValueType = CERT_RDN_OCTET_STRING;
2716  attr.Value.cbData = keyId->cbData;
2717  attr.Value.pbData = keyId->pbData;
2719  &encodedLen);
2720  if (ret)
2721  {
2722  *nextData += encodedLen;
2723  issuer->cbData = encodedLen;
2724  }
2725  return ret;
2726 }
2727 
2729  const CMSG_CMS_SIGNER_INFO *in)
2730 {
2731  DWORD size = sizeof(CMSG_SIGNER_INFO), rdnSize = 0;
2732  BOOL ret;
2733 
2734  TRACE("(%p, %d, %p)\n", pvData, pvData ? *pcbData : 0, in);
2735 
2736  if (in->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER)
2737  {
2738  size += in->SignerId.u.IssuerSerialNumber.Issuer.cbData;
2739  size += in->SignerId.u.IssuerSerialNumber.SerialNumber.cbData;
2740  }
2741  else
2742  {
2743  rdnSize = CRYPT_SizeOfKeyIdAsIssuerAndSerial(&in->SignerId.u.KeyId);
2744  size += rdnSize;
2745  }
2746  if (in->HashAlgorithm.pszObjId)
2747  size += strlen(in->HashAlgorithm.pszObjId) + 1;
2748  size += in->HashAlgorithm.Parameters.cbData;
2749  if (in->HashEncryptionAlgorithm.pszObjId)
2750  size += strlen(in->HashEncryptionAlgorithm.pszObjId) + 1;
2751  size += in->HashEncryptionAlgorithm.Parameters.cbData;
2752  size += in->EncryptedHash.cbData;
2753  /* align pointer */
2755  size += CRYPT_SizeOfAttributes(&in->AuthAttrs);
2756  size += CRYPT_SizeOfAttributes(&in->UnauthAttrs);
2757  if (!pvData)
2758  {
2759  ret = TRUE;
2760  }
2761  else if (*pcbData < size)
2762  {
2764  ret = FALSE;
2765  }
2766  else
2767  {
2768  LPBYTE nextData = (BYTE *)pvData + sizeof(CMSG_SIGNER_INFO);
2770 
2771  ret = TRUE;
2772  out->dwVersion = in->dwVersion;
2773  if (in->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER)
2774  {
2775  CRYPT_CopyBlob(&out->Issuer,
2776  &in->SignerId.u.IssuerSerialNumber.Issuer, &nextData);
2777  CRYPT_CopyBlob(&out->SerialNumber,
2778  &in->SignerId.u.IssuerSerialNumber.SerialNumber, &nextData);
2779  }
2780  else
2781  ret = CRYPT_CopyKeyIdAsIssuerAndSerial(&out->Issuer, &out->SerialNumber,
2782  &in->SignerId.u.KeyId, rdnSize, &nextData);
2783  if (ret)
2784  {
2785  CRYPT_CopyAlgorithmId(&out->HashAlgorithm, &in->HashAlgorithm,
2786  &nextData);
2787  CRYPT_CopyAlgorithmId(&out->HashEncryptionAlgorithm,
2788  &in->HashEncryptionAlgorithm, &nextData);
2789  CRYPT_CopyBlob(&out->EncryptedHash, &in->EncryptedHash, &nextData);
2790  nextData = POINTER_ALIGN_DWORD_PTR(nextData);
2791  CRYPT_CopyAttributes(&out->AuthAttrs, &in->AuthAttrs, &nextData);
2792  CRYPT_CopyAttributes(&out->UnauthAttrs, &in->UnauthAttrs, &nextData);
2793  }
2794  }
2795  *pcbData = size;
2796  TRACE("returning %d\n", ret);
2797  return ret;
2798 }
2799 
2801  const CMSG_CMS_SIGNER_INFO *in)
2802 {
2803  DWORD size = sizeof(CMSG_CMS_SIGNER_INFO);
2804  BOOL ret;
2805 
2806  TRACE("(%p, %d, %p)\n", pvData, pvData ? *pcbData : 0, in);
2807 
2808  if (in->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER)
2809  {
2810  size += in->SignerId.u.IssuerSerialNumber.Issuer.cbData;
2811  size += in->SignerId.u.IssuerSerialNumber.SerialNumber.cbData;
2812  }
2813  else
2814  size += in->SignerId.u.KeyId.cbData;
2815  if (in->HashAlgorithm.pszObjId)
2816  size += strlen(in->HashAlgorithm.pszObjId) + 1;
2817  size += in->HashAlgorithm.Parameters.cbData;
2818  if (in->HashEncryptionAlgorithm.pszObjId)
2819  size += strlen(in->HashEncryptionAlgorithm.pszObjId) + 1;
2820  size += in->HashEncryptionAlgorithm.Parameters.cbData;
2821  size += in->EncryptedHash.cbData;
2822  /* align pointer */
2824  size += CRYPT_SizeOfAttributes(&in->AuthAttrs);
2825  size += CRYPT_SizeOfAttributes(&in->UnauthAttrs);
2826  if (!pvData)
2827  {
2828  *pcbData = size;
2829  ret = TRUE;
2830  }
2831  else if (*pcbData < size)
2832  {
2833  *pcbData = size;
2835  ret = FALSE;
2836  }
2837  else
2838  {
2839  LPBYTE nextData = (BYTE *)pvData + sizeof(CMSG_CMS_SIGNER_INFO);
2841 
2842  out->dwVersion = in->dwVersion;
2843  out->SignerId.dwIdChoice = in->SignerId.dwIdChoice;
2844  if (in->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER)
2845  {
2846  CRYPT_CopyBlob(&out->SignerId.u.IssuerSerialNumber.Issuer,
2847  &in->SignerId.u.IssuerSerialNumber.Issuer, &nextData);
2848  CRYPT_CopyBlob(&out->SignerId.u.IssuerSerialNumber.SerialNumber,
2849  &in->SignerId.u.IssuerSerialNumber.SerialNumber, &nextData);
2850  }
2851  else
2852  CRYPT_CopyBlob(&out->SignerId.u.KeyId, &in->SignerId.u.KeyId, &nextData);
2853  CRYPT_CopyAlgorithmId(&out->HashAlgorithm, &in->HashAlgorithm,
2854  &nextData);
2855  CRYPT_CopyAlgorithmId(&out->HashEncryptionAlgorithm,
2856  &in->HashEncryptionAlgorithm, &nextData);
2857  CRYPT_CopyBlob(&out->EncryptedHash, &in->EncryptedHash, &nextData);
2858  nextData = POINTER_ALIGN_DWORD_PTR(nextData);
2859  CRYPT_CopyAttributes(&out->AuthAttrs, &in->AuthAttrs, &nextData);
2860  CRYPT_CopyAttributes(&out->UnauthAttrs, &in->UnauthAttrs, &nextData);
2861  ret = TRUE;
2862  }
2863  TRACE("returning %d\n", ret);
2864  return ret;
2865 }
2866 
2868  const CMSG_CMS_SIGNER_INFO *in)
2869 {
2870  DWORD size = sizeof(CERT_INFO), rdnSize = 0;
2871  BOOL ret;
2872 
2873  TRACE("(%p, %d, %p)\n", pvData, pvData ? *pcbData : 0, in);
2874 
2875  if (in->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER)
2876  {
2877  size += in->SignerId.u.IssuerSerialNumber.Issuer.cbData;
2878  size += in->SignerId.u.IssuerSerialNumber.SerialNumber.cbData;
2879  }
2880  else
2881  {
2882  rdnSize = CRYPT_SizeOfKeyIdAsIssuerAndSerial(&in->SignerId.u.KeyId);
2883  size += rdnSize;
2884  }
2885  if (!pvData)
2886  {
2887  *pcbData = size;
2888  ret = TRUE;
2889  }
2890  else if (*pcbData < size)
2891  {
2892  *pcbData = size;
2894  ret = FALSE;
2895  }
2896  else
2897  {
2898  LPBYTE nextData = (BYTE *)pvData + sizeof(CERT_INFO);
2899  CERT_INFO *out = pvData;
2900 
2901  memset(out, 0, sizeof(CERT_INFO));
2902  if (in->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER)
2903  {
2904  CRYPT_CopyBlob(&out->Issuer,
2905  &in->SignerId.u.IssuerSerialNumber.Issuer, &nextData);
2906  CRYPT_CopyBlob(&out->SerialNumber,
2907  &in->SignerId.u.IssuerSerialNumber.SerialNumber, &nextData);
2908  ret = TRUE;
2909  }
2910  else
2911  ret = CRYPT_CopyKeyIdAsIssuerAndSerial(&out->Issuer, &out->SerialNumber,
2912  &in->SignerId.u.KeyId, rdnSize, &nextData);
2913  }
2914  TRACE("returning %d\n", ret);
2915  return ret;
2916 }
2917 
2920 {
2921  DWORD size = sizeof(CERT_INFO);
2922  BOOL ret;
2923 
2924  TRACE("(%p, %d, %p)\n", pvData, pvData ? *pcbData : 0, in);
2925 
2926  size += in->SerialNumber.cbData;
2927  size += in->Issuer.cbData;
2928  if (!pvData)
2929  {
2930  *pcbData = size;
2931  ret = TRUE;
2932  }
2933  else if (*pcbData < size)
2934  {
2935  *pcbData = size;
2937  ret = FALSE;
2938  }
2939  else
2940  {
2941  LPBYTE nextData = (BYTE *)pvData + sizeof(CERT_INFO);
2942  CERT_INFO *out = pvData;
2943 
2944  CRYPT_CopyBlob(&out->SerialNumber, &in->SerialNumber, &nextData);
2945  CRYPT_CopyBlob(&out->Issuer, &in->Issuer, &nextData);
2946  ret = TRUE;
2947  }
2948  TRACE("returning %d\n", ret);
2949  return ret;
2950 }
2951 
2953  DWORD dwIndex, void *pvData, DWORD *pcbData)
2954 {
2955  BOOL ret = FALSE;
2956 
2957  switch (dwParamType)
2958  {
2959  case CMSG_TYPE_PARAM:
2960  ret = CRYPT_CopyParam(pvData, pcbData, &msg->type, sizeof(msg->type));
2961  break;
2962  case CMSG_CONTENT_PARAM:
2963  if (msg->u.enveloped_data.data)
2965  msg->u.enveloped_data.content.pbData,
2966  msg->u.enveloped_data.content.cbData);
2967  else
2969  break;
2971  if (msg->u.enveloped_data.data)
2973  &msg->u.enveloped_data.data->cRecipientInfo, sizeof(DWORD));
2974  else
2976  break;
2978  if (msg->u.enveloped_data.data)
2979  {
2980  if (dwIndex < msg->u.enveloped_data.data->cRecipientInfo)
2981  {
2982  PCMSG_KEY_TRANS_RECIPIENT_INFO recipientInfo =
2983  &msg->u.enveloped_data.data->rgRecipientInfo[dwIndex];
2984 
2986  &recipientInfo->RecipientId.u.IssuerSerialNumber);
2987  }
2988  else
2990  }
2991  else
2993  break;
2994  default:
2995  FIXME("unimplemented for %d\n", dwParamType);
2997  }
2998  return ret;
2999 }
3000 
3002  DWORD dwIndex, void *pvData, DWORD *pcbData)
3003 {
3004  BOOL ret = FALSE;
3005 
3006  switch (dwParamType)
3007  {
3008  case CMSG_TYPE_PARAM:
3009  ret = CRYPT_CopyParam(pvData, pcbData, &msg->type, sizeof(msg->type));
3010  break;
3011  case CMSG_CONTENT_PARAM:
3012  if (msg->u.signed_data.info)
3013  {
3014  if (!strcmp(msg->u.signed_data.info->content.pszObjId,
3015  szOID_RSA_data))
3016  {
3018  DWORD size;
3019 
3021  msg->u.signed_data.info->content.Content.pbData,
3022  msg->u.signed_data.info->content.Content.cbData,
3024  if (ret)
3025  {
3026  ret = CRYPT_CopyParam(pvData, pcbData, blob->pbData,
3027  blob->cbData);
3028  LocalFree(blob);
3029  }
3030  }
3031  else
3033  msg->u.signed_data.info->content.Content.pbData,
3034  msg->u.signed_data.info->content.Content.cbData);
3035  }
3036  else
3038  break;
3040  if (msg->u.signed_data.info)
3042  msg->u.signed_data.info->content.pszObjId,
3043  strlen(msg->u.signed_data.info->content.pszObjId) + 1);
3044  else
3046  break;
3048  if (msg->u.signed_data.info)
3050  &msg->u.signed_data.info->cSignerInfo, sizeof(DWORD));
3051  else
3053  break;
3055  if (msg->u.signed_data.info)
3056  {
3057  if (dwIndex >= msg->u.signed_data.info->cSignerInfo)
3059  else
3061  &msg->u.signed_data.info->rgSignerInfo[dwIndex]);
3062  }
3063  else
3065  break;
3067  if (msg->u.signed_data.info)
3068  {
3069  if (dwIndex >= msg->u.signed_data.info->cSignerInfo)
3071  else
3073  &msg->u.signed_data.info->rgSignerInfo[dwIndex]);
3074  }
3075  else
3077  break;
3078  case CMSG_CERT_COUNT_PARAM:
3079  if (msg->u.signed_data.info)
3081  &msg->u.signed_data.info->cCertEncoded, sizeof(DWORD));
3082  else
3084  break;
3085  case CMSG_CERT_PARAM:
3086  if (msg->u.signed_data.info)
3087  {
3088  if (dwIndex >= msg->u.signed_data.info->cCertEncoded)
3090  else
3092  msg->u.signed_data.info->rgCertEncoded[dwIndex].pbData,
3093  msg->u.signed_data.info->rgCertEncoded[dwIndex].cbData);
3094  }
3095  else
3097  break;
3098  case CMSG_CRL_COUNT_PARAM:
3099  if (msg->u.signed_data.info)
3101  &msg->u.signed_data.info->cCrlEncoded, sizeof(DWORD));
3102  else
3104  break;
3105  case CMSG_CRL_PARAM:
3106  if (msg->u.signed_data.info)
3107  {
3108  if (dwIndex >= msg->u.signed_data.info->cCrlEncoded)
3110  else
3112  msg->u.signed_data.info->rgCrlEncoded[dwIndex].pbData,
3113  msg->u.signed_data.info->rgCrlEncoded[dwIndex].cbData);
3114  }
3115  else
3117  break;
3119  if (msg->u.signed_data.info)
3120  {
3121  if (dwIndex >= msg->u.signed_data.cSignerHandle)
3123  else
3125  msg->u.signed_data.signerHandles[dwIndex].contentHash,
3126  HP_HASHVAL, pvData, pcbData, 0);
3127  }
3128  else
3130  break;
3131  case CMSG_ENCODED_SIGNER:
3132  if (msg->u.signed_data.info)
3133  {
3134  if (dwIndex >= msg->u.signed_data.info->cSignerInfo)
3136  else
3139  &msg->u.signed_data.info->rgSignerInfo[dwIndex], 0, NULL,
3140  pvData, pcbData);
3141  }
3142  else
3144  break;
3146  if (msg->u.signed_data.info)
3147  {
3148  DWORD attrCertCount = 0;
3149 
3151  &attrCertCount, sizeof(DWORD));
3152  }
3153  else
3155  break;
3156  case CMSG_ATTR_CERT_PARAM:
3157  if (msg->u.signed_data.info)
3159  else
3161  break;
3163  if (msg->u.signed_data.info)
3164  {
3165  if (dwIndex >= msg->u.signed_data.info->cSignerInfo)
3167  else
3169  &msg->u.signed_data.info->rgSignerInfo[dwIndex]);
3170  }
3171  else
3173  break;
3174  default:
3175  FIXME("unimplemented for %d\n", dwParamType);
3177  }
3178  return ret;
3179 }
3180 
3181 static BOOL CDecodeMsg_GetParam(HCRYPTMSG hCryptMsg, DWORD dwParamType,
3182  DWORD dwIndex, void *pvData, DWORD *pcbData)
3183 {
3184  CDecodeMsg *msg = hCryptMsg;
3185  BOOL ret = FALSE;
3186 
3187  switch (msg->type)
3188  {
3189  case CMSG_HASHED:
3190  ret = CDecodeHashMsg_GetParam(msg, dwParamType, dwIndex, pvData,
3191  pcbData);
3192  break;
3193  case CMSG_ENVELOPED:
3194  ret = CDecodeEnvelopedMsg_GetParam(msg, dwParamType, dwIndex, pvData,
3195  pcbData);
3196  break;
3197  case CMSG_SIGNED:
3198  ret = CDecodeSignedMsg_GetParam(msg, dwParamType, dwIndex, pvData,
3199  pcbData);
3200  break;
3201  default:
3202  switch (dwParamType)
3203  {
3204  case CMSG_TYPE_PARAM:
3205  ret = CRYPT_CopyParam(pvData, pcbData, &msg->type,
3206  sizeof(msg->type));
3207  break;
3208  default:
3209  {
3211 
3212  ret = ContextPropertyList_FindProperty(msg->properties, dwParamType,
3213  &blob);
3214  if (ret)
3215  ret = CRYPT_CopyParam(pvData, pcbData, blob.pbData,
3216  blob.cbData);
3217  else
3219  }
3220  }
3221  }
3222  return ret;
3223 }
3224 
3226 {
3227  BOOL ret;
3229 
3232  if (ret)
3233  {
3234  DWORD computedHashSize = 0;
3235 
3237  &computedHashSize);
3238  if (hashBlob.cbData == computedHashSize)
3239  {
3240  LPBYTE computedHash = CryptMemAlloc(computedHashSize);
3241 
3242  if (computedHash)
3243  {
3245  computedHash, &computedHashSize);
3246  if (ret)
3247  {
3248  if (memcmp(hashBlob.pbData, computedHash, hashBlob.cbData))
3249  {
3251  ret = FALSE;
3252  }
3253  }
3254  CryptMemFree(computedHash);
3255  }
3256  else
3257  {
3259  ret = FALSE;
3260  }
3261  }
3262  else
3263  {
3265  ret = FALSE;
3266  }
3267  }
3268  return ret;
3269 }
3270 
3272  HCRYPTPROV prov, DWORD signerIndex, PCERT_PUBLIC_KEY_INFO keyInfo)
3273 {
3274  HCRYPTKEY key;
3275  BOOL ret;
3276 
3277  if (!prov)
3278  prov = msg->crypt_prov;
3279  ret = CryptImportPublicKeyInfo(prov, X509_ASN_ENCODING, keyInfo, &key);
3280  if (ret)
3281  {
3282  HCRYPTHASH hash;
3283  CRYPT_HASH_BLOB reversedHash;
3284 
3285  if (msg->u.signed_data.info->rgSignerInfo[signerIndex].AuthAttrs.cAttr)
3286  hash = msg->u.signed_data.signerHandles[signerIndex].authAttrHash;
3287  else
3288  hash = msg->u.signed_data.signerHandles[signerIndex].contentHash;
3289  ret = CRYPT_ConstructBlob(&reversedHash,
3290  &msg->u.signed_data.info->rgSignerInfo[signerIndex].EncryptedHash);
3291  if (ret)
3292  {
3293  CRYPT_ReverseBytes(&reversedHash);
3294  ret = CryptVerifySignatureW(hash, reversedHash.pbData,
3295  reversedHash.cbData, key, NULL, 0);
3296  CryptMemFree(reversedHash.pbData);
3297  }
3299  }
3300  return ret;
3301 }
3302 
3304 {
3305  BOOL ret = FALSE;
3306  DWORD i;
3307 
3308  if (!msg->u.signed_data.signerHandles)
3309  {
3311  return FALSE;
3312  }
3313  for (i = 0; !ret && i < msg->u.signed_data.info->cSignerInfo; i++)
3314  {
3315  PCMSG_CMS_SIGNER_INFO signerInfo =
3316  &msg->u.signed_data.info->rgSignerInfo[i];
3317 
3319  {
3321  &signerInfo->SignerId.u.IssuerSerialNumber.Issuer,
3322  &info->Issuer);
3323  if (ret)
3324  {
3326  &signerInfo->SignerId.u.IssuerSerialNumber.SerialNumber,
3327  &info->SerialNumber);
3328  if (ret)
3329  break;
3330  }
3331  }
3332  else
3333  {
3334  FIXME("signer %d: unimplemented for key id\n", i);
3335  }
3336  }
3337  if (ret)
3339  &info->SubjectPublicKeyInfo);
3340  else
3342 
3343  return ret;
3344 }
3345 
3348 {
3349  BOOL ret = FALSE;
3350 
3351  if (para->cbSize != sizeof(CMSG_CTRL_VERIFY_SIGNATURE_EX_PARA))
3353  else if (para->dwSignerIndex >= msg->u.signed_data.info->cSignerInfo)
3355  else if (!msg->u.signed_data.signerHandles)
3357  else
3358  {
3359  switch (para->dwSignerType)
3360  {
3363  para->hCryptProv, para->dwSignerIndex, para->pvSigner);
3364  break;
3366  {
3367  PCCERT_CONTEXT cert = para->pvSigner;
3368 
3370  para->dwSignerIndex, &cert->pCertInfo->SubjectPublicKeyInfo);
3371  break;
3372  }
3373  default:
3374  FIXME("unimplemented for signer type %d\n", para->dwSignerType);
3376  }
3377  }
3378  return ret;
3379 }
3380 
3382  PCRYPT_ALGORITHM_IDENTIFIER pContentEncryptionAlgorithm,
3383  PCMSG_CTRL_KEY_TRANS_DECRYPT_PARA pKeyTransDecryptPara, DWORD dwFlags,
3384  void *pvReserved, HCRYPTKEY *phContentEncryptKey)
3385 {
3386  BOOL ret;
3387  HCRYPTKEY key;
3388 
3389  ret = CryptGetUserKey(pKeyTransDecryptPara->hCryptProv,
3390  pKeyTransDecryptPara->dwKeySpec ? pKeyTransDecryptPara->dwKeySpec :
3391  AT_KEYEXCHANGE, &key);
3392  if (ret)
3393  {
3395  &pKeyTransDecryptPara->pKeyTrans[pKeyTransDecryptPara->dwRecipientIndex];
3396  CRYPT_DATA_BLOB *encryptedKey = &info->EncryptedKey;
3397  DWORD size = encryptedKey->cbData + sizeof(BLOBHEADER) + sizeof(ALG_ID);
3398  BYTE *keyBlob = CryptMemAlloc(size);
3399 
3400  if (keyBlob)
3401  {
3402  DWORD i, k = size - 1;
3403  BLOBHEADER *blobHeader = (BLOBHEADER *)keyBlob;
3404  ALG_ID *algID = (ALG_ID *)(keyBlob + sizeof(BLOBHEADER));
3405 
3406  blobHeader->bType = SIMPLEBLOB;
3407  blobHeader->bVersion = CUR_BLOB_VERSION;
3408  blobHeader->reserved = 0;
3409  blobHeader->aiKeyAlg = CertOIDToAlgId(
3410  pContentEncryptionAlgorithm->pszObjId);
3411  *algID = CertOIDToAlgId(info->KeyEncryptionAlgorithm.pszObjId);
3412  for (i = 0; i < encryptedKey->cbData; ++i, --k)
3413  keyBlob[k] = encryptedKey->pbData[i];
3414 
3415  ret = CryptImportKey(pKeyTransDecryptPara->hCryptProv, keyBlob,
3416  size, key, 0, phContentEncryptKey);
3417  CryptMemFree(keyBlob);
3418  }
3419  else
3420  ret = FALSE;
3422  }
3423  return ret;
3424 }
3425 
3428  HCRYPTKEY *key)
3429 {
3430  static HCRYPTOIDFUNCSET set = NULL;
3431  PFN_CMSG_IMPORT_KEY_TRANS importKeyFunc = NULL;
3432  HCRYPTOIDFUNCADDR hFunc = NULL;
3434  BOOL ret;
3435 
3436  memset(&decryptPara, 0, sizeof(decryptPara));
3437  decryptPara.cbSize = sizeof(decryptPara);
3438  decryptPara.hCryptProv = para->hCryptProv;
3439  decryptPara.dwKeySpec = para->dwKeySpec;
3440  decryptPara.pKeyTrans = info;
3441  decryptPara.dwRecipientIndex = para->dwRecipientIndex;
3442 
3443  if (!set)
3446  (void **)&importKeyFunc, &hFunc);
3447  if (!importKeyFunc)
3448  importKeyFunc = CRYPT_ImportKeyTrans;
3449  ret = importKeyFunc(contEncrAlg, &decryptPara, 0, NULL, key);
3450  if (hFunc)
3451  CryptFreeOIDFunctionAddress(hFunc, 0);
3452  return ret;
3453 }
3454 
3457 {
3458  BOOL ret = FALSE;
3459  CEnvelopedDecodeMsg *enveloped_data = &msg->u.enveloped_data;
3460  CRYPT_ENVELOPED_DATA *data = enveloped_data->data;
3461 
3462  if (para->cbSize != sizeof(CMSG_CTRL_DECRYPT_PARA))
3464  else if (!data)
3466  else if (para->dwRecipientIndex >= data->cRecipientInfo)
3468  else if (enveloped_data->decrypted)
3470  else if (!para->hCryptProv)
3472  else if (enveloped_data->content.cbData)
3473  {
3474  HCRYPTKEY key;
3475 
3477  &data->encryptedContentInfo.contentEncryptionAlgorithm, para,
3478  data->rgRecipientInfo, &key);
3479  if (ret)
3480  {
3481  ret = CryptDecrypt(key, 0, TRUE, 0, enveloped_data->content.pbData,
3482  &enveloped_data->content.cbData);
3484  }
3485  }
3486  else
3487  ret = TRUE;
3488  if (ret)
3489  enveloped_data->decrypted = TRUE;
3490  return ret;
3491 }
3492 
3494  DWORD dwCtrlType, const void *pvCtrlPara)
3495 {
3496  CDecodeMsg *msg = hCryptMsg;
3497  BOOL ret = FALSE;
3498 
3499  switch (dwCtrlType)
3500  {
3502  switch (msg->type)
3503  {
3504  case CMSG_SIGNED:
3506  break;
3507  default:
3509  }
3510  break;
3511  case CMSG_CTRL_DECRYPT:
3512  switch (msg->type)
3513  {
3514  case CMSG_ENVELOPED:
3516  (PCMSG_CTRL_DECRYPT_PARA)pvCtrlPara);
3518  msg->u.enveloped_data.crypt_prov =
3519  ((PCMSG_CTRL_DECRYPT_PARA)pvCtrlPara)->hCryptProv;
3520  break;
3521  default:
3523  }
3524  break;
3525  case CMSG_CTRL_VERIFY_HASH:
3526  switch (msg->type)
3527  {
3528  case CMSG_HASHED:
3530  break;
3531  default:
3533  }
3534  break;
3536  switch (msg->type)
3537  {
3538  case CMSG_SIGNED:
3541  break;
3542  default:
3544  }
3545  break;
3546  default:
3548  }
3549  return ret;
3550 }
3551 
3553  DWORD dwMsgType, HCRYPTPROV_LEGACY hCryptProv, PCERT_INFO pRecipientInfo,
3554  PCMSG_STREAM_INFO pStreamInfo)
3555 {
3556  CDecodeMsg *msg;
3557 
3558  TRACE("(%08x, %08x, %08x, %08lx, %p, %p)\n", dwMsgEncodingType,
3559  dwFlags, dwMsgType, hCryptProv, pRecipientInfo, pStreamInfo);
3560 
3561  if (GET_CMSG_ENCODING_TYPE(dwMsgEncodingType) != PKCS_7_ASN_ENCODING)
3562  {
3564  return NULL;
3565  }
3566  msg = CryptMemAlloc(sizeof(CDecodeMsg));
3567  if (msg)
3568  {
3569  CryptMsgBase_Init((CryptMsgBase *)msg, dwFlags, pStreamInfo,
3572  msg->type = dwMsgType;
3573  msg->crypt_prov = hCryptProv;
3574  memset(&msg->u, 0, sizeof(msg->u));
3575  msg->msg_data.cbData = 0;
3576  msg->msg_data.pbData = NULL;
3577  msg->detached_data.cbData = 0;
3578  msg->detached_data.pbData = NULL;
3579  msg->properties = ContextPropertyList_Create();
3580  }
3581  return msg;
3582 }
3583 
3585 {
3586  TRACE("(%p)\n", hCryptMsg);
3587 
3588  if (hCryptMsg)
3589  {
3590  CryptMsgBase *msg = hCryptMsg;
3591 
3592  InterlockedIncrement(&msg->ref);
3593  }
3594  return hCryptMsg;
3595 }
3596 
3598 {
3599  TRACE("(%p)\n", hCryptMsg);
3600 
3601  if (hCryptMsg)
3602  {
3603  CryptMsgBase *msg = hCryptMsg;
3604 
3605  if (InterlockedDecrement(&msg->ref) == 0)
3606  {
3607  TRACE("freeing %p\n", msg);
3608  if (msg->close)
3609  msg->close(msg);
3610  CryptMemFree(msg);
3611  }
3612  }
3613  return TRUE;
3614 }
3615 
3617  DWORD cbData, BOOL fFinal)
3618 {
3619  CryptMsgBase *msg = hCryptMsg;
3620 
3621  TRACE("(%p, %p, %d, %d)\n", hCryptMsg, pbData, cbData, fFinal);
3622 
3623  return msg->update(hCryptMsg, pbData, cbData, fFinal);
3624 }
3625 
3626 BOOL WINAPI CryptMsgGetParam(HCRYPTMSG hCryptMsg, DWORD dwParamType,
3627  DWORD dwIndex, void *pvData, DWORD *pcbData)
3628 {
3629  CryptMsgBase *msg = hCryptMsg;
3630 
3631  TRACE("(%p, %d, %d, %p, %p)\n", hCryptMsg, dwParamType, dwIndex,
3632  pvData, pcbData);
3633  return msg->get_param(hCryptMsg, dwParamType, dwIndex, pvData, pcbData);
3634 }
3635 
3637  DWORD dwCtrlType, const void *pvCtrlPara)
3638 {
3639  CryptMsgBase *msg = hCryptMsg;
3640 
3641  TRACE("(%p, %08x, %d, %p)\n", hCryptMsg, dwFlags, dwCtrlType,
3642  pvCtrlPara);
3643  return msg->control(hCryptMsg, dwFlags, dwCtrlType, pvCtrlPara);
3644 }
3645 
3647  DWORD dwSignerIndex)
3648 {
3649  CERT_INFO *certInfo = NULL;
3650  DWORD size;
3651 
3653  &size))
3654  {
3655  certInfo = CryptMemAlloc(size);
3656  if (certInfo)
3657  {
3659  dwSignerIndex, certInfo, &size))
3660  {
3661  CryptMemFree(certInfo);
3662  certInfo = NULL;
3663  }
3664  }
3665  }
3666  return certInfo;
3667 }
3668 
3670  HCERTSTORE *rghSignerStore, DWORD dwFlags, PCCERT_CONTEXT *ppSigner,
3672 {
3673  HCERTSTORE store;
3674  DWORD i, signerIndex = 0;
3675  PCCERT_CONTEXT signerCert = NULL;
3676  BOOL ret = FALSE;
3677 
3678  TRACE("(%p, %d, %p, %08x, %p, %p)\n", hCryptMsg, cSignerStore,
3679  rghSignerStore, dwFlags, ppSigner, pdwSignerIndex);
3680 
3681  /* Clear output parameters */
3682  if (ppSigner)
3683  *ppSigner = NULL;
3685  *pdwSignerIndex = 0;
3686 
3687  /* Create store to search for signer certificates */
3691  {
3692  HCERTSTORE msgStore = CertOpenStore(CERT_STORE_PROV_MSG, 0, 0, 0,
3693  hCryptMsg);
3694 
3695  CertAddStoreToCollection(store, msgStore, 0, 0);
3696  CertCloseStore(msgStore, 0);
3697  }
3698  for (i = 0; i < cSignerStore; i++)
3699  CertAddStoreToCollection(store, rghSignerStore[i], 0, 0);
3700 
3701  /* Find signer cert */
3703  {
3704  CERT_INFO *signer = CRYPT_GetSignerCertInfoFromMsg(hCryptMsg,
3705  *pdwSignerIndex);
3706 
3707  if (signer)
3708  {
3709  signerIndex = *pdwSignerIndex;
3710  signerCert = CertFindCertificateInStore(store, X509_ASN_ENCODING,
3711  0, CERT_FIND_SUBJECT_CERT, signer, NULL);
3712  CryptMemFree(signer);
3713  }
3714  }
3715  else
3716  {
3717  DWORD count, size = sizeof(count);
3718 
3719  if (CryptMsgGetParam(hCryptMsg, CMSG_SIGNER_COUNT_PARAM, 0, &count,
3720  &size))
3721  {
3722  for (i = 0; !signerCert && i < count; i++)
3723  {
3724  CERT_INFO *signer = CRYPT_GetSignerCertInfoFromMsg(hCryptMsg,
3725  i);
3726 
3727  if (signer)
3728  {
3729  signerCert = CertFindCertificateInStore(store,
3731  NULL);
3732  if (signerCert)
3733  signerIndex = i;
3734  CryptMemFree(signer);
3735  }
3736  }
3737  }
3738  if (!signerCert)
3740  }
3741  if (signerCert)
3742  {
3743  if (!(dwFlags & CMSG_SIGNER_ONLY_FLAG))
3745  signerCert->pCertInfo);
3746  else
3747  ret = TRUE;
3748  if (ret)
3749  {
3750  if (ppSigner)
3752  if (pdwSignerIndex)
3753  *pdwSignerIndex = signerIndex;
3754  }
3755  CertFreeCertificateContext(signerCert);
3756  }
3757 
3758  CertCloseStore(store, 0);
3759  return ret;
3760 }
3761 
3763  DWORD dwEncodingType, BYTE *pbSignerInfo, DWORD cbSignerInfo,
3764  PBYTE pbSignerInfoCountersignature, DWORD cbSignerInfoCountersignature,
3765  CERT_INFO *pciCountersigner)
3766 {
3767  FIXME("(%08lx, %08x, %p, %d, %p, %d, %p): stub\n", hCryptProv,
3768  dwEncodingType, pbSignerInfo, cbSignerInfo, pbSignerInfoCountersignature,
3769  cbSignerInfoCountersignature, pciCountersigner);
3770  return FALSE;
3771 }
3772 
3774  DWORD dwEncodingType, PBYTE pbSignerInfo, DWORD cbSignerInfo,
3775  PBYTE pbSignerInfoCountersignature, DWORD cbSignerInfoCountersignature,
3776  DWORD dwSignerType, void *pvSigner, DWORD dwFlags, void *pvReserved)
3777 {
3778  FIXME("(%08lx, %08x, %p, %d, %p, %d, %d, %p, %08x, %p): stub\n", hCryptProv,
3779  dwEncodingType, pbSignerInfo, cbSignerInfo, pbSignerInfoCountersignature,
3780  cbSignerInfoCountersignature, dwSignerType, pvSigner, dwFlags, pvReserved);
3781  return FALSE;
3782 }
3783 
3785  PCTL_INFO pCtlInfo, PCMSG_SIGNED_ENCODE_INFO pSignInfo, DWORD dwFlags,
3787 {
3788  BOOL ret;
3789  BYTE *pbCtlContent;
3790  DWORD cbCtlContent;
3791 
3792  TRACE("(%08x, %p, %p, %08x, %p, %p)\n", dwMsgEncodingType, pCtlInfo,
3793  pSignInfo, dwFlags, pbEncoded, pcbEncoded);
3794 
3795  if (dwFlags)
3796  {
3797  FIXME("unimplemented for flags %08x\n", dwFlags);
3798  return FALSE;
3799  }
3800  if ((ret = CryptEncodeObjectEx(dwMsgEncodingType, PKCS_CTL, pCtlInfo,
3801  CRYPT_ENCODE_ALLOC_FLAG, NULL, &pbCtlContent, &cbCtlContent)))
3802  {
3803  ret = CryptMsgSignCTL(dwMsgEncodingType, pbCtlContent, cbCtlContent,
3804  pSignInfo, dwFlags, pbEncoded, pcbEncoded);
3805  LocalFree(pbCtlContent);
3806  }
3807  return ret;
3808 }
3809 
3810 BOOL WINAPI CryptMsgSignCTL(DWORD dwMsgEncodingType, BYTE *pbCtlContent,
3811  DWORD cbCtlContent, PCMSG_SIGNED_ENCODE_INFO pSignInfo, DWORD dwFlags,
3813 {
3814  static char oid_ctl[] = szOID_CTL;
3815  BOOL ret;
3816  HCRYPTMSG msg;
3817 
3818  TRACE("(%08x, %p, %d, %p, %08x, %p, %p)\n", dwMsgEncodingType,
3819  pbCtlContent, cbCtlContent, pSignInfo, dwFlags, pbEncoded, pcbEncoded);
3820 
3821  if (dwFlags)
3822  {
3823  FIXME("unimplemented for flags %08x\n", dwFlags);
3824  return FALSE;
3825  }
3826  msg = CryptMsgOpenToEncode(dwMsgEncodingType, 0, CMSG_SIGNED, pSignInfo,
3827  oid_ctl, NULL);
3828  if (msg)
3829  {
3830  ret = CryptMsgUpdate(msg, pbCtlContent, cbCtlContent, TRUE);
3831  if (ret)
3833  pcbEncoded);
3834  CryptMsgClose(msg);
3835  }
3836  else
3837  ret = FALSE;
3838  return ret;
3839 }
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:2079
HCRYPTPROV prov
Definition: msg.c:1505
HCRYPTHASH contentHash
Definition: msg.c:913
HCRYPTMSG WINAPI CryptMsgDuplicate(HCRYPTMSG hCryptMsg)
Definition: msg.c:3584
static void CRecipientInfo_Free(CMSG_KEY_TRANS_RECIPIENT_INFO *info)
Definition: msg.c:1789
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:5775
#define CRYPT_E_MSG_ERROR
Definition: winerror.h:2985
static BOOL CDecodeMsg_DecodeSignedContent(CDecodeMsg *msg, const CRYPT_DER_BLOB *blob)
Definition: msg.c:2263
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:2078
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:2093
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:3455
#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:2602
#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:1742
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
union _CDecodeMsg::@345 u
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:1670
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:3646
struct _CSignedEncodeMsg CSignedEncodeMsg
#define CMSG_CTRL_VERIFY_SIGNATURE_EX
Definition: wincrypt.h:3885
static VOID WINAPI mem_free(LPVOID pv)
Definition: msg.c:1675
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:5773
#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:2728
#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:2205
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
#define CERT_STORE_PROV_COLLECTION
Definition: wincrypt.h:2261
static BOOL CRYPT_EncodePKCSDigestedData(CHashEncodeMsg *msg, void *pvData, DWORD *pcbData)
Definition: msg.c:391
#define szOID_RSA_hashedData
Definition: wincrypt.h:3033