private unsafe static CMSG_SIGNER_ENCODE_INFO CreateSignerInfo( CmsSigner cmsSigner, CngKey privateKey, HeapBlockRetainer hb) { var signerInfo = new CMSG_SIGNER_ENCODE_INFO(); signerInfo.cbSize = (uint)Marshal.SizeOf(signerInfo); signerInfo.pCertInfo = Marshal.PtrToStructure <CERT_CONTEXT>(cmsSigner.Certificate.Handle).pCertInfo; signerInfo.hCryptProvOrhNCryptKey = privateKey.Handle.DangerousGetHandle(); signerInfo.HashAlgorithm.pszObjId = cmsSigner.DigestAlgorithm.Value; if (cmsSigner.SignerIdentifierType == SubjectIdentifierType.SubjectKeyIdentifier) { var certContextHandle = IntPtr.Zero; try { certContextHandle = NativeMethods.CertDuplicateCertificateContext(cmsSigner.Certificate.Handle); uint cbData = 0; var pbData = IntPtr.Zero; ThrowIfFailed(NativeMethods.CertGetCertificateContextProperty( certContextHandle, NativeMethods.CERT_KEY_IDENTIFIER_PROP_ID, pbData, ref cbData)); if (cbData > 0) { pbData = hb.Alloc((int)cbData); ThrowIfFailed(NativeMethods.CertGetCertificateContextProperty( certContextHandle, NativeMethods.CERT_KEY_IDENTIFIER_PROP_ID, pbData, ref cbData)); signerInfo.SignerId.dwIdChoice = NativeMethods.CERT_ID_KEY_IDENTIFIER; signerInfo.SignerId.KeyId.cbData = cbData; signerInfo.SignerId.KeyId.pbData = pbData; } } finally { if (certContextHandle != IntPtr.Zero) { NativeMethods.CertFreeCertificateContext(certContextHandle); } } } if (cmsSigner.SignedAttributes.Count != 0) { signerInfo.cAuthAttr = cmsSigner.SignedAttributes.Count; checked { var attributeSize = Marshal.SizeOf <CRYPT_ATTRIBUTE>(); var blobSize = Marshal.SizeOf <CRYPT_INTEGER_BLOB>(); var attributesArray = (CRYPT_ATTRIBUTE *)hb.Alloc(attributeSize * cmsSigner.SignedAttributes.Count); var currentAttribute = attributesArray; foreach (var attribute in cmsSigner.SignedAttributes) { currentAttribute->pszObjId = hb.AllocAsciiString(attribute.Oid.Value); currentAttribute->cValue = (uint)attribute.Values.Count; currentAttribute->rgValue = hb.Alloc(blobSize); foreach (var value in attribute.Values) { var attrData = value.RawData; if (attrData.Length > 0) { var blob = (CRYPT_INTEGER_BLOB *)currentAttribute->rgValue; blob->cbData = (uint)attrData.Length; blob->pbData = hb.Alloc(value.RawData.Length); Marshal.Copy(attrData, 0, blob->pbData, attrData.Length); } } currentAttribute++; } signerInfo.rgAuthAttr = new IntPtr(attributesArray); } } return(signerInfo); }
public static extern bool CryptMsgCountersign( SafeCryptMsgHandle hCryptMsg, uint dwIndex, int cCountersigners, CMSG_SIGNER_ENCODE_INFO rgCountersigners);