Exemple #1
0
        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);
        }
Exemple #2
0
        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);
        }
Exemple #3
0
        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);
                }
            }
        }
Exemple #4
0
        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);
                }
            }
        }
Exemple #5
0
        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);
            }
        }