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)); } } }
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); } } }
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; } }
/// <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; } } } }
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)); } } } }