示例#1
0
        internal static string ReadAnyAsnString(this 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.NumericString:
            case UniversalTagNumber.PrintableString:
            case UniversalTagNumber.UTF8String:
            case UniversalTagNumber.T61String:
                // .NET's string comparisons start by checking the length, so a trailing
                // NULL character which was literally embedded in the DER would cause a
                // failure in .NET whereas it wouldn't have with strcmp.
                return(tavReader.ReadCharacterString((UniversalTagNumber)tag.TagValue).TrimEnd('\0'));

            default:
                throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
            }
        }
示例#2
0
        public static void GetIA5String_Throws(
            string description,
            PublicEncodingRules ruleSet,
            string inputHex)
        {
            byte[]    inputData = inputHex.HexToByteArray();
            AsnReader reader    = new AsnReader(inputData, (AsnEncodingRules)ruleSet);

            Assert.Throws <CryptographicException>(
                () => reader.ReadCharacterString(UniversalTagNumber.IA5String));
        }
示例#3
0
        public static void GetIA5String_Success(
            PublicEncodingRules ruleSet,
            string inputHex,
            string expectedValue)
        {
            byte[]    inputData = inputHex.HexToByteArray();
            AsnReader reader    = new AsnReader(inputData, (AsnEncodingRules)ruleSet);
            string    value     = reader.ReadCharacterString(UniversalTagNumber.IA5String);

            Assert.Equal(expectedValue, value);
        }
示例#4
0
        public static void GetIA5String_Throws(
            string description,
            AsnEncodingRules ruleSet,
            string inputHex)
        {
            _ = description;
            byte[]    inputData = inputHex.HexToByteArray();
            AsnReader reader    = new AsnReader(inputData, ruleSet);

            Assert.Throws <AsnContentException>(
                () => reader.ReadCharacterString(UniversalTagNumber.IA5String));
        }
示例#5
0
        private static bool TryReadBmpString(ReadOnlyMemory <byte> bmpString, out string read)
        {
            try
            {
                AsnReader reader = new AsnReader(bmpString, AsnEncodingRules.BER);
                read = reader.ReadCharacterString(UniversalTagNumber.BMPString);
                return(true);
            }
            catch (CryptographicException)
            {
            }

            read = null;
            return(false);
        }
示例#6
0
        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.ReadObjectIdentifier());

            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})");
        }
示例#7
0
        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.ReadCharacterString(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);
        }
示例#8
0
        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.TryReadPrimitiveBitString(
                    out int unusedBitCount,
                    out ReadOnlyMemory <byte> signature),
                "certReader.TryReadPrimitiveBitStringValue");

            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.ReadObjectIdentifier());
            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.ReadObjectIdentifier());
            spkiAlgorithm.ReadNull();
            Assert.False(spkiAlgorithm.HasData, "spkiAlgorithm.HasData");

            Assert.True(
                subjectPublicKeyInfo.TryReadPrimitiveBitString(
                    out unusedBitCount,
                    out ReadOnlyMemory <byte> encodedPublicKey),
                "subjectPublicKeyInfo.TryReadBitStringBytes");

            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.ReadObjectIdentifier());
            Assert.True(sanExtension.TryReadPrimitiveOctetString(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(UniversalTagNumber.IA5String, dnsName));
            Assert.Equal("wwwqa.microsoft.com", sanExtensionValue.ReadCharacterString(UniversalTagNumber.IA5String, dnsName));
            Assert.False(sanExtensionValue.HasData, "sanExtensionValue.HasData");

            AsnReader basicConstraints = extensions.ReadSequence();

            Assert.Equal("2.5.29.19", basicConstraints.ReadObjectIdentifier());
            Assert.True(basicConstraints.TryReadPrimitiveOctetString(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.ReadObjectIdentifier());
            Assert.True(keyUsageExtension.ReadBoolean(), "keyUsageExtension.ReadBoolean() (IsCritical)");
            Assert.True(keyUsageExtension.TryReadPrimitiveOctetString(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.ReadObjectIdentifier());
            sigAlgReader.ReadNull();
            Assert.False(sigAlgReader.HasData);
        }
示例#9
0
        public static void ExpectedTag_IgnoresConstructed(
            AsnEncodingRules ruleSet,
            string inputHex,
            TagClass tagClass,
            int tagValue)
        {
            byte[]    inputData   = inputHex.HexToByteArray();
            Asn1Tag   correctCons = new Asn1Tag(tagClass, tagValue, true);
            Asn1Tag   correctPrim = new Asn1Tag(tagClass, tagValue, false);
            AsnReader reader      = new AsnReader(inputData, ruleSet);

            Assert.True(
                reader.TryGetIA5StringBytes(
                    correctCons,
                    out ReadOnlyMemory <byte> val1));

            Assert.False(reader.HasData);

            reader = new AsnReader(inputData, ruleSet);

            Assert.True(
                reader.TryGetIA5StringBytes(
                    correctPrim,
                    out ReadOnlyMemory <byte> val2));

            Assert.False(reader.HasData);

            Assert.Equal(val1.ByteArrayToHex(), val2.ByteArrayToHex());

#if NETCOREAPP
            string expected = Encoding.ASCII.GetString(val1.Span);
#else
            string expected = Encoding.ASCII.GetString(val1.ToArray());
#endif

            reader = new AsnReader(inputData, ruleSet);
            Assert.Equal(expected, reader.ReadCharacterString(UniversalTagNumber.IA5String, correctPrim));

            reader = new AsnReader(inputData, ruleSet);
            Assert.Equal(expected, reader.ReadCharacterString(UniversalTagNumber.IA5String, correctCons));

            char[] output = new char[28];

            reader = new AsnReader(inputData, ruleSet);

            Assert.True(
                reader.TryReadCharacterString(
                    output.AsSpan(1),
                    UniversalTagNumber.IA5String,
                    out int charsWritten,
                    correctPrim));

            Assert.Equal(expected, output.AsSpan(1, charsWritten).ToString());

            reader = new AsnReader(inputData, ruleSet);

            Assert.True(
                reader.TryReadCharacterString(
                    output.AsSpan(2),
                    UniversalTagNumber.IA5String,
                    out charsWritten,
                    correctCons));

            Assert.Equal(expected, output.AsSpan(2, charsWritten).ToString());
        }