public static void GetBMPString_Throws( string description, PublicEncodingRules ruleSet, string inputHex) { byte[] inputData = inputHex.HexToByteArray(); AsnReader reader = new AsnReader(inputData, (AsnEncodingRules)ruleSet); Assert.Throws <CryptographicException>( () => { reader.GetCharacterString(UniversalTagNumber.BMPString); }); }
private static string ReadString(AsnReader tavReader) { Asn1Tag tag = tavReader.PeekTag(); if (tag.TagClass != TagClass.Universal) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } switch ((UniversalTagNumber)tag.TagValue) { case UniversalTagNumber.BMPString: case UniversalTagNumber.IA5String: case UniversalTagNumber.PrintableString: case UniversalTagNumber.UTF8String: case UniversalTagNumber.T61String: return(tavReader.GetCharacterString((UniversalTagNumber)tag.TagValue)); default: throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } }
public static IReadOnlyList <string> GetNameInfo(this X509Certificate2 certificate, string nameTypeOid, bool forIssuer) { ThrowHelpers.CheckNullOrEempty(nameof(nameTypeOid), nameTypeOid); byte[] nameBytes = forIssuer ? certificate.IssuerName.RawData : certificate.SubjectName.RawData; 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); }
public PrincipalName(ref AsnReader reader) { var tag = reader.ReadTagAndLength(out var contentLength, out var bytesRead); reader = reader.AdvanceReader(bytesRead); if (tag.TagClass != TagClass.Universal || tag.TagValue != (int)UniversalTagNumber.Sequence) { throw new InvalidOperationException("Not a sequence but " + tag); } while (reader.HasData) { tag = reader.ReadTagAndLength(out contentLength, out bytesRead); reader = reader.AdvanceReader(bytesRead); if (tag.TagClass == TagClass.ContextSpecific) { switch (tag.TagValue) { case 0: Type = (NameType)(int)reader.GetInteger(); break; case 1: reader = reader.ReadSequence(); var names = new List <string>(); while (reader.HasData) { names.Add(reader.GetCharacterString(new Asn1Tag(UniversalTagNumber.GeneralString), KerberosTags.KerberosStringTag)); } Name = names.ToArray(); break; } } } }
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.GetEncodedValue(); ReadOnlySpan <byte> valueSpan = value.Span; Assert.True(Asn1Tag.TryParse(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.GetCharacterString((UniversalTagNumber)valueTag.TagValue)); Assert.False(valueReader.HasData, "valueReader.HasData"); } Assert.False(attributeTypeAndValue.HasData, $"attributeTypeAndValue.HasData ({label})"); Assert.False(rdn.HasData, $"rdn.HasData ({label})"); }
private static string FindAltNameMatch(byte[] extensionBytes, GeneralNameType matchType, string otherOid) { // If Other, have OID, else, no OID. Debug.Assert( (otherOid == null) == (matchType != GeneralNameType.OtherName), $"otherOid has incorrect nullarity for matchType {matchType}"); Debug.Assert( matchType == GeneralNameType.UniformResourceIdentifier || matchType == GeneralNameType.DnsName || matchType == GeneralNameType.Email || matchType == GeneralNameType.OtherName, $"matchType ({matchType}) is not currently supported"); Debug.Assert( otherOid == null || otherOid == Oids.UserPrincipalName, $"otherOid ({otherOid}) is not supported"); AsnReader reader = new AsnReader(extensionBytes, AsnEncodingRules.DER); AsnReader sequenceReader = reader.ReadSequence(); reader.ThrowIfNotEmpty(); while (sequenceReader.HasData) { GeneralNameAsn.Decode(sequenceReader, out GeneralNameAsn generalName); switch (matchType) { case GeneralNameType.OtherName: // If the OtherName OID didn't match, move to the next entry. if (generalName.OtherName.HasValue && generalName.OtherName.Value.TypeId == otherOid) { // Currently only UPN is supported, which is a UTF8 string per // https://msdn.microsoft.com/en-us/library/ff842518.aspx AsnReader nameReader = new AsnReader(generalName.OtherName.Value.Value, AsnEncodingRules.DER); string udnName = nameReader.GetCharacterString(UniversalTagNumber.UTF8String); nameReader.ThrowIfNotEmpty(); return(udnName); } break; case GeneralNameType.Rfc822Name: if (generalName.Rfc822Name != null) { return(generalName.Rfc822Name); } break; case GeneralNameType.DnsName: if (generalName.DnsName != null) { return(generalName.DnsName); } break; case GeneralNameType.UniformResourceIdentifier: if (generalName.Uri != null) { return(generalName.Uri); } break; } } return(null); }
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); }
public KerberosError(ref AsnReader reader) { var tag = reader.ReadTagAndLength(out var contentLength, out var bytesRead); reader = reader.AdvanceReader(bytesRead); if (tag.TagClass != TagClass.Universal || tag.TagValue != (int)UniversalTagNumber.Sequence) { throw new InvalidOperationException("Not a sequence but " + tag); } while (reader.HasData) { tag = reader.ReadTagAndLength(out contentLength, out bytesRead); reader = reader.AdvanceReader(bytesRead); if (tag.TagClass == TagClass.ContextSpecific) { switch (tag.TagValue) { case 0: // pvno [0] INTEGER (5), ProtocolVersionNumber = (int)reader.GetInteger(); break; case 1: // msg-type [1] INTEGER (30), MessageType = (MessageType)(int)reader.GetInteger(); break; case 2: // ctime [2] KerberosTime OPTIONAL, CTime = reader.GetGeneralizedTime(disallowFractions: true); break; case 3: // cusec [3] Microseconds OPTIONAL, var cusec = reader.GetInteger(); CUsec = new Microseconds((int)cusec); break; case 4: // stime [4] KerberosTime, STime = reader.GetGeneralizedTime(disallowFractions: true); break; case 5: // susec [5] Microseconds, var susec = reader.GetInteger(); SUsec = new Microseconds((int)susec); break; case 6: // error-code [6] Int32, ErrorCode = (KrbErrorCode)(int)reader.GetInteger(); break; case 7: // crealm [7] Realm OPTIONAL, CRealm = reader.GetCharacterString(new Asn1Tag(UniversalTagNumber.GeneralString), KerberosTags.RealmTag); break; case 8: // cname [8] PrincipalName OPTIONAL, CName = new PrincipalName(ref reader); break; case 9: // realm [9] Realm -- service realm --, ServiceRealm = reader.GetCharacterString(new Asn1Tag(UniversalTagNumber.GeneralString), KerberosTags.RealmTag); break; case 10: // sname [10] PrincipalName -- service name --, SName = new PrincipalName(ref reader); break; case 11: // e-text [11] KerberosString OPTIONAL, EText = reader.GetCharacterString(new Asn1Tag(UniversalTagNumber.GeneralString), KerberosTags.KerberosStringTag); break; case 12: // e-data [12] OCTET STRING OPTIONAL EData = new byte[contentLength.Value]; reader.TryCopyOctetStringBytes(EData, out _); break; } } } }