コード例 #1
0
        public IReadOnlyList <ISignature> Extract(string filePath)
        {
            EncodingType          encodingType;
            CryptQueryContentType contentType;
            CryptQueryFormatType  formatType;
            CryptMsgSafeHandle    message = CryptMsgSafeHandle.InvalidHandle;
            var result = Crypt32.CryptQueryObject(CryptQueryObjectType.CERT_QUERY_OBJECT_FILE, filePath, CryptQueryContentFlagType.CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED, CryptQueryFormatFlagType.CERT_QUERY_FORMAT_FLAG_BINARY, CryptQueryObjectFlags.NONE, out encodingType, out contentType, out formatType, IntPtr.Zero, out message, IntPtr.Zero);

            if (!result)
            {
                var resultCode = Marshal.GetLastWin32Error();
                switch (unchecked ((uint)resultCode))
                {
                case 0x80092009:     //Cannot find request object. There's no signature.
                    return(Array.Empty <ISignature>());

                default:
                    throw new Win32Exception(resultCode, "Failed to extract signature.");
                }
            }
            using (message)
            {
                if (message.IsInvalid || message.IsClosed)
                {
                    return(Array.Empty <ISignature>());
                }
                return(GetSignatures(message));
            }
        }
コード例 #2
0
        private static unsafe IReadOnlyList <ICmsSignature> GetSignatures(CryptMsgSafeHandle messageHandle)
        {
            var countSize = 0u;

            if (!Crypt32.CryptMsgGetParam(messageHandle, CryptMsgParamType.CMSG_SIGNER_COUNT_PARAM, 0, LocalBufferSafeHandle.Zero, ref countSize))
            {
                return(Array.Empty <ICmsSignature>());
            }
            uint signerCount;

            using (var countHandle = LocalBufferSafeHandle.Alloc(countSize))
            {
                if (!Crypt32.CryptMsgGetParam(messageHandle, CryptMsgParamType.CMSG_SIGNER_COUNT_PARAM, 0, countHandle, ref countSize))
                {
                    return(Array.Empty <ICmsSignature>());
                }
                signerCount = (uint)Marshal.ReadInt32(countHandle.DangerousGetHandle());
            }
            var signatures  = new List <ICmsSignature>();
            var contentSize = 0u;

            byte[] content = null;
            if (Crypt32.CryptMsgGetParam(messageHandle, CryptMsgParamType.CMSG_CONTENT_PARAM, 0, LocalBufferSafeHandle.Zero, ref contentSize))
            {
                using (var contentHandle = LocalBufferSafeHandle.Alloc(contentSize))
                {
                    if (Crypt32.CryptMsgGetParam(messageHandle, CryptMsgParamType.CMSG_CONTENT_PARAM, 0, contentHandle, ref contentSize))
                    {
                        content = new byte[contentSize];
                        Marshal.Copy(contentHandle.DangerousGetHandle(), content, 0, (int)contentSize);
                    }
                }
            }
            for (var i = 0u; i < signerCount; i++)
            {
                var signerSize = 0u;
                if (!Crypt32.CryptMsgGetParam(messageHandle, CryptMsgParamType.CMSG_SIGNER_INFO_PARAM, i, LocalBufferSafeHandle.Zero, ref signerSize))
                {
                    continue;
                }
                using (var signerHandle = LocalBufferSafeHandle.Alloc(signerSize))
                {
                    if (!Crypt32.CryptMsgGetParam(messageHandle, CryptMsgParamType.CMSG_SIGNER_INFO_PARAM, i, signerHandle, ref signerSize))
                    {
                        continue;
                    }
                    var signature = new CmsSignature(SignatureKind.Signature, messageHandle, signerHandle, content);
                    signatures.Add(signature);
                }
            }
            return(signatures.AsReadOnly());
        }
コード例 #3
0
        private void InitFromHandles(CryptMsgSafeHandle messageHandle, LocalBufferSafeHandle signerHandle)
        {
            var signerInfo = Marshal.PtrToStructure <CMSG_SIGNER_INFO>(signerHandle.DangerousGetHandle());
            var subjectId  = new UniversalSubjectIdentifier(signerInfo.Issuer, signerInfo.SerialNumber);
            var certs      = GetCertificatesFromMessage(messageHandle);

            if (subjectId.Type == SubjectIdentifierType.SubjectKeyIdentifier)
            {
                Certificate = FindCertificate((string)subjectId.Value, certs);
            }
            else if (subjectId.Type == SubjectIdentifierType.IssuerAndSerialNumber)
            {
                Certificate = FindCertificate((X509IssuerSerial)subjectId.Value, certs);
            }
            AdditionalCertificates  = certs;
            DigestAlgorithm         = new Oid(signerInfo.HashAlgorithm.pszObjId);
            HashEncryptionAlgorithm = new Oid(signerInfo.HashEncryptionAlgorithm.pszObjId);
            SerialNumber            = ReadBlob(signerInfo.SerialNumber);
            UnsignedAttributes      = ReadAttributes(signerInfo.UnauthAttrs);
            SignedAttributes        = ReadAttributes(signerInfo.AuthAttrs);
        }
コード例 #4
0
        internal X509Certificate2Collection GetCertificatesFromMessage(CryptMsgSafeHandle handle)
        {
            var  size  = (uint)Marshal.SizeOf <uint>();
            var  certs = new X509Certificate2Collection();
            uint certCount;

            using (var certCountLocalBuffer = LocalBufferSafeHandle.Alloc(size))
            {
                if (!Crypt32.CryptMsgGetParam(handle, CryptMsgParamType.CMSG_CERT_COUNT_PARAM, 0, certCountLocalBuffer, ref size))
                {
                    return(certs);
                }
                certCount = unchecked ((uint)Marshal.ReadInt32(certCountLocalBuffer.DangerousGetHandle(), 0));
            }
            if (certCount == 0)
            {
                return(certs);
            }
            for (var i = 0u; i < certCount; i++)
            {
                uint certSize = 0;
                if (!Crypt32.CryptMsgGetParam(handle, CryptMsgParamType.CMSG_CERT_PARAM, i, LocalBufferSafeHandle.Zero, ref certSize))
                {
                    continue;
                }
                using (var certLocalBuffer = LocalBufferSafeHandle.Alloc(certSize))
                {
                    if (!Crypt32.CryptMsgGetParam(handle, CryptMsgParamType.CMSG_CERT_PARAM, i, certLocalBuffer, ref certSize))
                    {
                        continue;
                    }
                    var data = new byte[certSize];
                    Marshal.Copy(certLocalBuffer.DangerousGetHandle(), data, 0, data.Length);
                    var cert = new X509Certificate2(data);
                    certs.Add(cert);
                }
            }
            return(certs);
        }
コード例 #5
0
 static CryptMsgSafeHandle()
 {
     InvalidHandle = new CryptMsgSafeHandle(true);
     InvalidHandle.SetHandleAsInvalid();
 }
コード例 #6
0
 internal Signature(SignatureKind kind, CryptMsgSafeHandle messageHandle, LocalBufferSafeHandle signerHandle)
 {
     Kind = kind;
     InitFromHandles(messageHandle, signerHandle);
 }