private byte[] GetByteArrayAttribute(CMSG_GETPARAM_TYPE param, uint index) { // Get the length of the attribute uint valueLength = 0; NativeUtils.ThrowIfFailed(NativeMethods.CryptMsgGetParam( _handle, param, index, null, ref valueLength)); // Now allocate some memory for it byte[] data = new byte[(int)valueLength]; // Get the actual digest NativeUtils.ThrowIfFailed(NativeMethods.CryptMsgGetParam( _handle, param, index, data, ref valueLength)); return(data); }
internal static SignedCms RequestTimestamp(byte[] data, string hashAlgorithmOid, Uri timestampingAuthorityUrl) { var para = new CRYPT_TIMESTAMP_PARA() { fRequestCerts = true }; IntPtr unmanagedContext = IntPtr.Zero; byte[] encodedResponse; try { NativeUtils.ThrowIfFailed(NativeMethods.CryptRetrieveTimeStamp( wszUrl: timestampingAuthorityUrl.ToString(), dwRetrievalFlags: NativeMethods.TIMESTAMP_VERIFY_CONTEXT_SIGNATURE, dwTimeout: 5 * 1000 /* 5 second timeout */, pszHashId: hashAlgorithmOid, pPara: ref para, pbData: data, cbData: (uint)data.Length, ppTsContext: out unmanagedContext, ppTsSigner: IntPtr.Zero, phStore: IntPtr.Zero)); // Copy the encoded response out var context = (CRYPT_TIMESTAMP_CONTEXT)Marshal.PtrToStructure(unmanagedContext, typeof(CRYPT_TIMESTAMP_CONTEXT)); encodedResponse = new byte[context.cbEncoded]; Marshal.Copy(context.pbEncoded, encodedResponse, 0, (int)context.cbEncoded); } finally { if (unmanagedContext != IntPtr.Zero) { NativeMethods.CryptMemFree(unmanagedContext); } } SignedCms cms = new SignedCms(); cms.Decode(encodedResponse); return(cms); }
public void AddCertificates(IEnumerable <byte[]> encodedCertificates) { foreach (var cert in encodedCertificates) { // Construct the blob IntPtr unmanagedCert = IntPtr.Zero; IntPtr unmanagedBlob = IntPtr.Zero; try { // Build blob holder unmanagedCert = Marshal.AllocHGlobal(cert.Length); Marshal.Copy(cert, 0, unmanagedCert, cert.Length); var blob = new CRYPT_INTEGER_BLOB_INTPTR() { cbData = (uint)cert.Length, pbData = unmanagedCert }; // Copy it to unmanaged memory unmanagedBlob = Marshal.AllocHGlobal(Marshal.SizeOf(blob)); Marshal.StructureToPtr(blob, unmanagedBlob, fDeleteOld: false); // Invoke the request if (!NativeMethods.CryptMsgControl( _handle, dwFlags: 0, dwCtrlType: CMSG_CONTROL_TYPE.CMSG_CTRL_ADD_CERT, pvCtrlPara: unmanagedBlob)) { Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); } } finally { NativeUtils.SafeFree(unmanagedCert); NativeUtils.SafeFree(unmanagedBlob); } } }
internal static TimeStampToken VerifyTimestamp(byte[] data, SignedCms timestampCms) { var signer = Signer.FromSignerInfo(timestampCms.SignerInfos[0]); bool trusted = signer.SignerCertificate.Verify(); var contentInfo = timestampCms.Encode(); IntPtr unmanagedContext = IntPtr.Zero; try { NativeUtils.ThrowIfFailed(NativeMethods.CryptVerifyTimeStampSignature( pbTSContentInfo: contentInfo, cbTSContentInfo: (uint)contentInfo.Length, pbData: data, cbData: (uint)data.Length, hAdditionalStore: IntPtr.Zero, ppTsContext: out unmanagedContext, ppTsSigner: IntPtr.Zero, phStore: IntPtr.Zero)); // Copy the context out var context = (CRYPT_TIMESTAMP_CONTEXT)Marshal.PtrToStructure(unmanagedContext, typeof(CRYPT_TIMESTAMP_CONTEXT)); // Copy the info out var info = (CRYPT_TIMESTAMP_INFO)Marshal.PtrToStructure(context.pTimeStamp, typeof(CRYPT_TIMESTAMP_INFO)); return(TimeStampToken.FromTimestampInfo(info, signer, trusted)); } finally { if (unmanagedContext != IntPtr.Zero) { NativeMethods.CryptMemFree(unmanagedContext); } } }
public void AddTimestamp(byte[] timeStampCms) { IntPtr unmanagedTimestamp = IntPtr.Zero; IntPtr unmanagedBlob = IntPtr.Zero; IntPtr unmanagedAttr = IntPtr.Zero; IntPtr unmanagedEncoded = IntPtr.Zero; IntPtr unmanagedAddAttr = IntPtr.Zero; try { // Wrap the timestamp in a CRYPT_INTEGER_BLOB and copy that to unmanaged memory unmanagedTimestamp = Marshal.AllocHGlobal(timeStampCms.Length); Marshal.Copy(timeStampCms, 0, unmanagedTimestamp, timeStampCms.Length); var blob = new CRYPT_INTEGER_BLOB_INTPTR() { cbData = (uint)timeStampCms.Length, pbData = unmanagedTimestamp }; unmanagedBlob = Marshal.AllocHGlobal(Marshal.SizeOf(blob)); Marshal.StructureToPtr(blob, unmanagedBlob, fDeleteOld: false); // Wrap it in a CRYPT_ATTRIBUTE and copy that too! var attr = new CRYPT_ATTRIBUTE() { pszObjId = Constants.SignatureTimeStampTokenAttributeOid.Value, cValue = 1, rgValue = unmanagedBlob }; unmanagedAttr = Marshal.AllocHGlobal(Marshal.SizeOf(attr)); Marshal.StructureToPtr(attr, unmanagedAttr, fDeleteOld: false); // Now encode the object using ye olde double-call-to-find-out-the-length mechanism :) uint encodedLength = 0; if (!NativeMethods.CryptEncodeObjectEx( dwCertEncodingType: NativeMethods.X509_ASN_ENCODING | NativeMethods.PKCS_7_ASN_ENCODING, lpszStructType: new IntPtr(NativeMethods.PKCS_ATTRIBUTE), pvStructInfo: unmanagedAttr, dwFlags: 0, pEncodePara: IntPtr.Zero, pvEncoded: IntPtr.Zero, pcbEncoded: ref encodedLength)) { var err = Marshal.GetLastWin32Error(); if (err != NativeMethods.ERROR_MORE_DATA) { Marshal.ThrowExceptionForHR(NativeMethods.GetHRForWin32Error(err)); } } unmanagedEncoded = Marshal.AllocHGlobal((int)encodedLength); if (!NativeMethods.CryptEncodeObjectEx( dwCertEncodingType: NativeMethods.X509_ASN_ENCODING | NativeMethods.PKCS_7_ASN_ENCODING, lpszStructType: new IntPtr(NativeMethods.PKCS_ATTRIBUTE), pvStructInfo: unmanagedAttr, dwFlags: 0, pEncodePara: IntPtr.Zero, pvEncoded: unmanagedEncoded, pcbEncoded: ref encodedLength)) { Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); } // Create the structure used to add the attribute var addAttr = new CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR_PARA() { dwSignerIndex = 0, BLOB = new CRYPT_INTEGER_BLOB_INTPTR() { cbData = encodedLength, pbData = unmanagedEncoded } }; addAttr.cbSize = (uint)Marshal.SizeOf(addAttr); unmanagedAddAttr = Marshal.AllocHGlobal(Marshal.SizeOf(addAttr)); Marshal.StructureToPtr(addAttr, unmanagedAddAttr, fDeleteOld: false); // Now store the timestamp in the message... FINALLY if (!NativeMethods.CryptMsgControl( _handle, dwFlags: 0, dwCtrlType: CMSG_CONTROL_TYPE.CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR, pvCtrlPara: unmanagedAddAttr)) { Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); } } finally { NativeUtils.SafeFree(unmanagedTimestamp); NativeUtils.SafeFree(unmanagedBlob); NativeUtils.SafeFree(unmanagedAttr); NativeUtils.SafeFree(unmanagedEncoded); NativeUtils.SafeFree(unmanagedAddAttr); } }