/// <summary>
 /// Initializes a new instance of the <see cref="Asn1TagInfo"/> struct.
 /// </summary>
 /// <param name="asn1SnmpTag">The asn1 SNMP tag.</param>
 /// <param name="constructType">Type of the construct.</param>
 public Asn1TagInfo(Asn1SnmpTag asn1SnmpTag, ConstructType constructType)
 {
     this.Asn1ClassType = Asn1Class.Application;
     this.Asn1ConstructType = constructType;
     this.Asn1SnmpTagType = asn1SnmpTag;
     this.Asn1TagType = Asn1Tag.NotAsn1Data;
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="Asn1TagInfo"/> struct.
 /// </summary>
 /// <param name="asn1Tag">The asn1 tag.</param>
 /// <param name="constructType">Type of the construct.</param>
 /// <param name="asn1Class">The asn1 class.</param>
 public Asn1TagInfo(Asn1Tag asn1Tag, ConstructType constructType, Asn1Class asn1Class)
 {
     this.Asn1ClassType = asn1Class;
     this.Asn1ConstructType = constructType;
     this.Asn1SnmpTagType = Asn1SnmpTag.NotSnmpData;
     this.Asn1TagType = asn1Tag;
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="Asn1TagInfo"/> struct.
 /// </summary>
 /// <param name="asn1Tag">The asn1 tag.</param>
 /// <param name="constructType">Type of the construct.</param>
 public Asn1TagInfo(Asn1Tag asn1Tag, ConstructType constructType)
 {
     this.Asn1ClassType = Asn1Class.Universal;
     this.Asn1ConstructType = constructType;
     this.Asn1SnmpTagType = Asn1SnmpTag.NotSnmpData;
     this.Asn1TagType = asn1Tag;
 }
        public static DateTime GetUtcTime(Asn1Tag tag)
        {
            byte[] data = tag.Data;
            // YYMMDDhhmmssZ
            if (data.Length != 13) throw new IOException("Invalid UTC time, data length is not 13.");

            for (int i = 0; i < 12; i++)
            {
                if (data[i] < '0' || tag.Data[i] > '9')
                    throw new IOException("Invalid UTC time, contains illegal character.");
            }
            if (data[12] != 'Z')
                throw new IOException("Invalid UTC time, doesn't contain Z.");

            int year, month, day, hour, minute, second;
            year = GetNDigitValue(data, 0, 2);
            month = GetNDigitValue(data, 2, 2);
            day = GetNDigitValue(data, 4, 2);
            hour = GetNDigitValue(data, 6, 2);
            minute = GetNDigitValue(data, 8, 2);
            second = GetNDigitValue(data, 10, 2);

            year += (year < 86) ? 2000 : 1900;

            DateTime utcTime = new DateTime(year, month, day, hour, minute, second);

            return utcTime;
        }
Exemple #5
0
        public void ShowAsn1(Asn1Tag root)
        {
            treeView1.Nodes.Clear();
            Asn1TreeNode treeNode = new Asn1TreeNode(root);
            treeView1.Nodes.Add(treeNode);

            AddSubNodes(treeNode, root);
            treeView1.ExpandAll();
        }
        public static string GetDataString(Asn1Tag tag)
        {
            if (tag.Class == Asn1.Class.Universal)
            {
                switch ((Asn1.TagNumber)tag.Identifier)
                {
                    case Asn1.TagNumber.ObjectIdentifier:
                        return GetOidDataString(tag);
                    case Asn1.TagNumber.BitString:
                        return GetBitDataString(tag);
                    case Asn1.TagNumber.PrintableString:
                        return GetPrintableDataString(tag, Encoding.ASCII);
                    case Asn1.TagNumber.Utrf8String:
                        return GetPrintableDataString(tag, Encoding.UTF8);
                    case Asn1.TagNumber.UtcTime:
                        return GetUtcDataString(tag);
                }
            }

            return GetHexDataString(tag.Data, 0, Math.Min(64, tag.Data.Length));
        }
Exemple #7
0
        public Asn1TreeNode(Asn1Tag asn1Node)
        {
            this.Asn1Node = asn1Node;

            // Use data length instead of full byte count
            this.Text = string.Concat("(", asn1Node.StartByte, ", ", (asn1Node.IndefiniteLength ? "inf" : Asn1.GetTotalByteCount(asn1Node).ToString()), ") ", asn1Node.ShortDescription);
            if (!asn1Node.Constructed)
            {
                this.Text += string.Concat(": ", asn1Node.DataText);
            }
            if (asn1Node.Class == Asn1.Class.Universal && asn1Node.Identifier <= 31)
            {
                this.ImageIndex = Asn1ImageIndexes[asn1Node.Identifier];
            }
            else
            {
                this.ImageIndex = 32;
            }
            this.SelectedImageIndex = this.ImageIndex;

            this.ContextMenu = CreateContextMenu();
        }
Exemple #8
0
        public void OpenFile(string file)
        {
            SuspendLayout();

            try
            {
                using (FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read))
                {
                    try
                    {
                        byte[] pemData = PemReader.ReadPem(fs);

                        using (MemoryStream ms = new MemoryStream(pemData))
                        {
                            rootNode = Asn1.Decode(ms);
                        }
                    }
                    catch (ArgumentException)
                    {
                        fs.Position = 0;
                        rootNode = Asn1.Decode(fs);
                    }

                    stsFile.Text = string.Concat("File: ", file);
                    stsSize.Text = string.Concat("Size: ", fs.Length.ToString(), " bytes");
                    Text = string.Concat(TitleBase, " - ", file);
                }

                ShowAsn1(rootNode);
                UpdateHexViewerData();
            }
            catch (Exception ex)
            {
                MessageBox.Show(this, "Error while opening file: " + ex.Message, "Error opening file", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
            }

            ResumeLayout();
        }
Exemple #9
0
 public static long GetTotalByteCount(Asn1Tag node)
 {
     if (node.Constructed)
     {
         return Asn1.EncodeHeader(node).Length + node.Sum(subTag => GetTotalByteCount(subTag));
     }
     else
     {
         return Asn1.EncodeHeader(node).Length + node.Data.Length;
     }
 }
Exemple #10
0
 public static void ExportText(string filename, Asn1Tag node)
 {
     CallWithFilestream(ExportText, filename, node);
 }
Exemple #11
0
 public static void EncodeHeader(Stream stream, Asn1Tag node)
 {
     byte[] header = EncodeHeader(node);
     stream.Write(header, 0, header.Length);
 }
Exemple #12
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Asn1TagInfo"/> struct.
 /// </summary>
 /// <param name="asn1Class">The asn1 class.</param>
 /// <param name="constructType">Type of the construct.</param>
 /// <param name="tagType">Type of the tag.</param>
 internal Asn1TagInfo(int asn1Class, int constructType, int tagType)
 {
     this.Asn1ClassType = (Asn1Class)asn1Class;
     this.Asn1ConstructType = (ConstructType)constructType;
     if (this.Asn1ClassType == Asn1Class.Application)
     {
         this.Asn1SnmpTagType = (Asn1SnmpTag)tagType;
         this.Asn1TagType = Asn1Tag.NotAsn1Data;
     }
     else
     {
         this.Asn1TagType = (Asn1Tag)tagType;
         this.Asn1SnmpTagType = Asn1SnmpTag.NotSnmpData;
     }
 }
        internal static void Decode(ref AsnValueReader reader, Asn1Tag expectedTag, ReadOnlyMemory <byte> rebind, out Rfc3161TimeStampReq decoded)
        {
            decoded = default;
            AsnValueReader      sequenceReader = reader.ReadSequence(expectedTag);
            AsnValueReader      defaultReader;
            AsnValueReader      collectionReader;
            ReadOnlySpan <byte> rebindSpan = rebind.Span;
            int offset;
            ReadOnlySpan <byte> tmpSpan;


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

            System.Security.Cryptography.Pkcs.Asn1.MessageImprint.Decode(ref sequenceReader, rebind, out decoded.MessageImprint);

            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(Asn1Tag.ObjectIdentifier))
            {
                decoded.ReqPolicy = sequenceReader.ReadObjectIdentifier();
            }


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(Asn1Tag.Integer))
            {
                tmpSpan       = sequenceReader.ReadIntegerBytes();
                decoded.Nonce = rebindSpan.Overlaps(tmpSpan, out offset) ? rebind.Slice(offset, tmpSpan.Length) : tmpSpan.ToArray();
            }


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(Asn1Tag.Boolean))
            {
                decoded.CertReq = sequenceReader.ReadBoolean();
            }
            else
            {
                defaultReader   = new AsnValueReader(s_defaultCertReq, AsnEncodingRules.DER);
                decoded.CertReq = defaultReader.ReadBoolean();
            }


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0)))
            {
                // Decode SEQUENCE OF for Extensions
                {
                    collectionReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 0));
                    var tmpList = new List <System.Security.Cryptography.Asn1.X509ExtensionAsn>();
                    System.Security.Cryptography.Asn1.X509ExtensionAsn tmpItem;

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

                    decoded.Extensions = tmpList.ToArray();
                }
            }


            sequenceReader.ThrowIfNotEmpty();
        }
Exemple #14
0
 internal abstract void WriteString(AsnWriter writer, Asn1Tag tag, string s);
Exemple #15
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.TryReadPrimitiveBitStringValue(
                    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.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.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.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);
        }
Exemple #16
0
        private void AddSubNodes(TreeNode rootTree, Asn1Tag rootAsn1)
        {
            foreach (Asn1Tag subAsn1 in rootAsn1)
            {
                Asn1TreeNode subTree = new Asn1TreeNode(subAsn1);
                rootTree.Nodes.Add(subTree);

                AddSubNodes(subTree, subAsn1);
            }
        }
        public void SealWithMac(
            ReadOnlySpan <char> password,
            HashAlgorithmName hashAlgorithm,
            int iterationCount)
        {
            if (iterationCount < 1)
            {
                throw new ArgumentOutOfRangeException(nameof(iterationCount));
            }
            if (IsSealed)
            {
                throw new InvalidOperationException(SR.Cryptography_Pkcs12_PfxIsSealed);
            }

            byte[]? rentedAuthSafe = null;
            Span <byte> authSafeSpan = default;

            byte[]? rentedMac = null;
            Span <byte> macSpan = default;
            Span <byte> salt    = stackalloc byte[0];

            try
            {
                AsnWriter contentsWriter = new AsnWriter(AsnEncodingRules.BER);

                using (IncrementalHash hasher = IncrementalHash.CreateHash(hashAlgorithm))
                {
                    contentsWriter.PushSequence();
                    if (_contents != null)
                    {
                        foreach (ContentInfoAsn contentInfo in _contents)
                        {
                            contentInfo.Encode(contentsWriter);
                        }
                    }
                    contentsWriter.PopSequence();

                    rentedAuthSafe = CryptoPool.Rent(contentsWriter.GetEncodedLength());

                    if (!contentsWriter.TryEncode(rentedAuthSafe, out int written))
                    {
                        Debug.Fail("TryEncode failed with a pre-allocated buffer");
                        throw new InvalidOperationException();
                    }

                    authSafeSpan = rentedAuthSafe.AsSpan(0, written);

                    // Get an array of the proper size for the hash.
                    byte[] macKey = hasher.GetHashAndReset();
                    rentedMac = CryptoPool.Rent(macKey.Length);
                    macSpan   = rentedMac.AsSpan(0, macKey.Length);

                    // Since the biggest supported hash is SHA-2-512 (64 bytes), the
                    // 128-byte cap here shouldn't ever come into play.
                    Debug.Assert(macKey.Length <= 128);
                    salt = stackalloc byte[Math.Min(macKey.Length, 128)];
                    RandomNumberGenerator.Fill(salt);

                    Pkcs12Kdf.DeriveMacKey(
                        password,
                        hashAlgorithm,
                        iterationCount,
                        salt,
                        macKey);

                    using (IncrementalHash mac = IncrementalHash.CreateHMAC(hashAlgorithm, macKey))
                    {
                        mac.AppendData(authSafeSpan);

                        if (!mac.TryGetHashAndReset(macSpan, out int bytesWritten) || bytesWritten != macSpan.Length)
                        {
                            Debug.Fail($"TryGetHashAndReset wrote {bytesWritten} of {macSpan.Length} bytes");
                            throw new CryptographicException();
                        }
                    }
                }

                // https://tools.ietf.org/html/rfc7292#section-4
                //
                // PFX ::= SEQUENCE {
                //   version    INTEGER {v3(3)}(v3,...),
                //   authSafe   ContentInfo,
                //   macData    MacData OPTIONAL
                // }
                AsnWriter writer = new AsnWriter(AsnEncodingRules.BER);
                {
                    writer.PushSequence();

                    writer.WriteInteger(3);

                    writer.PushSequence();
                    {
                        writer.WriteObjectIdentifierForCrypto(Oids.Pkcs7Data);

                        Asn1Tag contextSpecific0 = new Asn1Tag(TagClass.ContextSpecific, 0);

                        writer.PushSequence(contextSpecific0);
                        {
                            writer.WriteOctetString(authSafeSpan);
                            writer.PopSequence(contextSpecific0);
                        }

                        writer.PopSequence();
                    }

                    // https://tools.ietf.org/html/rfc7292#section-4
                    //
                    // MacData ::= SEQUENCE {
                    //   mac        DigestInfo,
                    //   macSalt    OCTET STRING,
                    //   iterations INTEGER DEFAULT 1
                    //   -- Note: The default is for historical reasons and its use is
                    //   -- deprecated.
                    // }
                    writer.PushSequence();
                    {
                        writer.PushSequence();
                        {
                            writer.PushSequence();
                            {
                                writer.WriteObjectIdentifierForCrypto(PkcsHelpers.GetOidFromHashAlgorithm(hashAlgorithm));
                                writer.PopSequence();
                            }

                            writer.WriteOctetString(macSpan);
                            writer.PopSequence();
                        }

                        writer.WriteOctetString(salt);

                        if (iterationCount > 1)
                        {
                            writer.WriteInteger(iterationCount);
                        }

                        writer.PopSequence();
                    }

                    writer.PopSequence();
                    _sealedData = writer.Encode();
                }
            }
            finally
            {
                CryptographicOperations.ZeroMemory(macSpan);
                CryptographicOperations.ZeroMemory(authSafeSpan);

                if (rentedMac != null)
                {
                    // Already cleared
                    CryptoPool.Return(rentedMac, clearSize: 0);
                }

                if (rentedAuthSafe != null)
                {
                    // Already cleared
                    CryptoPool.Return(rentedAuthSafe, clearSize: 0);
                }
            }
        }
Exemple #18
0
        internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out Asn1BindResponse decoded)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

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

            decoded.ResultCode = sequenceReader.GetEnumeratedValue <ResultCode>();

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


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


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 3)))
            {
                // Decode SEQUENCE OF for Referral
                {
                    collectionReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 3));
                    var tmpList = new List <ReadOnlyMemory <byte> >();
                    ReadOnlyMemory <byte> tmpItem;

                    while (collectionReader.HasData)
                    {
                        if (collectionReader.TryGetPrimitiveOctetStringBytes(out ReadOnlyMemory <byte> tmp))
                        {
                            tmpItem = tmp;
                        }
                        else
                        {
                            tmpItem = collectionReader.ReadOctetString();
                        }

                        tmpList.Add(tmpItem);
                    }

                    decoded.Referral = tmpList.ToArray();
                }
            }


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


            sequenceReader.ThrowIfNotEmpty();
        }
Exemple #19
0
        internal static void Decode(ref AsnValueReader reader, Asn1Tag expectedTag, ReadOnlyMemory <byte> rebind, out SignedDataAsn decoded)
        {
            decoded = default;
            AsnValueReader      sequenceReader = reader.ReadSequence(expectedTag);
            AsnValueReader      collectionReader;
            ReadOnlySpan <byte> rebindSpan = rebind.Span;
            int offset;
            ReadOnlySpan <byte> tmpSpan;


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


            // Decode SEQUENCE OF for DigestAlgorithms
            {
                collectionReader = sequenceReader.ReadSetOf();
                var tmpList = new List <AlgorithmIdentifierAsn>();
                AlgorithmIdentifierAsn tmpItem;

                while (collectionReader.HasData)
                {
                    AlgorithmIdentifierAsn.Decode(ref collectionReader, rebind, out tmpItem);
                    tmpList.Add(tmpItem);
                }

                decoded.DigestAlgorithms = tmpList.ToArray();
            }

            EncapsulatedContentInfoAsn.Decode(ref sequenceReader, rebind, out decoded.EncapContentInfo);
            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0)))
            {
                // Decode SEQUENCE OF for CertificateSet
                {
                    collectionReader = sequenceReader.ReadSetOf(new Asn1Tag(TagClass.ContextSpecific, 0));
                    var tmpList = new List <CertificateChoiceAsn>();
                    CertificateChoiceAsn tmpItem;

                    while (collectionReader.HasData)
                    {
                        CertificateChoiceAsn.Decode(ref collectionReader, rebind, out tmpItem);
                        tmpList.Add(tmpItem);
                    }

                    decoded.CertificateSet = tmpList.ToArray();
                }
            }


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 1)))
            {
                // Decode SEQUENCE OF for Crls
                {
                    collectionReader = sequenceReader.ReadSetOf(new Asn1Tag(TagClass.ContextSpecific, 1));
                    var tmpList = new List <ReadOnlyMemory <byte> >();
                    ReadOnlyMemory <byte> tmpItem;

                    while (collectionReader.HasData)
                    {
                        tmpSpan = collectionReader.ReadEncodedValue();
                        tmpItem = rebindSpan.Overlaps(tmpSpan, out offset) ? rebind.Slice(offset, tmpSpan.Length) : tmpSpan.ToArray();
                        tmpList.Add(tmpItem);
                    }

                    decoded.Crls = tmpList.ToArray();
                }
            }


            // Decode SEQUENCE OF for SignerInfos
            {
                collectionReader = sequenceReader.ReadSetOf();
                var           tmpList = new List <SignerInfoAsn>();
                SignerInfoAsn tmpItem;

                while (collectionReader.HasData)
                {
                    SignerInfoAsn.Decode(ref collectionReader, rebind, out tmpItem);
                    tmpList.Add(tmpItem);
                }

                decoded.SignerInfos = tmpList.ToArray();
            }


            sequenceReader.ThrowIfNotEmpty();
        }
Exemple #20
0
 // T-REC-X.690-201508 sec 8.12
 // The writer claims SetOf, and not Set, so as to avoid the field
 // ordering clause of T-REC-X.690-201508 sec 9.3
 private void PushSetOfCore(Asn1Tag tag)
 {
     PushTag(tag, UniversalTagNumber.SetOf);
 }
        public static void ReadSequenceOf_PreservesOptions(AsnEncodingRules ruleSet)
        {
            // [5] (UtcTime) 500102123456Z
            // UtcTime 120102235959Z
            //
            // They're sorted backwards, though.
            const string PayloadHex =
                "850D3530303130323132333435365A" +
                "170D3132303130323233353935395A";

            byte[] inputData;

            // Build the rule-specific form of SEQUENCE { [PRIVATE 9] SEQUENCE { SET-OF { dates }, NULL } }
            // The outer Set-Of is also invalid, because the NULL should be first.
            if (ruleSet == AsnEncodingRules.DER)
            {
                inputData = ("3024" + "E922" + "A21E" + PayloadHex + "0500").HexToByteArray();
            }
            else
            {
                string inputHex = "3080" + "E980" + "A280" + PayloadHex + "0000" + "0500" + "0000" + "0000";
                inputData = inputHex.HexToByteArray();
            }

            AsnReaderOptions options = new AsnReaderOptions
            {
                SkipSetSortOrderVerification = true,
                UtcTimeTwoDigitYearMax       = 2011,
            };

            AsnReader initial = new AsnReader(inputData, ruleSet, options);
            AsnReader outer   = initial.ReadSequence();

            Assert.False(initial.HasData);
            AsnReader inner = outer.ReadSequence(new Asn1Tag(TagClass.Private, 9));

            Assert.False(outer.HasData);

            Asn1Tag setTag = new Asn1Tag(TagClass.ContextSpecific, 2);

            if (ruleSet != AsnEncodingRules.BER)
            {
                Assert.Throws <AsnContentException>(() => inner.ReadSetOf(false, setTag));
            }

            // This confirms that we've passed SkipSetOrderVerification this far.
            AsnReader setOf = inner.ReadSetOf(setTag);

            Assert.True(inner.HasData);

            Assert.Equal(
                new DateTimeOffset(1950, 1, 2, 12, 34, 56, TimeSpan.Zero),
                setOf.ReadUtcTime(new Asn1Tag(TagClass.ContextSpecific, 5)));

            // This confirms that we've passed UtcTimeTwoDigitYearMax,
            // the default would call this 2012.
            Assert.Equal(
                new DateTimeOffset(1912, 1, 2, 23, 59, 59, TimeSpan.Zero),
                setOf.ReadUtcTime());

            Assert.False(setOf.HasData);

            inner.ReadNull();
            Assert.False(inner.HasData);

            setOf.ThrowIfNotEmpty();
            inner.ThrowIfNotEmpty();
            outer.ThrowIfNotEmpty();
            initial.ThrowIfNotEmpty();
        }
Exemple #22
0
        private static void ReadData(Asn1Tag node, Stream stream, long dataLength)
        {
            if (dataLength > int.MaxValue)
            {
                throw new IOException("Can't read primitive data with more than " + int.MaxValue + " bytes.");
            }

            node.Data = new byte[(int)dataLength];
            int read = stream.Read(node.Data, 0, node.Data.Length);
            if (read != node.Data.Length)
            {
                throw new IOException("Unable to read enough data bytes.");
            }
        }
Exemple #23
0
        public unsafe string ProcessNegotiateChallenge(string challengeString)
        {
            NegState state = NegState.Unknown;
            string   mech  = null;

            byte[] blob = null;

            byte[]    data            = Convert.FromBase64String(challengeString);
            AsnReader reader          = new AsnReader(data, AsnEncodingRules.DER);
            AsnReader challengeReader = reader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegotiationToken.NegTokenResp));

            // NegTokenResp::= SEQUENCE {
            //    negState[0] ENUMERATED {
            //        accept - completed(0),
            //        accept - incomplete(1),
            //        reject(2),
            //        request - mic(3)
            //    } OPTIONAL,
            // --REQUIRED in the first reply from the target
            //    supportedMech[1] MechType OPTIONAL,
            // --present only in the first reply from the target
            // responseToken[2] OCTET STRING  OPTIONAL,
            // mechListMIC[3] OCTET STRING  OPTIONAL,
            // ...
            // }

            challengeReader = challengeReader.ReadSequence();
            while (challengeReader.HasData)
            {
                Asn1Tag tag = challengeReader.PeekTag();
                if (tag.TagClass == TagClass.ContextSpecific)
                {
                    NegTokenResp dataType      = (NegTokenResp)tag.TagValue;
                    AsnReader    specificValue = new AsnReader(challengeReader.PeekContentBytes(), AsnEncodingRules.DER);

                    switch (dataType)
                    {
                    case NegTokenResp.NegState:
                        state = specificValue.ReadEnumeratedValue <NegState>();
                        break;

                    case NegTokenResp.SupportedMech:
                        mech = specificValue.ReadObjectIdentifier();
                        break;

                    case NegTokenResp.ResponseToken:
                        blob = specificValue.ReadOctetString();
                        break;

                    default:
                        // Ignore everything else
                        break;
                    }
                }

                challengeReader.ReadEncodedValue();
            }

            if (Diag)
            {
                Console.WriteLine("Negotiate challenege: {0} - {1} in {2}", challengeString, mech, state);
            }

            // Mechanism should be set on first message. That means always
            // as NTLM has only one challenege message.
            if (!NtlmOid.Equals(mech))
            {
                throw new NotSupportedException($"'{mech}' mechanism is not supported");
            }


            if (state != NegState.Unknown && state != NegState.AcceptIncomplete)
            {
                // If state was set, it should be AcceptIncomplete for us to proseed.
                return("");
            }

            if (blob?.Length > 0)
            {
                // Process decoded NTLM blob.
                byte[] response = ProcessChallengeMessage(blob);
                if (response?.Length > 0)
                {
                    AsnWriter writer = new AsnWriter(AsnEncodingRules.DER);

                    using (writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegotiationToken.NegTokenResp)))
                    {
                        writer.PushSequence();
                        using (writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenInit.MechToken)))
                        {
                            writer.WriteOctetString(response);
                        }

                        writer.PopSequence();
                    }

                    return("Negotiate " + Convert.ToBase64String(writer.Encode(), Base64FormattingOptions.None));
                }
            }

            return("");
        }
 internal override void WriteString(AsnWriter writer, Asn1Tag tag, string s) =>
 writer.WriteCharacterString(UniversalTagNumber.UTF8String, s, tag);
        private static void DecodeCore(ref AsnValueReader reader, Asn1Tag expectedTag, ReadOnlyMemory <byte> rebind, out TbsCertificateAsn decoded)
        {
            decoded = default;
            AsnValueReader      sequenceReader = reader.ReadSequence(expectedTag);
            AsnValueReader      explicitReader;
            AsnValueReader      defaultReader;
            AsnValueReader      collectionReader;
            ReadOnlySpan <byte> rebindSpan = rebind.Span;
            int offset;
            ReadOnlySpan <byte> tmpSpan;


            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 AsnValueReader(DefaultVersion, AsnEncodingRules.DER);

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

            tmpSpan = sequenceReader.ReadIntegerBytes();
            decoded.SerialNumber = rebindSpan.Overlaps(tmpSpan, out offset) ? rebind.Slice(offset, tmpSpan.Length) : tmpSpan.ToArray();
            System.Security.Cryptography.Asn1.AlgorithmIdentifierAsn.Decode(ref sequenceReader, rebind, out decoded.SignatureAlgorithm);
            if (!sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag((UniversalTagNumber)16)))
            {
                throw new CryptographicException();
            }

            tmpSpan        = sequenceReader.ReadEncodedValue();
            decoded.Issuer = rebindSpan.Overlaps(tmpSpan, out offset) ? rebind.Slice(offset, tmpSpan.Length) : tmpSpan.ToArray();
            System.Security.Cryptography.X509Certificates.Asn1.ValidityAsn.Decode(ref sequenceReader, rebind, out decoded.Validity);
            if (!sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag((UniversalTagNumber)16)))
            {
                throw new CryptographicException();
            }

            tmpSpan         = sequenceReader.ReadEncodedValue();
            decoded.Subject = rebindSpan.Overlaps(tmpSpan, out offset) ? rebind.Slice(offset, tmpSpan.Length) : tmpSpan.ToArray();
            System.Security.Cryptography.Asn1.SubjectPublicKeyInfoAsn.Decode(ref sequenceReader, rebind, out decoded.SubjectPublicKeyInfo);

            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 1)))
            {
                if (sequenceReader.TryReadPrimitiveBitString(out _, out tmpSpan, new Asn1Tag(TagClass.ContextSpecific, 1)))
                {
                    decoded.IssuerUniqueId = rebindSpan.Overlaps(tmpSpan, out offset) ? rebind.Slice(offset, tmpSpan.Length) : tmpSpan.ToArray();
                }
                else
                {
                    decoded.IssuerUniqueId = sequenceReader.ReadBitString(out _, new Asn1Tag(TagClass.ContextSpecific, 1));
                }
            }


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 2)))
            {
                if (sequenceReader.TryReadPrimitiveBitString(out _, out tmpSpan, new Asn1Tag(TagClass.ContextSpecific, 2)))
                {
                    decoded.SubjectUniqueId = rebindSpan.Overlaps(tmpSpan, out offset) ? rebind.Slice(offset, tmpSpan.Length) : tmpSpan.ToArray();
                }
                else
                {
                    decoded.SubjectUniqueId = sequenceReader.ReadBitString(out _, new Asn1Tag(TagClass.ContextSpecific, 2));
                }
            }


            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(ref collectionReader, rebind, out tmpItem);
                        tmpList.Add(tmpItem);
                    }

                    decoded.Extensions = tmpList.ToArray();
                }

                explicitReader.ThrowIfNotEmpty();
            }


            sequenceReader.ThrowIfNotEmpty();
        }
        internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out Rfc3161TimeStampReq decoded)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

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


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

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

            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(Asn1Tag.ObjectIdentifier))
            {
                decoded.ReqPolicy = sequenceReader.ReadObjectIdentifier();
            }


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(Asn1Tag.Integer))
            {
                decoded.Nonce = sequenceReader.ReadIntegerBytes();
            }


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(Asn1Tag.Boolean))
            {
                decoded.CertReq = sequenceReader.ReadBoolean();
            }
            else
            {
                defaultReader   = new AsnReader(s_defaultCertReq, AsnEncodingRules.DER);
                decoded.CertReq = defaultReader.ReadBoolean();
            }


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0)))
            {
                // Decode SEQUENCE OF for Extensions
                {
                    collectionReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 0));
                    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();
                }
            }


            sequenceReader.ThrowIfNotEmpty();
        }
        internal void Encode(AsnWriter writer, Asn1Tag tag)
        {
            writer.PushSequence(tag);


            // DEFAULT value handler for Version.
            {
                AsnWriter tmp = new AsnWriter(AsnEncodingRules.DER);
                tmp.WriteInteger(Version);

                if (!tmp.EncodedValueEquals(DefaultVersion))
                {
                    writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 0));
                    tmp.CopyTo(writer);
                    writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 0));
                }
            }

            writer.WriteInteger(SerialNumber.Span);
            SignatureAlgorithm.Encode(writer);
            // Validator for tag constraint for Issuer
            {
                if (!Asn1Tag.TryDecode(Issuer.Span, out Asn1Tag validateTag, out _) ||
                    !validateTag.HasSameClassAndValue(new Asn1Tag((UniversalTagNumber)16)))
                {
                    throw new CryptographicException();
                }
            }

            try
            {
                writer.WriteEncodedValue(Issuer.Span);
            }
            catch (ArgumentException e)
            {
                throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e);
            }
            Validity.Encode(writer);
            // Validator for tag constraint for Subject
            {
                if (!Asn1Tag.TryDecode(Subject.Span, out Asn1Tag validateTag, out _) ||
                    !validateTag.HasSameClassAndValue(new Asn1Tag((UniversalTagNumber)16)))
                {
                    throw new CryptographicException();
                }
            }

            try
            {
                writer.WriteEncodedValue(Subject.Span);
            }
            catch (ArgumentException e)
            {
                throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e);
            }
            SubjectPublicKeyInfo.Encode(writer);

            if (IssuerUniqueId.HasValue)
            {
                writer.WriteBitString(IssuerUniqueId.Value.Span, 0, new Asn1Tag(TagClass.ContextSpecific, 1));
            }


            if (SubjectUniqueId.HasValue)
            {
                writer.WriteBitString(SubjectUniqueId.Value.Span, 0, new Asn1Tag(TagClass.ContextSpecific, 2));
            }


            if (Extensions != null)
            {
                writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 3));

                writer.PushSequence();
                for (int i = 0; i < Extensions.Length; i++)
                {
                    Extensions[i].Encode(writer);
                }
                writer.PopSequence();

                writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 3));
            }

            writer.PopSequence(tag);
        }
 public Asn1TypeAttribute(Asn1Tag asn1TagInfo)
 {
     this.tagInfo = new Asn1TagInfo(asn1TagInfo);
 }
        internal static void Decode <T>(AsnReader reader, Asn1Tag expectedTag, out T decoded)
            where T : KrbAuthPack, 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));
            KrbPKAuthenticator.Decode <KrbPKAuthenticator>(explicitReader, out KrbPKAuthenticator tmpPKAuthenticator);
            decoded.PKAuthenticator = tmpPKAuthenticator;

            explicitReader.ThrowIfNotEmpty();

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

                KrbSubjectPublicKeyInfo.Decode <KrbSubjectPublicKeyInfo>(explicitReader, out KrbSubjectPublicKeyInfo tmpClientPublicValue);
                decoded.ClientPublicValue = tmpClientPublicValue;
                explicitReader.ThrowIfNotEmpty();
            }

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

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

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

                    decoded.SupportedCMSTypes = tmpList.ToArray();
                }
                explicitReader.ThrowIfNotEmpty();
            }

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


                if (explicitReader.TryReadPrimitiveOctetStringBytes(out ReadOnlyMemory <byte> tmpClientDHNonce))
                {
                    decoded.ClientDHNonce = tmpClientDHNonce;
                }
                else
                {
                    decoded.ClientDHNonce = explicitReader.ReadOctetString();
                }
                explicitReader.ThrowIfNotEmpty();
            }

            sequenceReader.ThrowIfNotEmpty();
        }
 private static string GetPrintableDataString(Asn1Tag tag, Encoding encoding)
 {
     return encoding.GetString(tag.Data);
 }
Exemple #31
0
        internal static void Decode <T>(AsnReader reader, Asn1Tag expectedTag, out T decoded)
            where T : KrbEncKdcRepPart, 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));
            KrbEncryptionKey.Decode <KrbEncryptionKey>(explicitReader, out decoded.Key);
            explicitReader.ThrowIfNotEmpty();


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

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

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

                decoded.LastReq = tmpList.ToArray();
            }

            explicitReader.ThrowIfNotEmpty();


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

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

            explicitReader.ThrowIfNotEmpty();


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


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

            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, 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();
            }


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


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


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

                // 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, 12)))
            {
                explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 12));
                KrbMethodData tmpEncryptedPaData;
                KrbMethodData.Decode <KrbMethodData>(explicitReader, out tmpEncryptedPaData);
                decoded.EncryptedPaData = tmpEncryptedPaData;

                explicitReader.ThrowIfNotEmpty();
            }


            sequenceReader.ThrowIfNotEmpty();
        }
Exemple #32
0
        private KdcMessageHandlerBase LocateMessageHandler(ReadOnlyMemory <byte> request, Asn1Tag tag)
        {
            MessageType messageType = KrbMessage.DetectMessageType(tag);

            ValidateSupportedMessageType(messageType);

            if (!this.messageHandlers.TryGetValue(messageType, out MessageHandlerConstructor builder))
            {
                throw new KerberosProtocolException(
                          KerberosErrorCode.KRB_ERR_GENERIC,
                          $"Application tag {messageType} doesn't have a message handler registered"
                          );
            }

            var handler = builder(request, this.options);

            if (handler == null)
            {
                throw new InvalidOperationException($"Message handler builder {messageType} must not return null");
            }

            handler.RegisterPreAuthHandlers(this.preAuthHandlers);

            return(handler);
        }
Exemple #33
0
        internal void Encode(AsnWriter writer, Asn1Tag tag)
        {
            writer.PushSequence(tag);

            writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 0));
            Key?.Encode(writer);
            writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 0));
            writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 1));

            writer.PushSequence();
            for (int i = 0; i < LastReq.Length; i++)
            {
                LastReq[i]?.Encode(writer);
            }
            writer.PopSequence();

            writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 1));
            writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 2));
            writer.WriteInteger(Nonce);
            writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 2));

            if (HasValue(KeyExpiration))
            {
                writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 3));
                writer.WriteGeneralizedTime(KeyExpiration.Value);
                writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 3));
            }

            writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 4));
            writer.WriteBitString(Flags.AsReadOnly());
            writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 4));
            writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 5));
            writer.WriteGeneralizedTime(AuthTime);
            writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 5));

            if (HasValue(StartTime))
            {
                writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 6));
                writer.WriteGeneralizedTime(StartTime.Value);
                writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 6));
            }

            writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 7));
            writer.WriteGeneralizedTime(EndTime);
            writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 7));

            if (HasValue(RenewTill))
            {
                writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 8));
                writer.WriteGeneralizedTime(RenewTill.Value);
                writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 8));
            }

            writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 9));
            writer.WriteCharacterString(UniversalTagNumber.GeneralString, Realm);
            writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 9));
            writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 10));
            SName?.Encode(writer);
            writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 10));

            if (HasValue(CAddr))
            {
                writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 11));

                writer.PushSequence();
                for (int i = 0; i < CAddr.Length; i++)
                {
                    CAddr[i]?.Encode(writer);
                }
                writer.PopSequence();

                writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 11));
            }


            if (HasValue(EncryptedPaData))
            {
                writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 12));
                EncryptedPaData?.Encode(writer);
                writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 12));
            }

            writer.PopSequence(tag);
        }
Exemple #34
0
        public static byte[] EncodeHeader(Asn1Tag node)
        {
            //TODO: determine/rationalize the initial size (though it's not like we're working with megabytes)
            AutoGrowArray<byte> header = new AutoGrowArray<byte>(10);

            #region Tag
            byte tagByte = (byte)((((int)node.Class) << 6) | ((node.Constructed ? 1 : 0) << 5));
            if (node.Identifier < 31 && !node.ForceMultiByteIdentifier)
            {
                tagByte = (byte)(tagByte | node.Identifier);
                header.Add(tagByte);
            }
            else
            {
                tagByte |= 31;
                header.Add(tagByte);
                int n = 0;
                while ((node.Identifier >> (n * 7)) > 0)
                {
                    n++;
                }

                while (n > 0)
                {
                    n--;
                    tagByte = (byte)((node.Identifier >> (n * 7)) & (0x7F));
                    if (n >= 1) tagByte |= 0x80;
                    header.Add(tagByte);
                }
            }
            #endregion

            #region Length
            long dataLength;
            if (node.Constructed)
            {
                //TODO: don't calculate and generate the length of subnodes over and over again
                dataLength = node.Sum(subTag => GetTotalByteCount(subTag));
            }
            else
            {
                dataLength = node.Data.Length;
            }

            byte lenByte;
            if (node.IndefiniteLength)
            {
                lenByte = 0x80;
                header.Add(lenByte);
            }
            else if (dataLength >= 0 && dataLength <= 127)
            {
                lenByte = (byte)dataLength;
                header.Add(lenByte);
            }
            else if (dataLength > 0)
            {
                int numBytes = (int)Math.Ceiling(Math.Log(dataLength + 1) / Math.Log(256));
                if (numBytes >= 0x7F) throw new IOException("Don't know how to write length with 127 bytes");
                lenByte = (byte)(0x80 | (numBytes & 0x7F));
                header.Add(lenByte);

                for (int i = 0; i < numBytes; ++i)
                {
                    lenByte = (byte)((dataLength >> (8 * (numBytes - i - 1))) & 0xFF);
                    header.Add(lenByte);
                }
            }
            else
            {
                throw new IOException("Don't know how to write negative length.");
            }
            #endregion

            return header.ToArray();
        }
Exemple #35
0
        internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out SignedDataAsn decoded)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

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


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


            // Decode SEQUENCE OF for DigestAlgorithms
            {
                collectionReader = sequenceReader.ReadSetOf();
                var tmpList = new List <System.Security.Cryptography.Asn1.AlgorithmIdentifierAsn>();
                System.Security.Cryptography.Asn1.AlgorithmIdentifierAsn tmpItem;

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

                decoded.DigestAlgorithms = tmpList.ToArray();
            }

            System.Security.Cryptography.Pkcs.Asn1.EncapsulatedContentInfoAsn.Decode(sequenceReader, out decoded.EncapContentInfo);

            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0)))
            {
                // Decode SEQUENCE OF for CertificateSet
                {
                    collectionReader = sequenceReader.ReadSetOf(new Asn1Tag(TagClass.ContextSpecific, 0));
                    var tmpList = new List <System.Security.Cryptography.Pkcs.Asn1.CertificateChoiceAsn>();
                    System.Security.Cryptography.Pkcs.Asn1.CertificateChoiceAsn tmpItem;

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

                    decoded.CertificateSet = tmpList.ToArray();
                }
            }


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 1)))
            {
                // Decode SEQUENCE OF for Crls
                {
                    collectionReader = sequenceReader.ReadSetOf(new Asn1Tag(TagClass.ContextSpecific, 1));
                    var tmpList = new List <ReadOnlyMemory <byte> >();
                    ReadOnlyMemory <byte> tmpItem;

                    while (collectionReader.HasData)
                    {
                        tmpItem = collectionReader.GetEncodedValue();
                        tmpList.Add(tmpItem);
                    }

                    decoded.Crls = tmpList.ToArray();
                }
            }


            // Decode SEQUENCE OF for SignerInfos
            {
                collectionReader = sequenceReader.ReadSetOf();
                var tmpList = new List <System.Security.Cryptography.Pkcs.Asn1.SignerInfoAsn>();
                System.Security.Cryptography.Pkcs.Asn1.SignerInfoAsn tmpItem;

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

                decoded.SignerInfos = tmpList.ToArray();
            }


            sequenceReader.ThrowIfNotEmpty();
        }
Exemple #36
0
 public static void ExportText(Stream stream, Asn1Tag node)
 {
     byte[] text = ASCIIEncoding.ASCII.GetBytes(node.ToShortText());
     stream.Write(text, 0, text.Length);
 }
        internal static void Decode(ref AsnValueReader reader, Asn1Tag expectedTag, ReadOnlyMemory <byte> rebind, out Rfc3161TstInfo decoded)
        {
            decoded = default;
            AsnValueReader      sequenceReader = reader.ReadSequence(expectedTag);
            AsnValueReader      explicitReader;
            AsnValueReader      defaultReader;
            AsnValueReader      collectionReader;
            ReadOnlySpan <byte> rebindSpan = rebind.Span;
            int offset;
            ReadOnlySpan <byte> tmpSpan;


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

            decoded.Policy = sequenceReader.ReadObjectIdentifier();
            MessageImprint.Decode(ref sequenceReader, rebind, out decoded.MessageImprint);
            tmpSpan = sequenceReader.ReadIntegerBytes();
            decoded.SerialNumber = rebindSpan.Overlaps(tmpSpan, out offset) ? rebind.Slice(offset, tmpSpan.Length) : tmpSpan.ToArray();
            decoded.GenTime      = sequenceReader.ReadGeneralizedTime();

            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(Asn1Tag.Sequence))
            {
                Rfc3161Accuracy tmpAccuracy;
                Rfc3161Accuracy.Decode(ref sequenceReader, rebind, out tmpAccuracy);
                decoded.Accuracy = tmpAccuracy;
            }


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(Asn1Tag.Boolean))
            {
                decoded.Ordering = sequenceReader.ReadBoolean();
            }
            else
            {
                defaultReader    = new AsnValueReader(DefaultOrdering, AsnEncodingRules.DER);
                decoded.Ordering = defaultReader.ReadBoolean();
            }


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(Asn1Tag.Integer))
            {
                tmpSpan       = sequenceReader.ReadIntegerBytes();
                decoded.Nonce = rebindSpan.Overlaps(tmpSpan, out offset) ? rebind.Slice(offset, tmpSpan.Length) : tmpSpan.ToArray();
            }


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0)))
            {
                explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 0));
                GeneralNameAsn tmpTsa;
                GeneralNameAsn.Decode(ref explicitReader, rebind, out tmpTsa);
                decoded.Tsa = tmpTsa;

                explicitReader.ThrowIfNotEmpty();
            }


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 1)))
            {
                // Decode SEQUENCE OF for Extensions
                {
                    collectionReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 1));
                    var tmpList = new List <X509ExtensionAsn>();
                    X509ExtensionAsn tmpItem;

                    while (collectionReader.HasData)
                    {
                        X509ExtensionAsn.Decode(ref collectionReader, rebind, out tmpItem);
                        tmpList.Add(tmpItem);
                    }

                    decoded.Extensions = tmpList.ToArray();
                }
            }


            sequenceReader.ThrowIfNotEmpty();
        }
Exemple #38
0
 private static void CallWithFilestream(Action<Stream, Asn1Tag> method, string filename, Asn1Tag node)
 {
     using (FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write))
     {
         method(fs, node);
     }
 }
        public override int BerEncode(IAsn1BerEncodingBuffer buffer, bool explicitTag = true)
        {
            int     allLen = 0;
            Asn1Tag contextTag;

            switch (SelectedChoice)
            {
            case 1:
                allLen    += field0.BerEncode(buffer, false);
                allLen    += LengthBerEncode(buffer, allLen);
                contextTag = new Asn1Tag(Asn1TagType.Context, 0)
                {
                    EncodingWay = EncodingWay.Constructed
                };
                allLen += TagBerEncode(buffer, contextTag);
                break;

            case 2:
                allLen    += field1.BerEncode(buffer, false);
                allLen    += LengthBerEncode(buffer, allLen);
                contextTag = new Asn1Tag(Asn1TagType.Context, 1)
                {
                    EncodingWay = EncodingWay.Constructed
                };
                allLen += TagBerEncode(buffer, contextTag);
                break;

            case 3:
                allLen    += field2.BerEncode(buffer, false);
                allLen    += LengthBerEncode(buffer, allLen);
                contextTag = new Asn1Tag(Asn1TagType.Context, 2)
                {
                    EncodingWay = EncodingWay.Constructed
                };
                allLen += TagBerEncode(buffer, contextTag);
                break;

            case 4:
                allLen    += field3.BerEncode(buffer, false);
                allLen    += LengthBerEncode(buffer, allLen);
                contextTag = new Asn1Tag(Asn1TagType.Context, 3)
                {
                    EncodingWay = EncodingWay.Constructed
                };
                allLen += TagBerEncode(buffer, contextTag);
                break;

            case 5:
                allLen    += field4.BerEncode(buffer, false);
                allLen    += LengthBerEncode(buffer, allLen);
                contextTag = new Asn1Tag(Asn1TagType.Context, 4)
                {
                    EncodingWay = EncodingWay.Constructed
                };
                allLen += TagBerEncode(buffer, contextTag);
                break;

            case 6:
                allLen    += field5.BerEncode(buffer, false);
                allLen    += LengthBerEncode(buffer, allLen);
                contextTag = new Asn1Tag(Asn1TagType.Context, 5)
                {
                    EncodingWay = EncodingWay.Constructed
                };
                allLen += TagBerEncode(buffer, contextTag);
                break;

            case 7:
                allLen    += field6.BerEncode(buffer, false);
                allLen    += LengthBerEncode(buffer, allLen);
                contextTag = new Asn1Tag(Asn1TagType.Context, 6)
                {
                    EncodingWay = EncodingWay.Constructed
                };
                allLen += TagBerEncode(buffer, contextTag);
                break;

            case 8:
                allLen    += field7.BerEncode(buffer, false);
                allLen    += LengthBerEncode(buffer, allLen);
                contextTag = new Asn1Tag(Asn1TagType.Context, 7)
                {
                    EncodingWay = EncodingWay.Primitive
                };
                allLen += TagBerEncode(buffer, contextTag);
                break;

            case 9:
                allLen    += field8.BerEncode(buffer, false);
                allLen    += LengthBerEncode(buffer, allLen);
                contextTag = new Asn1Tag(Asn1TagType.Context, 8)
                {
                    EncodingWay = EncodingWay.Constructed
                };
                allLen += TagBerEncode(buffer, contextTag);
                break;

            case 10:
                allLen    += field9.BerEncode(buffer, false);
                allLen    += LengthBerEncode(buffer, allLen);
                contextTag = new Asn1Tag(Asn1TagType.Context, 9)
                {
                    EncodingWay = EncodingWay.Constructed
                };
                allLen += TagBerEncode(buffer, contextTag);
                break;

            default:
                throw new Asn1ConstraintsNotSatisfied(ExceptionMessages.InvalidChoiceIndex + " AuthenticationChoice");
            }
            return(allLen);
        }
Exemple #40
0
        /// <summary>
        /// Parse data in a (BitString) node if it's valid ASN.1 and add read nodes as sub nodes to this node.
        /// </summary>
        /// <param name="node">Node to read data from.</param>
        /// <returns>True if valid ASN.1 was read, false if not.</returns>
        private static bool ReadSubAsn1(Asn1Tag node, int dataOffset)
        {
            try
            {
                using (MemoryStream ms = new MemoryStream(node.Data, dataOffset, node.Data.Length - 1))
                {
                    Asn1Tag subTag = Asn1.Decode(ms);
                    subTag.ToShortText(); // To validate, if it fails with exception, it's not added

                    node.AddSubTag(subTag);
                    return true;
                }
            }
            catch (Exception ex) // TODO: narrow this down
            {
                Console.WriteLine("Exception: " + ex.Message);
                return false;
            }
        }
Exemple #41
0
        internal static void Decode <T>(AsnReader reader, Asn1Tag expectedTag, out T decoded)
            where T : KrbAuthenticator, 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.TryReadInt32(out decoded.AuthenticatorVersionNumber))
            {
                explicitReader.ThrowIfNotEmpty();
            }

            explicitReader.ThrowIfNotEmpty();


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


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


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 3)))
            {
                explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 3));
                KrbChecksum tmpChecksum;
                KrbChecksum.Decode <KrbChecksum>(explicitReader, out tmpChecksum);
                decoded.Checksum = tmpChecksum;

                explicitReader.ThrowIfNotEmpty();
            }


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

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

            explicitReader.ThrowIfNotEmpty();


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


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 6)))
            {
                explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 6));
                KrbEncryptionKey tmpSubkey;
                KrbEncryptionKey.Decode <KrbEncryptionKey>(explicitReader, out tmpSubkey);
                decoded.Subkey = tmpSubkey;

                explicitReader.ThrowIfNotEmpty();
            }


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

                if (explicitReader.TryReadInt32(out int tmpSequenceNumber))
                {
                    decoded.SequenceNumber = tmpSequenceNumber;
                }
                else
                {
                    explicitReader.ThrowIfNotEmpty();
                }

                explicitReader.ThrowIfNotEmpty();
            }


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

                // 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();
        }
 internal override void WriteSpan(AsnWriter writer, Asn1Tag tag, ReadOnlySpan <char> s) =>
 writer.WriteCharacterString(UniversalTagNumber.UTF8String, s, tag);
Exemple #43
0
        /// <summary>
        /// Decode the Tbs of the CRL.
        /// </summary>
        /// <param name="tbs">The raw TbsCertList of the CRL.</param>
        internal void DecodeCrl(byte[] tbs)
        {
            try
            {
                AsnReader crlReader = new AsnReader(tbs, AsnEncodingRules.DER);
                var       tag       = Asn1Tag.Sequence;
                var       seqReader = crlReader.ReadSequence(tag);
                crlReader.ThrowIfNotEmpty();
                if (seqReader != null)
                {
                    // Version is OPTIONAL
                    uint version = 0;
                    var  intTag  = new Asn1Tag(UniversalTagNumber.Integer);
                    var  peekTag = seqReader.PeekTag();
                    if (peekTag == intTag)
                    {
                        if (seqReader.TryReadUInt32(out version))
                        {
                            if (version != 1)
                            {
                                throw new AsnContentException($"The CRL contains an incorrect version {version}");
                            }
                        }
                    }

                    // Signature Algorithm Identifier
                    var sigReader = seqReader.ReadSequence();
                    var oid       = sigReader.ReadObjectIdentifier();
                    m_hashAlgorithmName = Oids.GetHashAlgorithmName(oid);
                    if (sigReader.HasData)
                    {
                        sigReader.ReadNull();
                    }
                    sigReader.ThrowIfNotEmpty();

                    // Issuer
                    m_issuerName = new X500DistinguishedName(seqReader.ReadEncodedValue().ToArray());

                    // thisUpdate
                    m_thisUpdate = seqReader.ReadUtcTime().UtcDateTime;

                    // nextUpdate is OPTIONAL
                    var utcTag = new Asn1Tag(UniversalTagNumber.UtcTime);
                    peekTag = seqReader.PeekTag();
                    if (peekTag == utcTag)
                    {
                        m_nextUpdate = seqReader.ReadUtcTime().UtcDateTime;
                    }

                    var seqTag = new Asn1Tag(UniversalTagNumber.Sequence, true);
                    peekTag = seqReader.PeekTag();
                    if (peekTag == seqTag)
                    {
                        // revoked certificates
                        var revReader           = seqReader.ReadSequence(tag);
                        var revokedCertificates = new List <RevokedCertificate>();
                        while (revReader.HasData)
                        {
                            var crlEntry           = revReader.ReadSequence();
                            var serial             = crlEntry.ReadInteger();
                            var revokedCertificate = new RevokedCertificate(serial.ToByteArray());
                            revokedCertificate.RevocationDate = crlEntry.ReadUtcTime().UtcDateTime;
                            if (version == 1 &&
                                crlEntry.HasData)
                            {
                                // CRL entry extensions
                                var crlEntryExtensions = crlEntry.ReadSequence();
                                while (crlEntryExtensions.HasData)
                                {
                                    var extension = crlEntryExtensions.ReadExtension();
                                    revokedCertificate.CrlEntryExtensions.Add(extension);
                                }
                                crlEntryExtensions.ThrowIfNotEmpty();
                            }
                            crlEntry.ThrowIfNotEmpty();
                            revokedCertificates.Add(revokedCertificate);
                        }
                        revReader.ThrowIfNotEmpty();
                        m_revokedCertificates = revokedCertificates;
                    }

                    // CRL extensions OPTIONAL
                    if (version == 1 &&
                        seqReader.HasData)
                    {
                        var extTag           = new Asn1Tag(TagClass.ContextSpecific, 0);
                        var optReader        = seqReader.ReadSequence(extTag);
                        var crlExtensionList = new X509ExtensionCollection();
                        var crlExtensions    = optReader.ReadSequence();
                        while (crlExtensions.HasData)
                        {
                            var extension = crlExtensions.ReadExtension();
                            crlExtensionList.Add(extension);
                        }
                        m_crlExtensions = crlExtensionList;
                    }
                    seqReader.ThrowIfNotEmpty();
                    m_decoded = true;
                    return;
                }
                throw new CryptographicException("The CRL contains ivalid data.");
            }
            catch (AsnContentException ace)
            {
                throw new CryptographicException("Failed to decode the CRL.", ace);
            }
        }
        internal static void Decode <T>(AsnReader reader, Asn1Tag expectedTag, out T decoded)
            where T : KrbKdcReq, 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, 1));

            if (!explicitReader.TryReadInt32(out int tmpProtocolVersionNumber))
            {
                explicitReader.ThrowIfNotEmpty();
            }

            decoded.ProtocolVersionNumber = tmpProtocolVersionNumber;

            explicitReader.ThrowIfNotEmpty();

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

            if (!explicitReader.TryReadInt32(out MessageType tmpMessageType))
            {
                explicitReader.ThrowIfNotEmpty();
            }

            decoded.MessageType = tmpMessageType;

            explicitReader.ThrowIfNotEmpty();

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

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

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

                    decoded.PaData = tmpList.ToArray();
                }
                explicitReader.ThrowIfNotEmpty();
            }

            explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 4));
            KrbKdcReqBody.Decode <KrbKdcReqBody>(explicitReader, out KrbKdcReqBody tmpBody);
            decoded.Body = tmpBody;

            explicitReader.ThrowIfNotEmpty();

            sequenceReader.ThrowIfNotEmpty();
        }
 // T-REC-X.690-201508 sec 8.9, 8.10
 private void PushSequenceCore(Asn1Tag tag)
 {
     PushTag(tag.AsConstructed(), UniversalTagNumber.Sequence);
 }
Exemple #46
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Asn1TagInfo"/> struct.
 /// </summary>
 /// <param name="asn1Tag">The asn1 SNMP tag.</param>
 public Asn1TagInfo(Asn1Tag asn1Tag) : this(asn1Tag, ConstructType.Primitive)
 {
 }
 private static string GetBitDataString(Asn1Tag tag)
 {
     byte unusedBits = tag.Data[0];
     return string.Concat("unused: ", unusedBits, " ", GetHexDataString(tag.Data, 1, Math.Min(64, tag.Data.Length - 1)));
 }
Exemple #48
0
 internal abstract void WriteSpan(AsnWriter writer, Asn1Tag tag, ReadOnlySpan <char> s);
Exemple #49
0
 public Asn1TypeAttribute(Asn1Tag asn1Tag, ConstructType constructType, Asn1Class asn1Class)
 {
     this.tagInfo = new Asn1TagInfo(asn1Tag, constructType, asn1Class);
 }
 public Asn1TypeAttribute(Asn1Tag asn1Tag, ConstructType constructType, Asn1Class asn1Class)
 {
     this.tagInfo = new Asn1TagInfo(asn1Tag, constructType, asn1Class);
 }
Exemple #51
0
 public static void Encode(Stream stream, Asn1Tag node)
 {
     EncodeHeader(stream, node);
     EncodeData(stream, node);
 }
        private static string GetOidDataString(Asn1Tag tag)
        {
            StringBuilder oidBuf = new StringBuilder();
            bool first = true;
            int value = 0;

            OidNode oidNode = OidDb;

            for (int i = 0; i < tag.Data.Length; ++i)
            {
                value <<= 7;
                value |= (tag.Data[i] & 0x7F);

                if ((tag.Data[i] & 0x80) == 0)
                {
                    if (first)
                    {
                        oidBuf.Append(value / 40);
                        oidBuf.Append('.');
                        oidBuf.Append(value % 40);
                        first = false;

                        if (oidNode != null) oidNode = oidNode.Get(value / 40);
                        if (oidNode != null) oidNode = oidNode.Get(value % 40);
                    }
                    else
                    {
                        oidBuf.Append('.');
                        oidBuf.Append(value);

                        if (oidNode != null) oidNode = oidNode.Get(value);
                    }

                    value = 0;
                }
            }

            if (oidNode != null) oidBuf.Append(" (").Append(oidNode.Description).Append(")");

            return oidBuf.ToString();
        }
Exemple #53
0
 public static void EncodeData(string filename, Asn1Tag node)
 {
     CallWithFilestream(EncodeData, filename, node);
 }
 private static string GetUtcDataString(Asn1Tag tag)
 {
     DateTime utcTime = GetUtcTime(tag);
     return string.Concat(utcTime.ToString("yyyy-MM-dd HH:mm:ss"), " UTC");
 }
Exemple #55
0
 public static void EncodeData(Stream stream, Asn1Tag node)
 {
     #region Data
     if (node.Constructed)
     {
         foreach (Asn1Tag subTag in node)
         {
             Encode(stream, subTag);
         }
     }
     else
     {
         stream.Write(node.Data, 0, node.Data.Length);
     }
     #endregion
 }
 // T-REC-X.690-201508 sec 8.9, 8.10
 private void PopSequenceCore(Asn1Tag tag)
 {
     PopTag(tag, UniversalTagNumber.Sequence);
 }
Exemple #57
0
        internal virtual async Task <ReadOnlyMemory <byte> > ProcessMessageCoreAsync(ReadOnlyMemory <byte> request, Asn1Tag tag)
        {
            KdcMessageHandlerBase messageHandler;

            try
            {
                messageHandler = this.LocateMessageHandler(request, tag);
            }
            catch (Exception ex) when(IsProtocolException(ex))
            {
                this.logger.LogWarning(ex, "Message handler could not be located for message");

                return(KdcMessageHandlerBase.GenerateGenericError(ex, this.options));
            }

            try
            {
                return(await messageHandler.ExecuteAsync().ConfigureAwait(false));
            }
            catch (Exception ex) when(IsProtocolException(ex))
            {
                this.logger.LogWarning(ex, "Message handler {MessageHandler} could not process message", messageHandler.GetType());

                return(KdcMessageHandlerBase.GenerateGenericError(ex, this.options));
            }
        }
Exemple #58
0
        /// <summary>
        /// Decode ASN.1 tags from a stream.
        /// </summary>
        /// <param name="stream">Stream to read from.</param>
        /// <param name="singleNode">If true, read only one single node without subnodes.</param>
        /// <param name="readSubAsn1">If true, possible ASN.1 data in BitStrings will be decoded.</param>
        /// <returns>The root node read from the stream.</returns>
        public static Asn1Tag Decode(Stream stream, bool singleNode, bool readSubAsn1)
        {
            Asn1Tag node = new Asn1Tag();

            Asn1.Class nodeClass;
            bool constructed;
            bool indefLength;
            int fullIdentifier;
            bool forceMultiByteIdentifier;

            node.StartByte = stream.Position;
            node.Identifier = ReadIdentifier(stream, out nodeClass, out constructed, out fullIdentifier, out forceMultiByteIdentifier);
            node.Class = nodeClass;
            node.Constructed = constructed;
            node.FullIdentifier = fullIdentifier;
            node.ForceMultiByteIdentifier = forceMultiByteIdentifier;
            long dataLength = ReadLength(stream, out indefLength);
            long headerLength = stream.Position - node.StartByte;

            if (node.Constructed)
            {
                if (!singleNode)
                {
                    while ((stream.Position < node.StartByte + headerLength + dataLength) || indefLength)
                    {
                        Asn1Tag subTag = Decode(stream, singleNode, readSubAsn1);
                        node.AddSubTag(subTag);
                        if (subTag.Identifier == EocIdentifier && subTag.Data.Length == EocLength)
                        {
                            break;
                        }
                    }
                }
            }
            else
            {
                ReadData(node, stream, dataLength);

                if (readSubAsn1)
                {
                    switch (node.Identifier)
                    {
                        case (int)Asn1.TagNumber.BitString:
                            ReadSubAsn1(node, 1);
                            break;
                        case (int)Asn1.TagNumber.OctetString:
                            ReadSubAsn1(node, 0);
                            break;
                    }
                }
            }

            return node;
        }
Exemple #59
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Asn1TagInfo"/> struct.
 /// </summary>
 /// <param name="asn1Tag">The asn1 SNMP tag.</param>
 public Asn1TagInfo(Asn1Tag asn1Tag)
     : this(asn1Tag, ConstructType.Primitive)
 {
 }