Beispiel #1
0
        public static DateTimeOffset?DecodeAuthenticodeTimestamp(AsnEncodedData data)
        {
            if (data.Oid.Value != KnownOids.SigningTime)
            {
                throw new ArgumentException("Data is not a signing time object.", nameof(data));
            }
            const EncodingType encodingType = EncodingType.PKCS_7_ASN_ENCODING | EncodingType.X509_ASN_ENCODING;

            unsafe
            {
                LocalBufferSafeHandle structBuffer;
                fixed(byte *buffer = data.RawData)
                {
                    uint size = 0;

                    if (!Crypt32.CryptDecodeObjectEx(encodingType, KnownOids.SigningTime, buffer, (uint)data.RawData.Length, CryptDecodeFlags.CRYPT_DECODE_ALLOC_FLAG, IntPtr.Zero, out structBuffer, ref size))
                    {
                        throw new InvalidOperationException("Failed to decode data.");
                    }
                }

                using (structBuffer)
                {
                    var  time        = Marshal.PtrToStructure <FILETIME>(structBuffer.DangerousGetHandle());
                    long fileTimeVal = (long)time.dwHighDateTime << 32 | (uint)time.dwLowDateTime;
                    return(DateTimeOffset.FromFileTime(fileTimeVal));
                }
            }
        }
Beispiel #2
0
        internal unsafe AuthenticodeTimestampCmsSignature(AsnEncodedData data, ICmsSignature owningSignature)
        {
            OwningSignature        = owningSignature;
            Kind                   = SignatureKind.AuthenticodeTimestamp;
            AdditionalCertificates = owningSignature.AdditionalCertificates;
            fixed(byte *dataPtr = data.RawData)
            {
                uint size = 0;

                if (Crypt32.CryptDecodeObjectEx(EncodingType.PKCS_7_ASN_ENCODING | EncodingType.X509_ASN_ENCODING, (IntPtr)500, new IntPtr(dataPtr), (uint)data.RawData.Length, CryptDecodeFlags.CRYPT_DECODE_ALLOC_FLAG, IntPtr.Zero, out var localBuffer, ref size))
                {
                    using (localBuffer)
                    {
                        var signerInfo = Marshal.PtrToStructure <CMSG_SIGNER_INFO>(localBuffer.DangerousGetHandle());
                        Signature               = ReadBlob(signerInfo.EncryptedHash);
                        DigestAlgorithm         = new Oid(signerInfo.HashAlgorithm.pszObjId);
                        HashEncryptionAlgorithm = new Oid(signerInfo.HashEncryptionAlgorithm.pszObjId);
                        SerialNumber            = ReadBlob(signerInfo.SerialNumber);
                        UnsignedAttributes      = ReadAttributes(signerInfo.UnauthAttrs);
                        SignedAttributes        = ReadAttributes(signerInfo.AuthAttrs);
                        var subjectId = new UniversalSubjectIdentifier(signerInfo.Issuer, signerInfo.SerialNumber);
                        if (subjectId.Type == SubjectIdentifierType.SubjectKeyIdentifier)
                        {
                            Certificate = FindCertificate((string)subjectId.Value, OwningSignature.AdditionalCertificates);
                        }
                        else if (subjectId.Type == SubjectIdentifierType.IssuerAndSerialNumber)
                        {
                            Certificate = FindCertificate((X509IssuerSerial)subjectId.Value, OwningSignature.AdditionalCertificates);
                        }
                    }
                }
Beispiel #3
0
        public UniversalSubjectIdentifier(CRYPTOAPI_BLOB issuer, CRYPTOAPI_BLOB serialNumber)
        {
            var allZeroSerial = IsBlobAllZero(serialNumber);

            if (allZeroSerial)
            {
                var  x500Name = LocalBufferSafeHandle.Zero;
                var  flags    = EncodingType.PKCS_7_ASN_ENCODING | EncodingType.X509_ASN_ENCODING;
                uint size     = 0;
                if (Crypt32.CryptDecodeObjectEx(flags, (IntPtr)7, issuer.pbData, issuer.cbData, CryptDecodeFlags.CRYPT_DECODE_ALLOC_FLAG, IntPtr.Zero, out x500Name, ref size))
                {
                    using (x500Name)
                    {
                        var info = Marshal.PtrToStructure <CERT_NAME_INFO>(x500Name.DangerousGetHandle());
                        for (var i = 0L; i < info.cRDN; i++)
                        {
                            var rdn = Marshal.PtrToStructure <CERT_RDN>(new IntPtr(info.rgRDN.ToInt64() + i * Marshal.SizeOf <CERT_RDN>()));
                            for (var j = 0; j < rdn.cRDNAttr; j++)
                            {
                                var attribute = Marshal.PtrToStructure <CERT_RDN_ATTR>(new IntPtr(rdn.rgRDNAttr.ToInt64() + j * Marshal.SizeOf <CERT_RDN_ATTR>()));
                                if (attribute.pszObjId == KnownOids.KeyId)
                                {
                                    Type = SubjectIdentifierType.SubjectKeyIdentifier;
                                    var ski = new byte[attribute.Value.cbData];
                                    Marshal.Copy(attribute.Value.pbData, ski, 0, ski.Length);
                                    Value = HashHelpers.HexEncodeBigEndian(ski);
                                    return;
                                }
                            }
                        }
                    }
                }
            }
            unsafe
            {
                var result = Crypt32.CertNameToStr(EncodingType.PKCS_7_ASN_ENCODING | EncodingType.X509_ASN_ENCODING, new IntPtr(&issuer), CertNameStrType.CERT_X500_NAME_STR | CertNameStrType.CERT_NAME_STR_REVERSE_FLAG, null, 0);
                if (result <= 1)
                {
                    throw new InvalidOperationException();
                }
                var builder = new StringBuilder((int)result);
                var final   = Crypt32.CertNameToStr(EncodingType.PKCS_7_ASN_ENCODING | EncodingType.X509_ASN_ENCODING, new IntPtr(&issuer), CertNameStrType.CERT_X500_NAME_STR | CertNameStrType.CERT_NAME_STR_REVERSE_FLAG, builder, result);
                if (final <= 1)
                {
                    throw new InvalidOperationException();
                }
                var serial = new byte[serialNumber.cbData];
                Marshal.Copy(serialNumber.pbData, serial, 0, serial.Length);
                var issuerSerial = new X509IssuerSerial();
                issuerSerial.IssuerName   = builder.ToString();
                issuerSerial.SerialNumber = HashHelpers.HexEncodeBigEndian(serial);
                Value = issuerSerial;
                Type  = SubjectIdentifierType.IssuerAndSerialNumber;
            }
        }
Beispiel #4
0
        /// <summary>
        /// Constructs a new instance of <see cref="PublisherInformation"/>
        /// from ASN.1 encoded data.
        /// </summary>
        /// <param name="data">The ASN.1 encoded data for the publisher information.</param>
        public PublisherInformation(AsnEncodedData data)
        {
            if (data.Oid.Value != KnownOids.OpusInfo)
            {
                throw new ArgumentException("Data is not a publisher information object.", nameof(data));
            }
            const EncodingType encodingType = EncodingType.PKCS_7_ASN_ENCODING | EncodingType.X509_ASN_ENCODING;

            unsafe
            {
                LocalBufferSafeHandle structBuffer;
                fixed(byte *buffer = data.RawData)
                {
                    uint size = 0;

                    if (!Crypt32.CryptDecodeObjectEx(encodingType, KnownOids.OpusInfo, buffer, (uint)data.RawData.Length, CryptDecodeFlags.CRYPT_DECODE_ALLOC_FLAG, IntPtr.Zero, out structBuffer, ref size))
                    {
                        throw new InvalidOperationException("Failed to decode data.");
                    }
                }

                using (structBuffer)
                {
                    var info = Marshal.PtrToStructure <SPC_SP_OPUS_INFO>(structBuffer.DangerousGetHandle());
                    Description = info.pwszProgramName?.Trim();
                    if (info.pMoreInfo == null)
                    {
                        return;
                    }

                    var moreInfo = info.pMoreInfo;
                    switch (moreInfo->dwLinkChoice)
                    {
                    case SpcLinkChoice.SPC_URL_LINK_CHOICE:
                        UrlLink = Marshal.PtrToStringUni(moreInfo->linkUnion.pwszUrl)?.Trim();
                        break;

                    case SpcLinkChoice.SPC_FILE_LINK_CHOICE:
                        FileLink = Marshal.PtrToStringUni(moreInfo->linkUnion.pwszFile)?.Trim();
                        break;
                    }
                }
            }
        }
Beispiel #5
0
        public static unsafe DateTimeOffset?DecodeRfc3161(byte[] content)
        {
            fixed(byte *contentPtr = content)
            {
                var sequenceSize = 0u;
                LocalBufferSafeHandle sequenceBuffer;

                if (!Crypt32.CryptDecodeObjectEx(EncodingType.PKCS_7_ASN_ENCODING | EncodingType.X509_ASN_ENCODING, (IntPtr)34, new IntPtr(contentPtr), (uint)content.Length, CryptDecodeFlags.CRYPT_DECODE_ALLOC_FLAG, IntPtr.Zero, out sequenceBuffer, ref sequenceSize))
                {
                    return(null);
                }

                using (sequenceBuffer)
                {
                    var sequenceStruct = Marshal.PtrToStructure <CRYPT_SEQUENCE_OF_ANY>(sequenceBuffer.DangerousGetHandle());
                    if (sequenceStruct.cValue < 5)
                    {
                        return(null);
                    }
                    var time     = sequenceStruct.rgValue[4];
                    var timeSize = 0u;
                    LocalBufferSafeHandle timeBuffer;
                    if (!Crypt32.CryptDecodeObjectEx(EncodingType.PKCS_7_ASN_ENCODING | EncodingType.X509_ASN_ENCODING, (IntPtr)30, time.pbData, time.cbData, CryptDecodeFlags.CRYPT_DECODE_ALLOC_FLAG, IntPtr.Zero, out timeBuffer, ref timeSize))
                    {
                        return(null);
                    }

                    using (timeBuffer)
                    {
                        var  fileTime    = Marshal.PtrToStructure <FILETIME>(timeBuffer.DangerousGetHandle());
                        long fileTimeVal = ((long)fileTime.dwHighDateTime) << 32 | (uint)fileTime.dwLowDateTime;
                        return(DateTimeOffset.FromFileTime(fileTimeVal));
                    }
                }
            }
        }