public static void TagMustBeCorrect_Custom(PublicEncodingRules ruleSet) { byte[] inputData = { 0x87, 2, 2, 4 }; AsnReader reader = new AsnReader(inputData, (AsnEncodingRules)ruleSet); AssertExtensions.Throws <ArgumentException>( "expectedTag", () => reader.GetNamedBitListValue <X509KeyUsageCSharpStyle>(Asn1Tag.Null)); Assert.True(reader.HasData, "HasData after bad universal tag"); Assert.Throws <CryptographicException>( () => reader.GetNamedBitListValue <X509KeyUsageCSharpStyle>()); Assert.True(reader.HasData, "HasData after default tag"); Assert.Throws <CryptographicException>( () => reader.GetNamedBitListValue <X509KeyUsageCSharpStyle>(new Asn1Tag(TagClass.Application, 0))); Assert.True(reader.HasData, "HasData after wrong custom class"); Assert.Throws <CryptographicException>( () => reader.GetNamedBitListValue <X509KeyUsageCSharpStyle>(new Asn1Tag(TagClass.ContextSpecific, 1))); Assert.True(reader.HasData, "HasData after wrong custom tag value"); Assert.Equal( X509KeyUsageCSharpStyle.KeyCertSign, reader.GetNamedBitListValue <X509KeyUsageCSharpStyle>(new Asn1Tag(TagClass.ContextSpecific, 7))); Assert.False(reader.HasData, "HasData after reading value"); }
public static void VerifyGenericReadNamedBitList(PublicEncodingRules ruleSet) { string inputHex = "0306078000000080" + "0309010000000080000002"; AsnReader reader = new AsnReader(inputHex.HexToByteArray(), (AsnEncodingRules)ruleSet); ULongFlags uLongFlags = reader.GetNamedBitListValue <ULongFlags>(); LongFlags longFlags = reader.GetNamedBitListValue <LongFlags>(); Assert.False(reader.HasData); Assert.Equal(ULongFlags.Mid | ULongFlags.Min, uLongFlags); Assert.Equal(LongFlags.Mid | LongFlags.Max, longFlags); }
public static void ExpectedTag_IgnoresConstructed( PublicEncodingRules ruleSet, string inputHex, PublicTagClass tagClass, int tagValue) { byte[] inputData = inputHex.HexToByteArray(); AsnReader reader = new AsnReader(inputData, (AsnEncodingRules)ruleSet); Assert.Equal( X509KeyUsageCSharpStyle.DecipherOnly, reader.GetNamedBitListValue <X509KeyUsageCSharpStyle>( new Asn1Tag((TagClass)tagClass, tagValue, true))); Assert.False(reader.HasData); reader = new AsnReader(inputData, (AsnEncodingRules)ruleSet); Assert.Equal( X509KeyUsageCSharpStyle.DecipherOnly, reader.GetNamedBitListValue <X509KeyUsageCSharpStyle>( new Asn1Tag((TagClass)tagClass, tagValue, false))); Assert.False(reader.HasData); }
public virtual void DecodeX509KeyUsageExtension(byte[] encoded, out X509KeyUsageFlags keyUsages) { AsnReader reader = new AsnReader(encoded, AsnEncodingRules.BER); KeyUsageFlagsAsn keyUsagesAsn = reader.GetNamedBitListValue <KeyUsageFlagsAsn>(); reader.ThrowIfNotEmpty(); // DER encodings of BIT_STRING values number the bits as // 01234567 89 (big endian), plus a number saying how many bits of the last byte were padding. // // So digitalSignature (0) doesn't mean 2^0 (0x01), it means the most significant bit // is set in this byte stream. // // BIT_STRING values are compact. So a value of cRLSign (6) | keyEncipherment (2), which // is 0b0010001 => 0b0010 0010 (1 bit padding) => 0x22 encoded is therefore // 0x02 (length remaining) 0x01 (1 bit padding) 0x22. // // We will read that, and return 0x22. 0x22 lines up // exactly with X509KeyUsageFlags.CrlSign (0x20) | X509KeyUsageFlags.KeyEncipherment (0x02) // // Once the decipherOnly (8) bit is added to the mix, the values become: // 0b001000101 => 0b0010 0010 1000 0000 (7 bits padding) // { 0x03 0x07 0x22 0x80 } // And we read new byte[] { 0x22 0x80 } // // The value of X509KeyUsageFlags.DecipherOnly is 0x8000. 0x8000 in a little endian // representation is { 0x00 0x80 }. This means that the DER storage mechanism has effectively // ended up being little-endian for BIT_STRING values. Untwist the bytes, and now the bits all // line up with the existing X509KeyUsageFlags. keyUsages = (X509KeyUsageFlags)ReverseBitOrder((byte)keyUsagesAsn) | (X509KeyUsageFlags)(ReverseBitOrder((byte)(((ushort)keyUsagesAsn >> 8))) << 8); }
internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out PkiStatusInfo decoded) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = default; AsnReader sequenceReader = reader.ReadSequence(expectedTag); if (!sequenceReader.TryReadInt32(out decoded.Status)) { sequenceReader.ThrowIfNotEmpty(); } if (sequenceReader.HasData) { decoded.StatusString = sequenceReader.GetEncodedValue(); } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(Asn1Tag.PrimitiveBitString)) { decoded.FailInfo = sequenceReader.GetNamedBitListValue <System.Security.Cryptography.Pkcs.Asn1.PkiFailureInfo>(); } sequenceReader.ThrowIfNotEmpty(); }
public static void ReadNamedBitList_ExcessiveBits(PublicEncodingRules ruleSet) { string inputHex = "0303061480"; AsnReader reader = new AsnReader(inputHex.HexToByteArray(), (AsnEncodingRules)ruleSet); Assert.Throws <CryptographicException>( () => reader.GetNamedBitListValue <X509KeyUsageCSharpStyle>()); Assert.True(reader.HasData, "reader.HasData"); }
public static void ReadNamedBitList_RequiresFlags(PublicEncodingRules ruleSet) { string inputHex = "030100"; AsnReader reader = new AsnReader(inputHex.HexToByteArray(), (AsnEncodingRules)ruleSet); AssertExtensions.Throws <ArgumentException>( "tFlagsEnum", () => reader.GetNamedBitListValue <AsnEncodingRules>()); Assert.True(reader.HasData, "reader.HasData"); }
public static void TagMustBeCorrect_Universal(PublicEncodingRules ruleSet) { byte[] inputData = { 3, 2, 1, 2 }; AsnReader reader = new AsnReader(inputData, (AsnEncodingRules)ruleSet); AssertExtensions.Throws <ArgumentException>( "expectedTag", () => reader.GetNamedBitListValue <X509KeyUsageCSharpStyle>(Asn1Tag.Null)); Assert.True(reader.HasData, "HasData after bad universal tag"); Assert.Throws <CryptographicException>( () => reader.GetNamedBitListValue <X509KeyUsageCSharpStyle>(new Asn1Tag(TagClass.ContextSpecific, 0))); Assert.True(reader.HasData, "HasData after wrong tag"); Assert.Equal( X509KeyUsageCSharpStyle.CrlSign, reader.GetNamedBitListValue <X509KeyUsageCSharpStyle>()); Assert.False(reader.HasData, "HasData after read"); }
public static void VerifyReadNamedBitListEncodings( PublicEncodingRules ruleSet, Type enumType, long enumValue, string inputHex) { byte[] inputBytes = inputHex.HexToByteArray(); AsnReader reader = new AsnReader(inputBytes, (AsnEncodingRules)ruleSet); Enum readValue = reader.GetNamedBitListValue(enumType); Assert.Equal(Enum.ToObject(enumType, enumValue), readValue); }
internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out DistributionPointAsn decoded) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = default; AsnReader sequenceReader = reader.ReadSequence(expectedTag); AsnReader explicitReader; AsnReader collectionReader; if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 0)); System.Security.Cryptography.X509Certificates.Asn1.DistributionPointNameAsn tmpDistributionPoint; System.Security.Cryptography.X509Certificates.Asn1.DistributionPointNameAsn.Decode(explicitReader, out tmpDistributionPoint); decoded.DistributionPoint = tmpDistributionPoint; explicitReader.ThrowIfNotEmpty(); } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 1))) { decoded.Reasons = sequenceReader.GetNamedBitListValue <System.Security.Cryptography.X509Certificates.Asn1.ReasonFlagsAsn>(new Asn1Tag(TagClass.ContextSpecific, 1)); } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 2))) { // Decode SEQUENCE OF for CRLIssuer { collectionReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 2)); var tmpList = new List <System.Security.Cryptography.Asn1.GeneralNameAsn>(); System.Security.Cryptography.Asn1.GeneralNameAsn tmpItem; while (collectionReader.HasData) { System.Security.Cryptography.Asn1.GeneralNameAsn.Decode(collectionReader, out tmpItem); tmpList.Add(tmpItem); } decoded.CRLIssuer = tmpList.ToArray(); } } sequenceReader.ThrowIfNotEmpty(); }
public static void ReadMicrosoftComCert() { byte[] bytes = MicrosoftDotComSslCertBytes; AsnReader fileReader = new AsnReader(bytes, AsnEncodingRules.DER); AsnReader certReader = fileReader.ReadSequence(); Assert.False(fileReader.HasData, "fileReader.HasData"); AsnReader tbsCertReader = certReader.ReadSequence(); AsnReader sigAlgReader = certReader.ReadSequence(); Assert.True( certReader.TryGetPrimitiveBitStringValue( out int unusedBitCount, out ReadOnlyMemory <byte> signature), "certReader.TryGetBitStringBytes"); Assert.Equal(0, unusedBitCount); AssertRefSame(signature, ref bytes[1176], "Signature is a ref to bytes[1176]"); Assert.False(certReader.HasData, "certReader.HasData"); AsnReader versionExplicitWrapper = tbsCertReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 0)); Assert.True(versionExplicitWrapper.TryReadInt32(out int certVersion)); Assert.Equal(2, certVersion); Assert.False(versionExplicitWrapper.HasData, "versionExplicitWrapper.HasData"); ReadOnlyMemory <byte> serialBytes = tbsCertReader.GetIntegerBytes(); AssertRefSame(serialBytes, ref bytes[15], "Serial number starts at bytes[15]"); AsnReader tbsSigAlgReader = tbsCertReader.ReadSequence(); Assert.Equal("1.2.840.113549.1.1.11", tbsSigAlgReader.ReadObjectIdentifierAsString()); Assert.True(tbsSigAlgReader.HasData, "tbsSigAlgReader.HasData before ReadNull"); tbsSigAlgReader.ReadNull(); Assert.False(tbsSigAlgReader.HasData, "tbsSigAlgReader.HasData after ReadNull"); AsnReader issuerReader = tbsCertReader.ReadSequence(); Asn1Tag printableString = new Asn1Tag(UniversalTagNumber.PrintableString); AssertRdn(issuerReader, "2.5.4.6", 57, printableString, bytes, "issuer[C]"); AssertRdn(issuerReader, "2.5.4.10", 70, printableString, bytes, "issuer[O]"); AssertRdn(issuerReader, "2.5.4.11", 101, printableString, bytes, "issuer[OU]"); AssertRdn(issuerReader, "2.5.4.3", 134, printableString, bytes, "issuer[CN]"); Assert.False(issuerReader.HasData, "issuerReader.HasData"); AsnReader validityReader = tbsCertReader.ReadSequence(); Assert.Equal(new DateTimeOffset(2014, 10, 15, 0, 0, 0, TimeSpan.Zero), validityReader.GetUtcTime()); Assert.Equal(new DateTimeOffset(2016, 10, 15, 23, 59, 59, TimeSpan.Zero), validityReader.GetUtcTime()); Assert.False(validityReader.HasData, "validityReader.HasData"); AsnReader subjectReader = tbsCertReader.ReadSequence(); Asn1Tag utf8String = new Asn1Tag(UniversalTagNumber.UTF8String); AssertRdn(subjectReader, "1.3.6.1.4.1.311.60.2.1.3", 220, printableString, bytes, "subject[EV Country]"); AssertRdn(subjectReader, "1.3.6.1.4.1.311.60.2.1.2", 241, utf8String, bytes, "subject[EV State]", "Washington"); AssertRdn(subjectReader, "2.5.4.15", 262, printableString, bytes, "subject[Business Category]"); AssertRdn(subjectReader, "2.5.4.5", 293, printableString, bytes, "subject[Serial Number]"); AssertRdn(subjectReader, "2.5.4.6", 313, printableString, bytes, "subject[C]"); AssertRdn(subjectReader, "2.5.4.17", 326, utf8String, bytes, "subject[Postal Code]", "98052"); AssertRdn(subjectReader, "2.5.4.8", 342, utf8String, bytes, "subject[ST]", "Washington"); AssertRdn(subjectReader, "2.5.4.7", 363, utf8String, bytes, "subject[L]", "Redmond"); AssertRdn(subjectReader, "2.5.4.9", 381, utf8String, bytes, "subject[Street Address]", "1 Microsoft Way"); AssertRdn(subjectReader, "2.5.4.10", 407, utf8String, bytes, "subject[O]", "Microsoft Corporation"); AssertRdn(subjectReader, "2.5.4.11", 439, utf8String, bytes, "subject[OU]", "MSCOM"); AssertRdn(subjectReader, "2.5.4.3", 455, utf8String, bytes, "subject[CN]", "www.microsoft.com"); Assert.False(subjectReader.HasData, "subjectReader.HasData"); AsnReader subjectPublicKeyInfo = tbsCertReader.ReadSequence(); AsnReader spkiAlgorithm = subjectPublicKeyInfo.ReadSequence(); Assert.Equal("1.2.840.113549.1.1.1", spkiAlgorithm.ReadObjectIdentifierAsString()); spkiAlgorithm.ReadNull(); Assert.False(spkiAlgorithm.HasData, "spkiAlgorithm.HasData"); Assert.True( subjectPublicKeyInfo.TryGetPrimitiveBitStringValue( out unusedBitCount, out ReadOnlyMemory <byte> encodedPublicKey), "subjectPublicKeyInfo.TryGetBitStringBytes"); Assert.Equal(0, unusedBitCount); AssertRefSame(encodedPublicKey, ref bytes[498], "Encoded public key starts at byte 498"); Assert.False(subjectPublicKeyInfo.HasData, "subjectPublicKeyInfo.HasData"); AsnReader publicKeyReader = new AsnReader(encodedPublicKey, AsnEncodingRules.DER); AsnReader rsaPublicKeyReader = publicKeyReader.ReadSequence(); AssertRefSame(rsaPublicKeyReader.GetIntegerBytes(), ref bytes[506], "RSA Modulus is at bytes[502]"); Assert.True(rsaPublicKeyReader.TryReadInt32(out int rsaExponent)); Assert.Equal(65537, rsaExponent); Assert.False(rsaPublicKeyReader.HasData, "rsaPublicKeyReader.HasData"); Assert.False(publicKeyReader.HasData, "publicKeyReader.HasData"); AsnReader extensionsContainer = tbsCertReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 3)); AsnReader extensions = extensionsContainer.ReadSequence(); Assert.False(extensionsContainer.HasData, "extensionsContainer.HasData"); AsnReader sanExtension = extensions.ReadSequence(); Assert.Equal("2.5.29.17", sanExtension.ReadObjectIdentifierAsString()); Assert.True(sanExtension.TryGetPrimitiveOctetStringBytes(out ReadOnlyMemory <byte> sanExtensionBytes)); Assert.False(sanExtension.HasData, "sanExtension.HasData"); AsnReader sanExtensionPayload = new AsnReader(sanExtensionBytes, AsnEncodingRules.DER); AsnReader sanExtensionValue = sanExtensionPayload.ReadSequence(); Assert.False(sanExtensionPayload.HasData, "sanExtensionPayload.HasData"); Asn1Tag dnsName = new Asn1Tag(TagClass.ContextSpecific, 2); Assert.Equal("www.microsoft.com", sanExtensionValue.GetCharacterString(dnsName, UniversalTagNumber.IA5String)); Assert.Equal("wwwqa.microsoft.com", sanExtensionValue.GetCharacterString(dnsName, UniversalTagNumber.IA5String)); Assert.False(sanExtensionValue.HasData, "sanExtensionValue.HasData"); AsnReader basicConstraints = extensions.ReadSequence(); Assert.Equal("2.5.29.19", basicConstraints.ReadObjectIdentifierAsString()); Assert.True(basicConstraints.TryGetPrimitiveOctetStringBytes(out ReadOnlyMemory <byte> basicConstraintsBytes)); AsnReader basicConstraintsPayload = new AsnReader(basicConstraintsBytes, AsnEncodingRules.DER); AsnReader basicConstraintsValue = basicConstraintsPayload.ReadSequence(); Assert.False(basicConstraintsValue.HasData, "basicConstraintsValue.HasData"); Assert.False(basicConstraintsPayload.HasData, "basicConstraintsPayload.HasData"); AsnReader keyUsageExtension = extensions.ReadSequence(); Assert.Equal("2.5.29.15", keyUsageExtension.ReadObjectIdentifierAsString()); Assert.True(keyUsageExtension.ReadBoolean(), "keyUsageExtension.ReadBoolean() (IsCritical)"); Assert.True(keyUsageExtension.TryGetPrimitiveOctetStringBytes(out ReadOnlyMemory <byte> keyUsageBytes)); AsnReader keyUsagePayload = new AsnReader(keyUsageBytes, AsnEncodingRules.DER); Assert.Equal( X509KeyUsageCSharpStyle.DigitalSignature | X509KeyUsageCSharpStyle.KeyEncipherment, keyUsagePayload.GetNamedBitListValue <X509KeyUsageCSharpStyle>()); Assert.False(keyUsagePayload.HasData, "keyUsagePayload.HasData"); AssertExtension(extensions, "2.5.29.37", false, 863, bytes); AssertExtension(extensions, "2.5.29.32", false, 894, bytes); AssertExtension(extensions, "2.5.29.35", false, 998, bytes); AssertExtension(extensions, "2.5.29.31", false, 1031, bytes); AssertExtension(extensions, "1.3.6.1.5.5.7.1.1", false, 1081, bytes); Assert.False(extensions.HasData, "extensions.HasData"); Assert.Equal("1.2.840.113549.1.1.11", sigAlgReader.ReadObjectIdentifierAsString()); sigAlgReader.ReadNull(); Assert.False(sigAlgReader.HasData); }