Beispiel #1
0
        public static void ReadBoolean_Failure(
            string description,
            AsnEncodingRules ruleSet,
            string inputHex)
        {
            _ = description;
            byte[] inputData = inputHex.HexToByteArray();

            AsnReader reader = new AsnReader(inputData, ruleSet);
            Asn1Tag   tag    = default(Asn1Tag);

            if (inputData.Length > 0)
            {
                tag = reader.PeekTag();
            }

            if (tag.TagClass == TagClass.Universal)
            {
                Assert.Throws <AsnContentException>(() => reader.ReadBoolean());
            }
            else
            {
                Assert.Throws <AsnContentException>(() => reader.ReadBoolean(tag));
            }

            if (inputData.Length == 0)
            {
                // If we started with nothing, where did the data come from?
                Assert.False(reader.HasData, "reader.HasData");
            }
            else
            {
                // Nothing should have moved
                Assert.True(reader.HasData, "reader.HasData");
            }
        }
Beispiel #2
0
        internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out RecipientEncryptedKeyAsn decoded)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            decoded = default;
            AsnReader sequenceReader = reader.ReadSequence(expectedTag);

            System.Security.Cryptography.Pkcs.Asn1.KeyAgreeRecipientIdentifierAsn.Decode(sequenceReader, out decoded.Rid);

            if (sequenceReader.TryGetPrimitiveOctetStringBytes(out ReadOnlyMemory <byte> tmpEncryptedKey))
            {
                decoded.EncryptedKey = tmpEncryptedKey;
            }
            else
            {
                decoded.EncryptedKey = sequenceReader.ReadOctetString();
            }


            sequenceReader.ThrowIfNotEmpty();
        }
            public override string DecodeOid(byte[] encodedOid)
            {
                Span <byte> emptyInvalidOid = stackalloc byte[2];

                emptyInvalidOid[0] = 0x06;
                emptyInvalidOid[1] = 0x00;

                // Windows compat.
                if (emptyInvalidOid.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);
            }
Beispiel #4
0
        public Pkcs8PrivateKeyInfo(
            Oid algorithmId,
            ReadOnlyMemory <byte>?algorithmParameters,
            ReadOnlyMemory <byte> privateKey,
            bool skipCopies = false)
        {
            if (algorithmId == null)
            {
                throw new ArgumentNullException(nameof(algorithmId));
            }

            if (algorithmParameters?.Length > 0)
            {
                // Read to ensure that there is precisely one legally encoded value.
                AsnReader reader = new AsnReader(algorithmParameters.Value, AsnEncodingRules.BER);
                reader.ReadEncodedValue();
                reader.ThrowIfNotEmpty();
            }

            AlgorithmId         = algorithmId;
            AlgorithmParameters = skipCopies ? algorithmParameters : algorithmParameters?.ToArray();
            PrivateKeyBytes     = skipCopies ? privateKey : privateKey.ToArray();
            Attributes          = new CryptographicAttributeObjectCollection();
        }
Beispiel #5
0
        internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out MessageImprint decoded)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            decoded = default;
            AsnReader sequenceReader = reader.ReadSequence(expectedTag);

            System.Security.Cryptography.Asn1.AlgorithmIdentifierAsn.Decode(sequenceReader, out decoded.HashAlgorithm);

            if (sequenceReader.TryReadPrimitiveOctetStringBytes(out ReadOnlyMemory <byte> tmpHashedMessage))
            {
                decoded.HashedMessage = tmpHashedMessage;
            }
            else
            {
                decoded.HashedMessage = sequenceReader.ReadOctetString();
            }


            sequenceReader.ThrowIfNotEmpty();
        }
Beispiel #6
0
        public static ReadOnlyMemory <byte> DecodeOctetString(ReadOnlyMemory <byte> encodedOctetString)
        {
            AsnReader reader = new AsnReader(encodedOctetString, AsnEncodingRules.BER);

            if (reader.PeekEncodedValue().Length != encodedOctetString.Length)
            {
                throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
            }

            if (reader.TryReadPrimitiveOctetStringBytes(out ReadOnlyMemory <byte> primitiveContents))
            {
                return(primitiveContents);
            }

            byte[] tooBig = new byte[encodedOctetString.Length];

            if (reader.TryCopyOctetStringBytes(tooBig, out int bytesWritten))
            {
                return(tooBig.AsMemory(0, bytesWritten));
            }

            Debug.Fail("TryCopyOctetStringBytes failed with an over-allocated array");
            throw new CryptographicException();
        }
Beispiel #7
0
        internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out OriginatorPublicKeyAsn decoded)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            decoded = default;
            AsnReader sequenceReader = reader.ReadSequence(expectedTag);

            System.Security.Cryptography.Asn1.AlgorithmIdentifierAsn.Decode(sequenceReader, out decoded.Algorithm);

            if (sequenceReader.TryGetPrimitiveBitStringValue(out _, out ReadOnlyMemory <byte> tmpPublicKey))
            {
                decoded.PublicKey = tmpPublicKey;
            }
            else
            {
                decoded.PublicKey = sequenceReader.ReadBitString(out _);
            }


            sequenceReader.ThrowIfNotEmpty();
        }
        public static void TryCopyUTF8StringBytes_Success_CER_MaxPrimitiveLength()
        {
            // CER says that the maximum encoding length for a UTF8String primitive
            // is 1000.
            //
            // So we need 0C [1000] { 1000 anythings }
            // 1000 => 0x3E8, so the length encoding is 82 03 E8.
            // 1000 + 3 + 1 == 1004
            byte[] input = new byte[1004];
            input[0] = 0x0C;
            input[1] = 0x82;
            input[2] = 0x03;
            input[3] = 0xE8;

            // Content
            input[4]    = 0x65;
            input[5]    = 0x65;
            input[1002] = 0x61;
            input[1003] = 0x61;

            byte[] output = new byte[1000];

            AsnReader reader = new AsnReader(input, AsnEncodingRules.CER);

            bool success = reader.TryCopyCharacterStringBytes(
                UniversalTagNumber.UTF8String,
                output,
                out int bytesWritten);

            Assert.True(success, "reader.TryCopyUTF8StringBytes");
            Assert.Equal(1000, bytesWritten);

            Assert.Equal(
                input.AsSpan(4).ByteArrayToHex(),
                output.ByteArrayToHex());
        }
Beispiel #9
0
        /// <summary>
        /// Decode a ECDSA signature from ASN.1.
        /// </summary>
        /// <param name="signature">The signature to decode from ASN.1</param>
        private static byte[] DecodeECDsa(ReadOnlyMemory <byte> signature)
        {
            AsnReader reader    = new AsnReader(signature, AsnEncodingRules.DER);
            var       seqReader = reader.ReadSequence();

            reader.ThrowIfNotEmpty();
            var r = seqReader.ReadIntegerBytes();
            var s = seqReader.ReadIntegerBytes();

            seqReader.ThrowIfNotEmpty();
            if (r.Span[0] == 0)
            {
                r = r.Slice(1);
            }
            if (s.Span[0] == 0)
            {
                s = s.Slice(1);
            }
            var result = new byte[r.Length + s.Length];

            r.CopyTo(new Memory <byte>(result, 0, r.Length));
            s.CopyTo(new Memory <byte>(result, r.Length, s.Length));
            return(result);
        }
        internal static void Decode <T>(AsnReader reader, out T decoded)
            where T : KrbETypeInfo2, new()
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            decoded = new T();

            Asn1Tag   tag = reader.PeekTag();
            AsnReader collectionReader;

            if (tag.HasSameClassAndValue(Asn1Tag.Sequence))
            {
                // Decode SEQUENCE OF for ETypeInfo
                {
                    collectionReader = reader.ReadSequence();
                    var tmpList = new List <KrbETypeInfo2Entry>();
                    KrbETypeInfo2Entry tmpItem;

                    while (collectionReader.HasData)
                    {
                        KrbETypeInfo2Entry.Decode <KrbETypeInfo2Entry>(collectionReader, out KrbETypeInfo2Entry tmp);
                        tmpItem = tmp;
                        tmpList.Add(tmpItem);
                    }

                    decoded.ETypeInfo = tmpList.ToArray();
                }
            }
            else
            {
                throw new CryptographicException();
            }
        }
Beispiel #11
0
        internal static void Decode <T>(AsnReader reader, Asn1Tag expectedTag, out T decoded)
            where T : KrbPaEncTsEnc, new()
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            decoded = new T();

            AsnReader sequenceReader = reader.ReadSequence(expectedTag);
            AsnReader explicitReader;

            explicitReader      = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 0));
            decoded.PaTimestamp = explicitReader.ReadGeneralizedTime();

            explicitReader.ThrowIfNotEmpty();

            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 1)))
            {
                explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 1));

                if (explicitReader.TryReadInt32(out int tmpPaUSec))
                {
                    decoded.PaUSec = tmpPaUSec;
                }
                else
                {
                    explicitReader.ThrowIfNotEmpty();
                }

                explicitReader.ThrowIfNotEmpty();
            }

            sequenceReader.ThrowIfNotEmpty();
        }
        public static void TagMustBeCorrect_Custom(AsnEncodingRules ruleSet)
        {
            byte[]    inputData = { 0x87, 2, (byte)'h', (byte)'i' };
            AsnReader reader    = new AsnReader(inputData, ruleSet);

            const UniversalTagNumber EncodingType = UniversalTagNumber.UTF8String;

            AssertExtensions.Throws <ArgumentException>(
                "expectedTag",
                () => reader.TryReadPrimitiveCharacterStringBytes(Asn1Tag.Null, out _));

            Assert.True(reader.HasData, "HasData after bad universal tag");

            Assert.Throws <AsnContentException>(
                () => reader.TryReadPrimitiveCharacterStringBytes(new Asn1Tag(EncodingType), out _));

            Assert.True(reader.HasData, "HasData after default tag");

            Assert.Throws <AsnContentException>(
                () => reader.TryReadPrimitiveCharacterStringBytes(new Asn1Tag(TagClass.Application, 0), out _));

            Assert.True(reader.HasData, "HasData after wrong custom class");

            Assert.Throws <AsnContentException>(
                () => reader.TryReadPrimitiveCharacterStringBytes(new Asn1Tag(TagClass.ContextSpecific, 1), out _));

            Assert.True(reader.HasData, "HasData after wrong custom tag value");

            Assert.True(
                reader.TryReadPrimitiveCharacterStringBytes(
                    new Asn1Tag(TagClass.ContextSpecific, 7),
                    out ReadOnlyMemory <byte> value));

            Assert.Equal("6869", value.ByteArrayToHex());
            Assert.False(reader.HasData, "HasData after reading value");
        }
Beispiel #13
0
        internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out Asn1SaslCredentials decoded)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            decoded = new Asn1SaslCredentials();
            AsnReader sequenceReader = reader.ReadSequence(expectedTag);


            if (sequenceReader.TryGetPrimitiveOctetStringBytes(out ReadOnlyMemory <byte> tmpMechanism))
            {
                decoded.Mechanism = tmpMechanism;
            }
            else
            {
                decoded.Mechanism = sequenceReader.ReadOctetString();
            }


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(Asn1Tag.PrimitiveOctetString))
            {
                if (sequenceReader.TryGetPrimitiveOctetStringBytes(out ReadOnlyMemory <byte> tmpCredentials))
                {
                    decoded.Credentials = tmpCredentials;
                }
                else
                {
                    decoded.Credentials = sequenceReader.ReadOctetString();
                }
            }


            sequenceReader.ThrowIfNotEmpty();
        }
Beispiel #14
0
        internal static void Decode <T>(AsnReader reader, Asn1Tag expectedTag, out T decoded)
            where T : KrbFastArmoredReq, new()
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            decoded = new T();

            AsnReader sequenceReader = reader.ReadSequence(expectedTag);
            AsnReader explicitReader;

            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0)))
            {
                explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 0));

                KrbFastArmor.Decode <KrbFastArmor>(explicitReader, out KrbFastArmor tmpArmor);
                decoded.Armor = tmpArmor;
                explicitReader.ThrowIfNotEmpty();
            }

            explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 1));
            KrbChecksum.Decode <KrbChecksum>(explicitReader, out KrbChecksum tmpRequestChecksum);
            decoded.RequestChecksum = tmpRequestChecksum;

            explicitReader.ThrowIfNotEmpty();

            explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 2));
            KrbEncryptedData.Decode <KrbEncryptedData>(explicitReader, out KrbEncryptedData tmpEncryptedFastRequest);
            decoded.EncryptedFastRequest = tmpEncryptedFastRequest;

            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.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})");
        }
Beispiel #16
0
        public override unsafe void ImportRSAPublicKey(ReadOnlySpan <byte> source, out int bytesRead)
        {
            fixed(byte *ptr = &MemoryMarshal.GetReference(source))
            {
                using (MemoryManager <byte> manager = new PointerMemoryManager <byte>(ptr, source.Length))
                {
                    AsnReader             reader       = new AsnReader(manager.Memory, AsnEncodingRules.BER);
                    ReadOnlyMemory <byte> firstElement = reader.PeekEncodedValue();

                    SafeRsaHandle key = Interop.Crypto.DecodeRsaPublicKey(firstElement.Span);

                    Interop.Crypto.CheckValidOpenSslHandle(key);

                    FreeKey();
                    _key = new Lazy <SafeRsaHandle>(key);

                    // Use ForceSet instead of the property setter to ensure that LegalKeySizes doesn't interfere
                    // with the already loaded key.
                    ForceSetKeySize(BitsPerByte * Interop.Crypto.RsaSize(key));

                    bytesRead = firstElement.Length;
                }
            }
        }
        public static void TryReadPrimitiveOctetStringBytes_Throws_CER_TooLong()
        {
            // CER says that the maximum encoding length for an OctetString primitive
            // is 1000.
            //
            // So we need 04 [1001] { 1001 0x00s }
            // 1001 => 0x3E9, so the length encoding is 82 03 E9.
            // 1001 + 3 + 1 == 1005
            byte[] input = new byte[1005];
            input[0] = 0x04;
            input[1] = 0x82;
            input[2] = 0x03;
            input[3] = 0xE9;

            AsnReader reader = new AsnReader(input, AsnEncodingRules.CER);

            Assert.Throws <AsnContentException>(
                () => reader.TryReadPrimitiveOctetString(out ReadOnlyMemory <byte> contents));

            Assert.Throws <AsnContentException>(
                () => reader.TryReadOctetString(new byte[input.Length], out _));

            Assert.Throws <AsnContentException>(() => reader.ReadOctetString());
        }
Beispiel #18
0
        public static void TryGetBitStringBytes_Throws_CER_TooLong()
        {
            // CER says that the maximum encoding length for a BitString primitive is
            // 1000 (999 value bytes and 1 unused bit count byte).
            //
            // So we need 03 [1001] { 1001 0x00s }
            // 1001 => 0x3E9, so the length encoding is 82 03 E9.
            // 1001 + 3 + 1 == 1005
            byte[] input = new byte[1005];
            input[0] = 0x03;
            input[1] = 0x82;
            input[2] = 0x03;
            input[3] = 0xE9;

            AsnReader reader = new AsnReader(input, AsnEncodingRules.CER);

            Assert.Throws <CryptographicException>(
                () =>
            {
                reader.TryGetPrimitiveBitStringValue(
                    out int unusedBitCount,
                    out ReadOnlyMemory <byte> contents);
            });
        }
        internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out Asn1ExtendedRequest decoded)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            decoded = new Asn1ExtendedRequest();
            AsnReader sequenceReader = reader.ReadSequence(expectedTag);


            if (sequenceReader.TryGetPrimitiveOctetStringBytes(new Asn1Tag(TagClass.ContextSpecific, 0), out ReadOnlyMemory <byte> tmpName))
            {
                decoded.Name = tmpName;
            }
            else
            {
                decoded.Name = sequenceReader.ReadOctetString(new Asn1Tag(TagClass.ContextSpecific, 0));
            }


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 1)))
            {
                if (sequenceReader.TryGetPrimitiveOctetStringBytes(new Asn1Tag(TagClass.ContextSpecific, 1), out ReadOnlyMemory <byte> tmpValue))
                {
                    decoded.Value = tmpValue;
                }
                else
                {
                    decoded.Value = sequenceReader.ReadOctetString(new Asn1Tag(TagClass.ContextSpecific, 1));
                }
            }


            sequenceReader.ThrowIfNotEmpty();
        }
Beispiel #20
0
        private static bool CanReadNtlmMessage(ReadOnlyMemory <byte> ntlm, out byte[] actualSignature, out BinaryReader reader, out AsnReader asnReader)
        {
            asnReader = null;

            reader = new BinaryReader(new MemoryStream(ntlm.ToArray()));

            actualSignature = reader.ReadBytes(MessageSignature.Length);

            if (actualSignature.SequenceEqual(MessageSignature))
            {
                return(true);
            }

            asnReader = new AsnReader(ntlm, AsnEncodingRules.DER);

            var peekTag = asnReader.PeekTag();

            if (AsnReader.IsExpectedTag(peekTag, GssApplicationTag, UniversalTagNumber.Sequence))
            {
                return(false);
            }

            return(AsnReader.IsExpectedTag(peekTag, NtlmContextTag, UniversalTagNumber.Sequence));
        }
        internal static string FindHttpAiaRecord(byte[] authorityInformationAccess, string recordTypeOid)
        {
            AsnReader reader         = new AsnReader(authorityInformationAccess, AsnEncodingRules.DER);
            AsnReader sequenceReader = reader.ReadSequence();

            reader.ThrowIfNotEmpty();

            while (sequenceReader.HasData)
            {
                AccessDescriptionAsn.Decode(sequenceReader, out AccessDescriptionAsn description);
                if (StringComparer.Ordinal.Equals(description.AccessMethod, recordTypeOid))
                {
                    GeneralNameAsn name = description.AccessLocation;
                    if (name.Uri != null &&
                        Uri.TryCreate(name.Uri, UriKind.Absolute, out Uri uri) &&
                        uri.Scheme == "http")
                    {
                        return(name.Uri);
                    }
                }
            }

            return(null);
        }
        internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out Asn1CompareRequest decoded)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            decoded = new Asn1CompareRequest();
            AsnReader sequenceReader = reader.ReadSequence(expectedTag);


            if (sequenceReader.TryGetPrimitiveOctetStringBytes(out ReadOnlyMemory <byte> tmpEntry))
            {
                decoded.Entry = tmpEntry;
            }
            else
            {
                decoded.Entry = sequenceReader.ReadOctetString();
            }

            Asn1AttributeValueAssertion.Decode(sequenceReader, out decoded.Assertion);

            sequenceReader.ThrowIfNotEmpty();
        }
Beispiel #23
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);
        }
Beispiel #24
0
        private static string X500DistinguishedNameDecode(
            byte[] encodedName,
            bool printOid,
            bool reverse,
            bool quoteIfNeeded,
            string dnSeparator,
            string multiValueSeparator,
            bool addTrailingDelimiter)
        {
            try
            {
                AsnReader x500NameReader         = new AsnReader(encodedName, AsnEncodingRules.DER);
                AsnReader x500NameSequenceReader = x500NameReader.ReadSequence();
                var       rdnReaders             = new List <AsnReader>();

                x500NameReader.ThrowIfNotEmpty();

                while (x500NameSequenceReader.HasData)
                {
                    // To match Windows' behavior, permit multi-value RDN SETs to not
                    // be DER sorted.
                    rdnReaders.Add(x500NameSequenceReader.ReadSetOf(skipSortOrderValidation: true));
                }

                // 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.ReadObjectIdentifier();
                        string    attributeValue = tavReader.ReadAnyAsnString();

                        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());
            }
            catch (AsnContentException e)
            {
                throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e);
            }
        }
Beispiel #25
0
        internal static void Decode <T>(AsnReader reader, Asn1Tag expectedTag, out T decoded)
            where T : KrbEncTicketPart, new()
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            decoded = new T();
            AsnReader sequenceReader = reader.ReadSequence(expectedTag);
            AsnReader explicitReader;
            AsnReader collectionReader;


            explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 0));

            if (explicitReader.TryReadPrimitiveBitStringValue(out _, out ReadOnlyMemory <byte> tmpFlags))
            {
                decoded.Flags = (TicketFlags)tmpFlags.AsLong();
            }
            else
            {
                decoded.Flags = (TicketFlags)explicitReader.ReadBitString(out _).AsLong();
            }

            explicitReader.ThrowIfNotEmpty();


            explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 1));
            KrbEncryptionKey.Decode <KrbEncryptionKey>(explicitReader, out decoded.Key);
            explicitReader.ThrowIfNotEmpty();


            explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 2));
            decoded.CRealm = explicitReader.ReadCharacterString(UniversalTagNumber.GeneralString);
            explicitReader.ThrowIfNotEmpty();


            explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 3));
            KrbPrincipalName.Decode <KrbPrincipalName>(explicitReader, out decoded.CName);
            explicitReader.ThrowIfNotEmpty();


            explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 4));
            KrbTransitedEncoding.Decode <KrbTransitedEncoding>(explicitReader, out decoded.Transited);
            explicitReader.ThrowIfNotEmpty();


            explicitReader   = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 5));
            decoded.AuthTime = explicitReader.ReadGeneralizedTime();
            explicitReader.ThrowIfNotEmpty();


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 6)))
            {
                explicitReader    = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 6));
                decoded.StartTime = explicitReader.ReadGeneralizedTime();
                explicitReader.ThrowIfNotEmpty();
            }


            explicitReader  = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 7));
            decoded.EndTime = explicitReader.ReadGeneralizedTime();
            explicitReader.ThrowIfNotEmpty();


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 8)))
            {
                explicitReader    = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 8));
                decoded.RenewTill = explicitReader.ReadGeneralizedTime();
                explicitReader.ThrowIfNotEmpty();
            }


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 9)))
            {
                explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 9));

                // Decode SEQUENCE OF for CAddr
                {
                    collectionReader = explicitReader.ReadSequence();
                    var            tmpList = new List <KrbHostAddress>();
                    KrbHostAddress tmpItem;

                    while (collectionReader.HasData)
                    {
                        KrbHostAddress.Decode <KrbHostAddress>(collectionReader, out tmpItem);
                        tmpList.Add(tmpItem);
                    }

                    decoded.CAddr = tmpList.ToArray();
                }

                explicitReader.ThrowIfNotEmpty();
            }


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 10)))
            {
                explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 10));

                // Decode SEQUENCE OF for AuthorizationData
                {
                    collectionReader = explicitReader.ReadSequence();
                    var tmpList = new List <KrbAuthorizationData>();
                    KrbAuthorizationData tmpItem;

                    while (collectionReader.HasData)
                    {
                        KrbAuthorizationData.Decode <KrbAuthorizationData>(collectionReader, out tmpItem);
                        tmpList.Add(tmpItem);
                    }

                    decoded.AuthorizationData = tmpList.ToArray();
                }

                explicitReader.ThrowIfNotEmpty();
            }


            sequenceReader.ThrowIfNotEmpty();
        }
Beispiel #26
0
        private static Asn1Tag PeekTag(ReadOnlySequence <byte> request)
        {
            AsnReader reader = new AsnReader(request.First, AsnEncodingRules.DER);

            return(reader.PeekTag());
        }
            public override RSAParameters ExportParameters(bool includePrivateParameters)
            {
                SecKeyPair keys = GetKeys();

                if (includePrivateParameters && keys.PrivateKey == null)
                {
                    throw new CryptographicException(SR.Cryptography_OpenInvalidHandle);
                }

                bool gotKeyBlob = Interop.AppleCrypto.TrySecKeyCopyExternalRepresentation(
                    includePrivateParameters ? keys.PrivateKey ! : keys.PublicKey,
                    out byte[] keyBlob);

                if (!gotKeyBlob)
                {
                    return(ExportParametersFromLegacyKey(keys, includePrivateParameters));
                }

                try
                {
                    if (!includePrivateParameters)
                    {
                        // When exporting a key handle opened from a certificate, it seems to
                        // export as a PKCS#1 blob instead of an X509 SubjectPublicKeyInfo blob.
                        // So, check for that.
                        // NOTE: It doesn't affect macOS Mojave when SecCertificateCopyKey API
                        // is used.
                        RSAParameters key;

                        AsnReader reader         = new AsnReader(keyBlob, AsnEncodingRules.BER);
                        AsnReader sequenceReader = reader.ReadSequence();

                        if (sequenceReader.PeekTag().Equals(Asn1Tag.Integer))
                        {
                            AlgorithmIdentifierAsn ignored = default;
                            RSAKeyFormatHelper.ReadRsaPublicKey(keyBlob, ignored, out key);
                        }
                        else
                        {
                            RSAKeyFormatHelper.ReadSubjectPublicKeyInfo(
                                keyBlob,
                                out int localRead,
                                out key);
                            Debug.Assert(localRead == keyBlob.Length);
                        }
                        return(key);
                    }
                    else
                    {
                        AlgorithmIdentifierAsn ignored = default;
                        RSAKeyFormatHelper.FromPkcs1PrivateKey(
                            keyBlob,
                            ignored,
                            out RSAParameters key);
                        return(key);
                    }
                }
                finally
                {
                    CryptographicOperations.ZeroMemory(keyBlob);
                }
            }
        internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out TbsCertificateAsn decoded)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            decoded = default;
            AsnReader sequenceReader = reader.ReadSequence(expectedTag);
            AsnReader explicitReader;
            AsnReader defaultReader;
            AsnReader collectionReader;


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0)))
            {
                explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 0));

                if (!explicitReader.TryReadInt32(out decoded.Version))
                {
                    explicitReader.ThrowIfNotEmpty();
                }

                explicitReader.ThrowIfNotEmpty();
            }
            else
            {
                defaultReader = new AsnReader(s_defaultVersion, AsnEncodingRules.DER);

                if (!defaultReader.TryReadInt32(out decoded.Version))
                {
                    defaultReader.ThrowIfNotEmpty();
                }
            }

            decoded.SerialNumber = sequenceReader.ReadIntegerBytes();
            System.Security.Cryptography.Asn1.AlgorithmIdentifierAsn.Decode(sequenceReader, out decoded.SignatureAlgorithm);
            if (!sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag((UniversalTagNumber)16)))
            {
                throw new CryptographicException();
            }

            decoded.Issuer = sequenceReader.ReadEncodedValue();
            System.Security.Cryptography.X509Certificates.Asn1.ValidityAsn.Decode(sequenceReader, out decoded.Validity);
            if (!sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag((UniversalTagNumber)16)))
            {
                throw new CryptographicException();
            }

            decoded.Subject = sequenceReader.ReadEncodedValue();
            System.Security.Cryptography.Asn1.SubjectPublicKeyInfoAsn.Decode(sequenceReader, out decoded.SubjectPublicKeyInfo);

            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 1)))
            {
                if (sequenceReader.TryReadPrimitiveBitStringValue(new Asn1Tag(TagClass.ContextSpecific, 1), out _, out ReadOnlyMemory <byte> tmpIssuerUniqueId))
                {
                    decoded.IssuerUniqueId = tmpIssuerUniqueId;
                }
                else
                {
                    decoded.IssuerUniqueId = sequenceReader.ReadBitString(new Asn1Tag(TagClass.ContextSpecific, 1), out _);
                }
            }


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 2)))
            {
                if (sequenceReader.TryReadPrimitiveBitStringValue(new Asn1Tag(TagClass.ContextSpecific, 2), out _, out ReadOnlyMemory <byte> tmpSubjectUniqueId))
                {
                    decoded.SubjectUniqueId = tmpSubjectUniqueId;
                }
                else
                {
                    decoded.SubjectUniqueId = sequenceReader.ReadBitString(new Asn1Tag(TagClass.ContextSpecific, 2), out _);
                }
            }


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 3)))
            {
                explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 3));

                // Decode SEQUENCE OF for Extensions
                {
                    collectionReader = explicitReader.ReadSequence();
                    var tmpList = new List <System.Security.Cryptography.Asn1.X509ExtensionAsn>();
                    System.Security.Cryptography.Asn1.X509ExtensionAsn tmpItem;

                    while (collectionReader.HasData)
                    {
                        System.Security.Cryptography.Asn1.X509ExtensionAsn.Decode(collectionReader, out tmpItem);
                        tmpList.Add(tmpItem);
                    }

                    decoded.Extensions = tmpList.ToArray();
                }

                explicitReader.ThrowIfNotEmpty();
            }


            sequenceReader.ThrowIfNotEmpty();
        }
Beispiel #29
0
        public byte[]? GetOutgoingBlob(byte[]?incomingBlob)
        {
            if (_spnegoMechList == null && incomingBlob.AsSpan().StartsWith(NtlmHeader))
            {
                _ntlmPassthrough = true;
                // Windows often sends pure NTLM instead of proper Negotiate, handle that as passthrough
                byte[]? outgoingBlob = _ntlmServer.GetOutgoingBlob(incomingBlob);
                IsAuthenticated      = _ntlmServer.IsAuthenticated;
                return(outgoingBlob);
            }

            Assert.False(_ntlmPassthrough);

            AsnReader reader = new AsnReader(incomingBlob, AsnEncodingRules.DER);

            if (_spnegoMechList == null)
            {
                AsnReader initialContextTokenReader = reader.ReadSequence(new Asn1Tag(TagClass.Application, 0));

                string spNegoOid = initialContextTokenReader.ReadObjectIdentifier();
                Assert.Equal(SpnegoOid, spNegoOid);

                AsnReader negTokenInitReader   = initialContextTokenReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegotiationToken.NegTokenInit)).ReadSequence();
                AsnReader mechTypesOuterReader = negTokenInitReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenInit.MechTypes));
                _spnegoMechList = mechTypesOuterReader.PeekEncodedValue().ToArray();

                bool      hasNtlm         = false;
                bool      isNtlmPreferred = false;
                bool      first           = true;
                AsnReader mechTypesReader = mechTypesOuterReader.ReadSequence();
                while (mechTypesReader.HasData)
                {
                    string mechType = mechTypesReader.ReadObjectIdentifier();
                    if (mechType == NtlmOid)
                    {
                        hasNtlm         = true;
                        isNtlmPreferred = first;
                    }
                    first = false;
                }

                // Skip context flags, if present
                if (negTokenInitReader.HasData && negTokenInitReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenInit.ReqFlags)))
                {
                    negTokenInitReader.ReadSequence();
                }

                byte[]? mechToken = null;
                if (negTokenInitReader.HasData && negTokenInitReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenInit.MechToken)))
                {
                    AsnReader mechTokenReader = negTokenInitReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenInit.MechToken));
                    mechToken = mechTokenReader.ReadOctetString();
                    Assert.False(mechTokenReader.HasData);
                }

                byte[]? mechListMIC = null;
                if (negTokenInitReader.HasData && negTokenInitReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenInit.MechListMIC)))
                {
                    AsnReader mechListMICReader = negTokenInitReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenInit.MechListMIC));
                    mechListMIC = mechListMICReader.ReadOctetString();
                    Assert.False(mechListMICReader.HasData);
                }

                Assert.True(hasNtlm);

                // If the preferred mechanism was NTLM then proceed with the given token
                byte[]? outgoingBlob = null;
                if (isNtlmPreferred && mechToken != null)
                {
                    Assert.Null(mechListMIC);
                    outgoingBlob = _ntlmServer.GetOutgoingBlob(mechToken);
                }

                // Generate reply
                AsnWriter writer = new AsnWriter(AsnEncodingRules.DER);
                using (writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegotiationToken.NegTokenResp)))
                {
                    using (writer.PushSequence())
                    {
                        using (writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenResp.NegState)))
                        {
                            if (RequestMIC)
                            {
                                writer.WriteEnumeratedValue(NegState.RequestMic);
                            }
                            else
                            {
                                writer.WriteEnumeratedValue(NegState.AcceptIncomplete);
                            }
                        }

                        using (writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenResp.SupportedMech)))
                        {
                            writer.WriteObjectIdentifier(NtlmOid);
                        }

                        if (outgoingBlob != null)
                        {
                            using (writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenResp.ResponseToken)))
                            {
                                writer.WriteOctetString(outgoingBlob);
                            }
                        }
                    }
                }

                return(writer.Encode());
            }
            else
            {
                AsnReader negTokenRespReader = reader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegotiationToken.NegTokenResp)).ReadSequence();

                Assert.True(negTokenRespReader.HasData);
                NegState?clientState;
                if (negTokenRespReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenResp.NegState)))
                {
                    AsnReader valueReader = negTokenRespReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenResp.NegState));
                    clientState = valueReader.ReadEnumeratedValue <NegState>();
                    Assert.False(valueReader.HasData);

                    Assert.NotEqual(NegState.Reject, clientState);
                    Assert.NotEqual(NegState.RequestMic, clientState);
                }

                // Client should not send mechanism
                Assert.False(negTokenRespReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenResp.SupportedMech)));

                byte[]? mechToken = null;
                if (negTokenRespReader.HasData && negTokenRespReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenResp.ResponseToken)))
                {
                    AsnReader mechTokenReader = negTokenRespReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenResp.ResponseToken));
                    mechToken = mechTokenReader.ReadOctetString();
                    Assert.False(mechTokenReader.HasData);
                }

                byte[]? mechListMIC = null;
                if (negTokenRespReader.HasData && negTokenRespReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenResp.MechListMIC)))
                {
                    AsnReader mechListMICReader = negTokenRespReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenResp.MechListMIC));
                    mechListMIC = mechListMICReader.ReadOctetString();
                    Assert.False(mechListMICReader.HasData);
                }

                Assert.NotNull(mechToken);
                byte[]? outgoingBlob = _ntlmServer.GetOutgoingBlob(mechToken);

                if (_ntlmServer.IsAuthenticated)
                {
                    if (RequestMIC)
                    {
                        Assert.NotNull(mechListMIC);
                    }

                    // Validate mechListMIC, if present
                    if (mechListMIC is not null)
                    {
                        _ntlmServer.VerifyMIC(_spnegoMechList, mechListMIC);
                    }
                }
                else
                {
                    Assert.Null(mechListMIC);
                }

                // Generate reply
                AsnWriter writer = new AsnWriter(AsnEncodingRules.DER);
                using (writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegotiationToken.NegTokenResp)))
                {
                    using (writer.PushSequence())
                    {
                        using (writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenResp.NegState)))
                        {
                            if (_ntlmServer.IsAuthenticated)
                            {
                                writer.WriteEnumeratedValue(NegState.AcceptCompleted);
                            }
                            else if (outgoingBlob != null)
                            {
                                writer.WriteEnumeratedValue(NegState.AcceptIncomplete);
                            }
                            else
                            {
                                writer.WriteEnumeratedValue(NegState.Reject);
                            }
                        }

                        if (outgoingBlob != null)
                        {
                            using (writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenResp.ResponseToken)))
                            {
                                writer.WriteOctetString(outgoingBlob);
                            }
                        }

                        if (mechListMIC != null)
                        {
                            using (writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenResp.MechListMIC)))
                            {
                                Span <byte> mic = stackalloc byte[16];
                                _ntlmServer.GetMIC(_spnegoMechList, mic);
                                writer.WriteOctetString(mic);

                                // MS-SPNG section 3.2.5.1 NTLM RC4 Key State for MechListMIC and First Signed Message
                                // specifies that the RC4 sealing keys are reset back to the initial state for the
                                // first message.
                                _ntlmServer.ResetKeys();
                            }
                        }
                    }
                }

                IsAuthenticated = _ntlmServer.IsAuthenticated;

                return(writer.Encode());
            }
        }
Beispiel #30
0
        public static void TryCopyIA5StringBytes_Success_CER_MinConstructedLength()
        {
            // CER says that the maximum encoding length for a IA5String primitive
            // is 1000, and that a constructed form must be used for values greater
            // than 1000 bytes, with segments dividing up for each thousand
            // [1000, 1000, ..., len%1000].
            //
            // So our smallest constructed form is 1001 bytes, [1000, 1]
            //
            // 36 80 (indefinite constructed IA5 string)
            //    04 82 03 E9 (primitive octet string, 1000 bytes)
            //       [1000 content bytes]
            //    04 01 (primitive octet string, 1 byte)
            //       pp
            //    00 00 (end of contents, 0 bytes)
            // 1011 total.
            byte[] input  = new byte[1011];
            int    offset = 0;

            // CONSTRUCTED IA5STRING (Indefinite)
            input[offset++] = 0x36;
            input[offset++] = 0x80;
            // OCTET STRING (1000)
            input[offset++] = 0x04;
            input[offset++] = 0x82;
            input[offset++] = 0x03;
            input[offset++] = 0xE8;

            // Primitive 1: (65 65 :: 61 61) (1000)
            input[offset++] = 0x65;
            input[offset]   = 0x65;
            offset         += 997;
            input[offset++] = 0x61;
            input[offset++] = 0x61;

            // OCTET STRING (1)
            input[offset++] = 0x04;
            input[offset++] = 0x01;

            // Primitive 2: One more byte
            input[offset] = 0x2E;

            byte[] expected = new byte[1001];
            offset             = 0;
            expected[offset++] = 0x65;
            expected[offset]   = 0x65;
            offset            += 997;
            expected[offset++] = 0x61;
            expected[offset++] = 0x61;
            expected[offset]   = 0x2E;

            byte[] output = new byte[1001];

            AsnReader reader = new AsnReader(input, AsnEncodingRules.CER);

            bool success = reader.TryCopyIA5StringBytes(output,
                                                        out int bytesWritten);

            Assert.True(success, "reader.TryCopyIA5StringBytes");
            Assert.Equal(1001, bytesWritten);

            Assert.Equal(
                expected.ByteArrayToHex(),
                output.ByteArrayToHex());
        }