public static void TagMustBeCorrect_Custom(PublicEncodingRules ruleSet) { byte[] inputData = "87028837".HexToByteArray(); AsnReader reader = new AsnReader(inputData, (AsnEncodingRules)ruleSet); AssertExtensions.Throws <ArgumentException>( "expectedTag", () => reader.GetIntegerBytes(Asn1Tag.Null)); Assert.True(reader.HasData, "HasData after bad universal tag"); Assert.Throws <CryptographicException>(() => reader.ReadObjectIdentifierAsString()); Assert.True(reader.HasData, "HasData after default tag"); Assert.Throws <CryptographicException>( () => reader.ReadObjectIdentifierAsString(new Asn1Tag(TagClass.Application, 0))); Assert.True(reader.HasData, "HasData after wrong custom class"); Assert.Throws <CryptographicException>( () => reader.ReadObjectIdentifierAsString(new Asn1Tag(TagClass.ContextSpecific, 1))); Assert.True(reader.HasData, "HasData after wrong custom tag value"); Assert.Equal( "2.999", reader.ReadObjectIdentifierAsString(new Asn1Tag(TagClass.ContextSpecific, 7))); Assert.False(reader.HasData, "HasData after reading value"); }
internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out CertificatePolicyMappingAsn decoded) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = default; AsnReader sequenceReader = reader.ReadSequence(expectedTag); decoded.IssuerDomainPolicy = sequenceReader.ReadObjectIdentifierAsString(); decoded.SubjectDomainPolicy = sequenceReader.ReadObjectIdentifierAsString(); sequenceReader.ThrowIfNotEmpty(); }
public static void ReadVeryLongOidArc(PublicEncodingRules ruleSet) { byte[] inputData = new byte[255]; // 06 81 93 (OBJECT IDENTIFIER, 147 bytes). inputData[0] = 0x06; inputData[1] = 0x81; inputData[2] = 0x93; // With 147 bytes we get 147*7 = 1029 value bits. // The smallest legal number to encode would have a top byte of 0x81, // leaving 1022 bits remaining. If they're all zero then we have 2^1022. // // Since it's our first sub-identifier it's really encoding "2.(2^1022 - 80)". inputData[3] = 0x81; // Leave the last byte as 0. new Span <byte>(inputData, 4, 145).Fill(0x80); const string ExpectedOid = "2." + "449423283715578976932326297697256183404494244735576643183575" + "202894331689513752407831771193306018840052800284699678483394" + "146974422036041556232118576598685310944419733562163713190755" + "549003115235298632707380212514422095376705856157203684782776" + "352068092908376276711465745599868114846199290762088390824060" + "56034224"; AsnReader reader = new AsnReader(inputData, (AsnEncodingRules)ruleSet); string oidString = reader.ReadObjectIdentifierAsString(); Assert.Equal(ExpectedOid, oidString); }
private static IEnumerable <KeyValuePair <string, string> > ReadReverseRdns(X500DistinguishedName name) { AsnReader x500NameReader = new AsnReader(name.RawData, AsnEncodingRules.DER); AsnReader sequenceReader = x500NameReader.ReadSequence(); var rdnReaders = new Stack <AsnReader>(); x500NameReader.ThrowIfNotEmpty(); while (sequenceReader.HasData) { rdnReaders.Push(sequenceReader.ReadSetOf()); } while (rdnReaders.Count > 0) { AsnReader rdnReader = rdnReaders.Pop(); while (rdnReader.HasData) { AsnReader tavReader = rdnReader.ReadSequence(); string oid = tavReader.ReadObjectIdentifierAsString(); string value = tavReader.ReadAnyAsnString(); tavReader.ThrowIfNotEmpty(); yield return(new KeyValuePair <string, string>(oid, value)); } } }
public static void ReadVeryLongOid(PublicEncodingRules ruleSet) { byte[] inputData = new byte[100000]; // 06 83 02 00 00 (OBJECT IDENTIFIER, 65536 bytes). inputData[0] = 0x06; inputData[1] = 0x83; inputData[2] = 0x01; inputData[3] = 0x00; inputData[4] = 0x00; // and the rest are all zero. // The first byte produces "0.0". Each of the remaining 65535 bytes produce // another ".0". const int ExpectedLength = 65536 * 2 + 1; StringBuilder builder = new StringBuilder(ExpectedLength); builder.Append('0'); for (int i = 0; i <= ushort.MaxValue; i++) { builder.Append('.'); builder.Append(0); } AsnReader reader = new AsnReader(inputData, (AsnEncodingRules)ruleSet); string oidString = reader.ReadObjectIdentifierAsString(); Assert.Equal(ExpectedLength, oidString.Length); Assert.Equal(builder.ToString(), oidString); }
internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out PolicyInformation decoded) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = default; AsnReader sequenceReader = reader.ReadSequence(expectedTag); AsnReader collectionReader; decoded.PolicyIdentifier = sequenceReader.ReadObjectIdentifierAsString(); if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(Asn1Tag.Sequence)) { // Decode SEQUENCE OF for PolicyQualifiers { collectionReader = sequenceReader.ReadSequence(); var tmpList = new List <System.Security.Cryptography.Pkcs.Asn1.PolicyQualifierInfo>(); System.Security.Cryptography.Pkcs.Asn1.PolicyQualifierInfo tmpItem; while (collectionReader.HasData) { System.Security.Cryptography.Pkcs.Asn1.PolicyQualifierInfo.Decode(collectionReader, out tmpItem); tmpList.Add(tmpItem); } decoded.PolicyQualifiers = tmpList.ToArray(); } } sequenceReader.ThrowIfNotEmpty(); }
internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out CertificateTemplateAsn decoded) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = default; AsnReader sequenceReader = reader.ReadSequence(expectedTag); decoded.TemplateID = sequenceReader.ReadObjectIdentifierAsString(); if (!sequenceReader.TryReadInt32(out decoded.TemplateMajorVersion)) { sequenceReader.ThrowIfNotEmpty(); } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(Asn1Tag.Integer)) { if (sequenceReader.TryReadInt32(out int tmpTemplateMinorVersion)) { decoded.TemplateMinorVersion = tmpTemplateMinorVersion; } else { sequenceReader.ThrowIfNotEmpty(); } } sequenceReader.ThrowIfNotEmpty(); }
public static void ReadEcPublicKey() { const string PublicKeyValue = "04" + "2363DD131DA65E899A2E63E9E05E50C830D4994662FFE883DB2B9A767DCCABA2" + "F07081B5711BE1DEE90DFC8DE17970C2D937A16CD34581F52B8D59C9E9532D13"; const string InputHex = "3059" + "3013" + "06072A8648CE3D0201" + "06082A8648CE3D030107" + "0342" + "00" + PublicKeyValue; byte[] inputData = InputHex.HexToByteArray(); var spki = AsnSerializer.Deserialize <SubjectPublicKeyInfo>( inputData, AsnEncodingRules.DER); Assert.Equal("1.2.840.10045.2.1", spki.AlgorithmIdentifier.Algorithm.Value); Assert.Equal(PublicKeyValue, spki.PublicKey.ByteArrayToHex()); AsnReader reader = new AsnReader(spki.AlgorithmIdentifier.Parameters, AsnEncodingRules.DER); string curveOid = reader.ReadObjectIdentifierAsString(); Assert.False(reader.HasData, "reader.HasData"); Assert.Equal("1.2.840.10045.3.1.7", curveOid); }
public static IReadOnlyList <string> GetNameInfo(this X509Certificate2 certificate, string nameTypeOid, X509NameSource nameSource) { ThrowHelpers.CheckNullOrEempty(nameof(nameTypeOid), nameTypeOid); byte[] nameBytes = nameSource switch { X509NameSource.Issuer => certificate.IssuerName.RawData, X509NameSource.Subject => certificate.SubjectName.RawData, _ => ThrowHelpers.NotSupport <byte[], X509NameSource>(nameSource) }; List <string> result = new List <string>(); AsnReader nameReader = new AsnReader(nameBytes, AsnEncodingRules.DER); AsnReader mainSequence = nameReader.ReadSequence(); while (mainSequence.HasData) { AsnReader x509Name = mainSequence.ReadSetOf().ReadSequence(); string oid = x509Name.ReadObjectIdentifierAsString(); if (string.Equals(nameTypeOid, oid, StringComparison.Ordinal)) { result.Add(x509Name.GetCharacterString(UniversalTagNumber.PrintableString)); } } return(result); } }
internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out EncryptedContentInfoAsn decoded) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = default; AsnReader sequenceReader = reader.ReadSequence(expectedTag); decoded.ContentType = sequenceReader.ReadObjectIdentifierAsString(); System.Security.Cryptography.Asn1.AlgorithmIdentifierAsn.Decode(sequenceReader, out decoded.ContentEncryptionAlgorithm); if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0))) { if (sequenceReader.TryReadPrimitiveOctetStringBytes(new Asn1Tag(TagClass.ContextSpecific, 0), out ReadOnlyMemory <byte> tmpEncryptedContent)) { decoded.EncryptedContent = tmpEncryptedContent; } else { decoded.EncryptedContent = sequenceReader.ReadOctetString(new Asn1Tag(TagClass.ContextSpecific, 0)); } } sequenceReader.ThrowIfNotEmpty(); }
public static void VerifyMultiByteParsing(string inputHex, string expectedValue) { byte[] inputData = inputHex.HexToByteArray(); AsnReader reader = new AsnReader(inputData, AsnEncodingRules.DER); string oidValue = reader.ReadObjectIdentifierAsString(); Assert.Equal(expectedValue, oidValue); }
public static void TagMustBeCorrect_Universal(PublicEncodingRules ruleSet) { byte[] inputData = "06028837".HexToByteArray(); AsnReader reader = new AsnReader(inputData, (AsnEncodingRules)ruleSet); Assert.Throws <ArgumentException>( "expectedTag", () => reader.ReadIntegerBytes(Asn1Tag.Null)); Assert.True(reader.HasData, "HasData after bad universal tag"); Assert.Throws <CryptographicException>( () => reader.ReadObjectIdentifierAsString(new Asn1Tag(TagClass.ContextSpecific, 0))); Assert.True(reader.HasData, "HasData after wrong tag"); Assert.Equal("2.999", reader.ReadObjectIdentifierAsString()); Assert.False(reader.HasData, "HasData after read"); }
public static void ReadObjectIdentifierAsString_Success( PublicEncodingRules ruleSet, string inputHex, string expectedValue) { byte[] inputData = inputHex.HexToByteArray(); AsnReader reader = new AsnReader(inputData, (AsnEncodingRules)ruleSet); string oidValue = reader.ReadObjectIdentifierAsString(); Assert.Equal(expectedValue, oidValue); }
private static void AssertExtension(AsnReader extensions, string oid, bool critical, int index, byte[] bytes) { AsnReader extension = extensions.ReadSequence(); Assert.Equal(oid, extension.ReadObjectIdentifierAsString()); if (critical) { Assert.True(extension.ReadBoolean(), $"{oid} is critical"); } Assert.True(extension.TryReadPrimitiveOctetStringBytes(out ReadOnlyMemory <byte> extensionBytes)); AssertRefSame(extensionBytes, ref bytes[index], $"{oid} extension value is at byte {index}"); }
internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out AccessDescriptionAsn decoded) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = default; AsnReader sequenceReader = reader.ReadSequence(expectedTag); decoded.AccessMethod = sequenceReader.ReadObjectIdentifierAsString(); System.Security.Cryptography.Asn1.GeneralNameAsn.Decode(sequenceReader, out decoded.AccessLocation); sequenceReader.ThrowIfNotEmpty(); }
public static string DecodeOid(byte[] encodedOid) { // Windows compat. if (s_invalidEmptyOid.AsSpan().SequenceEqual(encodedOid)) { return(string.Empty); } // Read using BER because the CMS specification says the encoding is BER. AsnReader reader = new AsnReader(encodedOid, AsnEncodingRules.BER); string value = reader.ReadObjectIdentifierAsString(); reader.ThrowIfNotEmpty(); return(value); }
internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out PolicyQualifierInfo decoded) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = default; AsnReader sequenceReader = reader.ReadSequence(expectedTag); decoded.PolicyQualifierId = sequenceReader.ReadObjectIdentifierAsString(); decoded.Qualifier = sequenceReader.GetEncodedValue(); sequenceReader.ThrowIfNotEmpty(); }
private static ISet <string> ReadExtendedKeyUsageExtension(byte[] rawData) { HashSet <string> oids = new HashSet <string>(); AsnReader reader = new AsnReader(rawData, AsnEncodingRules.DER); AsnReader sequenceReader = reader.ReadSequence(); reader.ThrowIfNotEmpty(); //OidCollection usages while (sequenceReader.HasData) { oids.Add(sequenceReader.ReadObjectIdentifierAsString()); } return(oids); }
public override string DecodeOid(byte[] encodedOid) { // Windows compat. if (s_invalidEmptyOid.AsSpan().SequenceEqual(encodedOid)) { return(string.Empty); } // Read using BER because the CMS specification says the encoding is BER. AsnReader reader = new AsnReader(encodedOid, AsnEncodingRules.BER); string value = reader.ReadObjectIdentifierAsString(); if (reader.HasData) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } return(value); }
internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out SecretBagAsn decoded) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = default; AsnReader sequenceReader = reader.ReadSequence(expectedTag); AsnReader explicitReader; decoded.SecretTypeId = sequenceReader.ReadObjectIdentifierAsString(); explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 0)); decoded.SecretValue = explicitReader.ReadEncodedValue(); explicitReader.ThrowIfNotEmpty(); sequenceReader.ThrowIfNotEmpty(); }
internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out OtherKeyAttributeAsn decoded) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = default; AsnReader sequenceReader = reader.ReadSequence(expectedTag); decoded.KeyAttrId = sequenceReader.ReadObjectIdentifierAsString(); if (sequenceReader.HasData) { decoded.KeyAttr = sequenceReader.GetEncodedValue(); } sequenceReader.ThrowIfNotEmpty(); }
public static void ExpectedTag_IgnoresConstructed( PublicEncodingRules ruleSet, string inputHex, PublicTagClass tagClass, int tagValue) { byte[] inputData = inputHex.HexToByteArray(); AsnReader reader = new AsnReader(inputData, (AsnEncodingRules)ruleSet); string val1 = reader.ReadObjectIdentifierAsString(new Asn1Tag((TagClass)tagClass, tagValue, true)); Assert.False(reader.HasData); reader = new AsnReader(inputData, (AsnEncodingRules)ruleSet); string val2 = reader.ReadObjectIdentifierAsString(new Asn1Tag((TagClass)tagClass, tagValue, false)); Assert.False(reader.HasData); Assert.Equal(val1, val2); }
internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out SafeBagAsn decoded) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = default; AsnReader sequenceReader = reader.ReadSequence(expectedTag); AsnReader explicitReader; AsnReader collectionReader; decoded.BagId = sequenceReader.ReadObjectIdentifierAsString(); explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 0)); decoded.BagValue = explicitReader.GetEncodedValue(); explicitReader.ThrowIfNotEmpty(); if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(Asn1Tag.SetOf)) { // Decode SEQUENCE OF for BagAttributes { collectionReader = sequenceReader.ReadSetOf(); var tmpList = new List <System.Security.Cryptography.Asn1.AttributeAsn>(); System.Security.Cryptography.Asn1.AttributeAsn tmpItem; while (collectionReader.HasData) { System.Security.Cryptography.Asn1.AttributeAsn.Decode(collectionReader, out tmpItem); tmpList.Add(tmpItem); } decoded.BagAttributes = tmpList.ToArray(); } } sequenceReader.ThrowIfNotEmpty(); }
internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out EncapsulatedContentInfoAsn decoded) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = default; AsnReader sequenceReader = reader.ReadSequence(expectedTag); AsnReader explicitReader; decoded.ContentType = sequenceReader.ReadObjectIdentifierAsString(); if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 0)); decoded.Content = explicitReader.ReadEncodedValue(); explicitReader.ThrowIfNotEmpty(); } sequenceReader.ThrowIfNotEmpty(); }
private static void AssertRdn( AsnReader reader, string atvOid, int offset, Asn1Tag valueTag, byte[] bytes, string label, string stringValue = null) { AsnReader rdn = reader.ReadSetOf(); AsnReader attributeTypeAndValue = rdn.ReadSequence(); Assert.Equal(atvOid, attributeTypeAndValue.ReadObjectIdentifierAsString()); ReadOnlyMemory <byte> value = attributeTypeAndValue.ReadEncodedValue(); ReadOnlySpan <byte> valueSpan = value.Span; Assert.True(Asn1Tag.TryDecode(valueSpan, out Asn1Tag actualTag, out int bytesRead)); Assert.Equal(1, bytesRead); Assert.Equal(valueTag, actualTag); AssertRefSame( ref MemoryMarshal.GetReference(valueSpan), ref bytes[offset], $"{label} is at bytes[{offset}]"); if (stringValue != null) { AsnReader valueReader = new AsnReader(value, AsnEncodingRules.DER); Assert.Equal(stringValue, valueReader.ReadCharacterString((UniversalTagNumber)valueTag.TagValue)); Assert.False(valueReader.HasData, "valueReader.HasData"); } Assert.False(attributeTypeAndValue.HasData, $"attributeTypeAndValue.HasData ({label})"); Assert.False(rdn.HasData, $"rdn.HasData ({label})"); }
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.TryReadPrimitiveBitStringValue( 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.ReadIntegerBytes(); 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.ReadUtcTime()); Assert.Equal(new DateTimeOffset(2016, 10, 15, 23, 59, 59, TimeSpan.Zero), validityReader.ReadUtcTime()); 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.TryReadPrimitiveBitStringValue( 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.ReadIntegerBytes(), 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.TryReadPrimitiveOctetStringBytes(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.ReadCharacterString(dnsName, UniversalTagNumber.IA5String)); Assert.Equal("wwwqa.microsoft.com", sanExtensionValue.ReadCharacterString(dnsName, UniversalTagNumber.IA5String)); Assert.False(sanExtensionValue.HasData, "sanExtensionValue.HasData"); AsnReader basicConstraints = extensions.ReadSequence(); Assert.Equal("2.5.29.19", basicConstraints.ReadObjectIdentifierAsString()); Assert.True(basicConstraints.TryReadPrimitiveOctetStringBytes(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.TryReadPrimitiveOctetStringBytes(out ReadOnlyMemory <byte> keyUsageBytes)); AsnReader keyUsagePayload = new AsnReader(keyUsageBytes, AsnEncodingRules.DER); Assert.Equal( X509KeyUsageCSharpStyle.DigitalSignature | X509KeyUsageCSharpStyle.KeyEncipherment, keyUsagePayload.ReadNamedBitListValue <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); }
private static string X500DistinguishedNameDecode( byte[] encodedName, bool printOid, bool reverse, bool quoteIfNeeded, string dnSeparator, string multiValueSeparator, bool addTrailingDelimiter) { AsnReader x500NameReader = new AsnReader(encodedName, AsnEncodingRules.DER); AsnReader x500NameSequenceReader = x500NameReader.ReadSequence(); var rdnReaders = new List <AsnReader>(); x500NameReader.ThrowIfNotEmpty(); while (x500NameSequenceReader.HasData) { rdnReaders.Add(x500NameSequenceReader.ReadSetOf()); } // We need to allocate a StringBuilder to hold the data as we're building it, and there's the usual // arbitrary process of choosing a number that's "big enough" to minimize reallocations without wasting // too much space in the average case. // // So, let's look at an example of what our output might be. // // GitHub.com's SSL cert has a "pretty long" subject (partially due to the unknown OIDs): // businessCategory=Private Organization // 1.3.6.1.4.1.311.60.2.1.3=US // 1.3.6.1.4.1.311.60.2.1.2=Delaware // serialNumber=5157550 // street=548 4th Street // postalCode=94107 // C=US // ST=California // L=San Francisco // O=GitHub, Inc. // CN=github.com // // Which comes out to 228 characters using OpenSSL's default pretty-print // (openssl x509 -in github.cer -text -noout) // Throw in some "maybe-I-need-to-quote-this" quotes, and a couple of extra/extra-long O/OU values // and round that up to the next programmer number, and you get that 512 should avoid reallocations // in all but the most dire of cases. StringBuilder decodedName = new StringBuilder(512); int entryCount = rdnReaders.Count; bool printSpacing = false; for (int i = 0; i < entryCount; i++) { int loc = reverse ? entryCount - i - 1 : i; // RelativeDistinguishedName ::= // SET SIZE (1..MAX) OF AttributeTypeAndValue // // AttributeTypeAndValue::= SEQUENCE { // type AttributeType, // value AttributeValue } // // AttributeType::= OBJECT IDENTIFIER // // AttributeValue ::= ANY-- DEFINED BY AttributeType if (printSpacing) { decodedName.Append(dnSeparator); } else { printSpacing = true; } AsnReader rdnReader = rdnReaders[loc]; bool hadValue = false; while (rdnReader.HasData) { AsnReader tavReader = rdnReader.ReadSequence(); string oid = tavReader.ReadObjectIdentifierAsString(); string attributeValue = tavReader.ReadDirectoryOrIA5String(); tavReader.ThrowIfNotEmpty(); if (hadValue) { decodedName.Append(multiValueSeparator); } else { hadValue = true; } if (printOid) { AppendOid(decodedName, oid); } bool quote = quoteIfNeeded && NeedsQuoting(attributeValue); if (quote) { decodedName.Append('"'); // If the RDN itself had a quote within it, that quote needs to be escaped // with another quote. attributeValue = attributeValue.Replace("\"", "\"\""); } decodedName.Append(attributeValue); if (quote) { decodedName.Append('"'); } } } if (addTrailingDelimiter && decodedName.Length > 0) { decodedName.Append(dnSeparator); } return(decodedName.ToString()); }
internal CertificateDataAsn(byte[] rawData) { AsnReader reader = new AsnReader(rawData, AsnEncodingRules.DER).ReadSequence(); AsnReader tbsCertificate = reader.ReadSequence(); if (tbsCertificate.PeekTag() == explicit0) { AsnReader version = tbsCertificate.ReadSequence(explicit0); version.TryReadInt32(out Version); } else if (tbsCertificate.PeekTag() != Asn1Tag.Integer) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } else { Version = 0; } if (Version < 0 || Version > 2) { throw new CryptographicException(); } SerialNumber = tbsCertificate.GetIntegerBytes().ToArray(); AsnReader tbsSignature = tbsCertificate.ReadSequence(); TbsSignature.AlgorithmId = tbsSignature.ReadObjectIdentifierAsString(); TbsSignature.Parameters = tbsSignature.HasData ? tbsSignature.GetEncodedValue().ToArray() : Array.Empty <byte>(); if (tbsSignature.HasData) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } Issuer = new X500DistinguishedName(tbsCertificate.GetEncodedValue().ToArray()); AsnReader validity = tbsCertificate.ReadSequence(); NotBefore = validity.GetUtcTime().UtcDateTime; // FIXME NotAfter = validity.GetUtcTime().UtcDateTime; if (validity.HasData) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } Subject = new X500DistinguishedName(tbsCertificate.GetEncodedValue().ToArray()); SubjectPublicKeyInfo = tbsCertificate.GetEncodedValue().ToArray(); AsnReader subjectPublicKeyInfo = new AsnReader(SubjectPublicKeyInfo, AsnEncodingRules.DER).ReadSequence(); AsnReader subjectKeyAlgorithm = subjectPublicKeyInfo.ReadSequence(); PublicKeyAlgorithm.AlgorithmId = subjectKeyAlgorithm.ReadObjectIdentifierAsString(); PublicKeyAlgorithm.Parameters = subjectKeyAlgorithm.HasData ? subjectKeyAlgorithm.GetEncodedValue().ToArray() : Array.Empty <byte>(); if (subjectKeyAlgorithm.HasData) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } PublicKey = subjectPublicKeyInfo.ReadBitString(); if (subjectPublicKeyInfo.HasData) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } if (Version > 0 && tbsCertificate.HasData && tbsCertificate.PeekTag() == explicit1) { IssuerUniqueId = tbsCertificate.ReadBitString(); } else { IssuerUniqueId = null; } if (Version > 0 && tbsCertificate.HasData && tbsCertificate.PeekTag() == explicit2) { SubjectUniqueId = tbsCertificate.ReadBitString(); } else { SubjectUniqueId = null; } Extensions = new List <X509Extension>(); if (Version > 1 && tbsCertificate.HasData && tbsCertificate.PeekTag() == explicit3) { AsnReader extensions = tbsCertificate.ReadSequence(explicit3); extensions = extensions.ReadSequence(); while (extensions.HasData) { AsnReader extensionReader = extensions.ReadSequence(); string oid = extensionReader.ReadObjectIdentifierAsString(); bool critical = false; if (extensionReader.PeekTag() == Asn1Tag.Boolean) { critical = extensionReader.ReadBoolean(); } byte[] extensionData = extensionReader.ReadOctetString(); Extensions.Add(new X509Extension(oid, extensionData, critical)); if (extensionReader.HasData) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } } } if (tbsCertificate.HasData) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } AsnReader signatureAlgorithm = reader.ReadSequence(); SignatureAlgorithm.AlgorithmId = signatureAlgorithm.ReadObjectIdentifierAsString(); SignatureAlgorithm.Parameters = signatureAlgorithm.HasData ? signatureAlgorithm.GetEncodedValue().ToArray() : Array.Empty <byte>(); if (signatureAlgorithm.HasData) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } SignatureValue = reader.ReadBitString(); if (reader.HasData) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } RawData = rawData; }