Example #1
0
        public static void WriteAfterDispose(bool empty)
        {
            using (AsnWriter writer = new AsnWriter(AsnEncodingRules.DER))
            {
                if (!empty)
                {
                    writer.WriteNull();
                }

                writer.Dispose();

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteGeneralizedTime(DateTimeOffset.UtcNow));

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteGeneralizedTime(DateTimeOffset.UtcNow, true));

                Assert.Throws <ArgumentException>(
                    "tag",
                    () => writer.WriteGeneralizedTime(Asn1Tag.Integer, DateTimeOffset.Now));

                Assert.Throws <ArgumentException>(
                    "tag",
                    () => writer.WriteGeneralizedTime(Asn1Tag.Integer, DateTimeOffset.Now, true));

                Asn1Tag tag = new Asn1Tag(TagClass.ContextSpecific, 18);

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteGeneralizedTime(tag, DateTimeOffset.Now));

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteGeneralizedTime(tag, DateTimeOffset.Now, true));
            }
        }
Example #2
0
        private unsafe AsnWriter WritePkcs8PrivateKey()
        {
            // A PKCS1 RSAPrivateKey is the Modulus (KeySize bits), D (~KeySize bits)
            // P, Q, DP, DQ, InverseQ (all ~KeySize/2 bits)
            // Each field can have up to 7 bytes of overhead, and then another 9 bytes
            // of fixed overhead.
            // So it should fit in 5 * KeySizeInBytes, but Exponent is a wildcard.

            int rentSize = checked (5 * KeySize / 8);

            while (true)
            {
                byte[] rented = ArrayPool <byte> .Shared.Rent(rentSize);

                rentSize = rented.Length;
                int pkcs1Size = 0;

                fixed(byte *rentPtr = rented)
                {
                    try
                    {
                        if (!TryExportRSAPrivateKey(rented, out pkcs1Size))
                        {
                            rentSize = checked (rentSize * 2);
                            continue;
                        }

                        AsnWriter writer = new AsnWriter(AsnEncodingRules.BER);

                        try
                        {
                            writer.PushSequence();
                            // Version 0 format (no attributes)
                            writer.WriteInteger(0);
                            WriteAlgorithmIdentifier(writer);
                            writer.WriteOctetString(rented.AsSpan(0, pkcs1Size));
                            writer.PopSequence();

                            return(writer);
                        }
                        catch
                        {
                            writer.Dispose();
                            throw;
                        }
                    }
                    finally
                    {
                        CryptographicOperations.ZeroMemory(rented.AsSpan(0, pkcs1Size));
                        ArrayPool <byte> .Shared.Return(rented);
                    }
                }
            }
        }
Example #3
0
        public static void Pop_After_Dispose(bool empty)
        {
            using (AsnWriter writer = new AsnWriter(AsnEncodingRules.DER))
            {
                if (!empty)
                {
                    writer.WriteNull();
                }

                writer.Dispose();

                Assert.Throws <ObjectDisposedException>(() => writer.PopSetOf());
            }
        }
Example #4
0
        public static void Push_Custom_After_Dispose(bool empty)
        {
            using (AsnWriter writer = new AsnWriter(AsnEncodingRules.DER))
            {
                if (!empty)
                {
                    writer.WriteNull();
                }

                writer.Dispose();

                Assert.Throws <ObjectDisposedException>(
                    () => writer.PushSetOf(new Asn1Tag(TagClass.Application, 2)));
            }
        }
Example #5
0
        private AsnWriter EncodeToNewWriter()
        {
            AsnWriter writer = new AsnWriter(AsnEncodingRules.BER);

            try
            {
                EncodeTo(writer);
                return(writer);
            }
            catch
            {
                writer.Dispose();
                throw;
            }
        }
Example #6
0
        public static void WriteAfterDispose(bool empty)
        {
            using (AsnWriter writer = new AsnWriter(AsnEncodingRules.DER))
            {
                if (!empty)
                {
                    writer.WriteNull();
                }

                writer.Dispose();

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteUtcTime(DateTimeOffset.Now));

                AssertExtensions.Throws <ArgumentOutOfRangeException>(
                    "value",
                    () => writer.WriteUtcTime(DateTimeOffset.Now, 1999));

                AssertExtensions.Throws <ArgumentOutOfRangeException>(
                    "value",
                    () => writer.WriteUtcTime(DateTimeOffset.Now, 8999));

                AssertExtensions.Throws <ArgumentException>(
                    "tag",
                    () => writer.WriteUtcTime(Asn1Tag.Integer, DateTimeOffset.Now));

                AssertExtensions.Throws <ArgumentException>(
                    "tag",
                    () => writer.WriteUtcTime(Asn1Tag.Integer, DateTimeOffset.Now, 1999));

                AssertExtensions.Throws <ArgumentException>(
                    "tag",
                    () => writer.WriteUtcTime(Asn1Tag.Integer, DateTimeOffset.Now, 8999));

                Asn1Tag tag = new Asn1Tag(TagClass.Application, 3);

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteUtcTime(tag, DateTimeOffset.Now));

                AssertExtensions.Throws <ArgumentOutOfRangeException>(
                    "value",
                    () => writer.WriteUtcTime(tag, DateTimeOffset.Now, 1999));

                AssertExtensions.Throws <ArgumentOutOfRangeException>(
                    "value",
                    () => writer.WriteUtcTime(tag, DateTimeOffset.Now, 8999));
            }
        }
Example #7
0
        public static void WriteAfterDispose(bool empty)
        {
            using (AsnWriter writer = new AsnWriter(AsnEncodingRules.DER))
            {
                if (!empty)
                {
                    writer.WriteBoolean(true);
                }

                writer.Dispose();

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteNull());

                AssertExtensions.Throws <ArgumentException>(
                    "tag",
                    () => writer.WriteNull(Asn1Tag.Integer));

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteNull(new Asn1Tag(TagClass.Private, 3)));
            }
        }
Example #8
0
        public static void WriteAfterDispose(bool empty)
        {
            using (AsnWriter writer = new AsnWriter(AsnEncodingRules.DER))
            {
                if (!empty)
                {
                    writer.WriteNull();
                }

                writer.Dispose();

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteBitString(ReadOnlySpan <byte> .Empty));

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteBitString(ReadOnlySpan <byte> .Empty, 1));

                Assert.Throws <ArgumentOutOfRangeException>(
                    "unusedBitCount",
                    () => writer.WriteBitString(ReadOnlySpan <byte> .Empty, 9));

                Assert.Throws <ArgumentException>(
                    "tag",
                    () => writer.WriteBitString(Asn1Tag.Boolean, ReadOnlySpan <byte> .Empty));

                Asn1Tag tag = new Asn1Tag(TagClass.ContextSpecific, 11);

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteBitString(tag, ReadOnlySpan <byte> .Empty));

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteBitString(tag, ReadOnlySpan <byte> .Empty, 1));

                Assert.Throws <ArgumentOutOfRangeException>(
                    "unusedBitCount",
                    () => writer.WriteBitString(tag, ReadOnlySpan <byte> .Empty, 9));
            }
        }
Example #9
0
        internal AsnWriter Encode()
        {
            AsnWriter writer;

            if (ConfidentialityMode == Pkcs12ConfidentialityMode.Password ||
                ConfidentialityMode == Pkcs12ConfidentialityMode.PublicKey)
            {
                writer = new AsnWriter(AsnEncodingRules.BER);
                writer.WriteEncodedValue(_encrypted.Span);
                return(writer);
            }

            Debug.Assert(ConfidentialityMode == Pkcs12ConfidentialityMode.None);

            writer = new AsnWriter(AsnEncodingRules.BER);

            try
            {
                writer.PushSequence();

                if (_bags != null)
                {
                    foreach (Pkcs12SafeBag safeBag in _bags)
                    {
                        safeBag.EncodeTo(writer);
                    }
                }

                writer.PopSequence();
                return(writer);
            }
            catch
            {
                writer.Dispose();
                throw;
            }
        }
        protected void WriteAfterDispose_String(bool empty)
        {
            using (AsnWriter writer = new AsnWriter(AsnEncodingRules.DER))
            {
                if (!empty)
                {
                    writer.WriteNull();
                }

                writer.Dispose();

                string input = "1";

                Assert.Throws <ObjectDisposedException>(
                    () => WriteString(writer, input));

                AssertExtensions.Throws <ArgumentException>(
                    "tag",
                    () => WriteString(writer, Asn1Tag.Boolean, input));

                Assert.Throws <ObjectDisposedException>(
                    () => WriteString(writer, new Asn1Tag(TagClass.Application, 0), input));
            }
        }
Example #11
0
        public static void WriteAfterDispose(bool empty)
        {
            using (AsnWriter writer = new AsnWriter(AsnEncodingRules.DER))
            {
                if (!empty)
                {
                    writer.WriteNull();
                }

                writer.Dispose();

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteOctetString(ReadOnlySpan <byte> .Empty));

                Assert.Throws <ArgumentException>(
                    "tag",
                    () => writer.WriteOctetString(Asn1Tag.Integer, ReadOnlySpan <byte> .Empty));

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteOctetString(
                        new Asn1Tag(TagClass.Private, 3),
                        ReadOnlySpan <byte> .Empty));
            }
        }
Example #12
0
        internal byte[] Encrypt(
            ReadOnlySpan <char> password,
            ReadOnlySpan <byte> passwordBytes,
            PbeParameters pbeParameters)
        {
            Debug.Assert(pbeParameters != null);
            Debug.Assert(pbeParameters.IterationCount >= 1);

            AsnWriter writer = null;

            using (AsnWriter contentsWriter = Encode())
            {
                ReadOnlySpan <byte> contentsSpan = contentsWriter.EncodeAsSpan();

                PasswordBasedEncryption.InitiateEncryption(
                    pbeParameters,
                    out SymmetricAlgorithm cipher,
                    out string hmacOid,
                    out string encryptionAlgorithmOid,
                    out bool isPkcs12);

                int         cipherBlockBytes = cipher.BlockSize / 8;
                byte[]      encryptedRent    = CryptoPool.Rent(contentsSpan.Length + cipherBlockBytes);
                Span <byte> encryptedSpan    = Span <byte> .Empty;
                Span <byte> iv   = stackalloc byte[cipherBlockBytes];
                Span <byte> salt = stackalloc byte[16];
                RandomNumberGenerator.Fill(salt);

                try
                {
                    int written = PasswordBasedEncryption.Encrypt(
                        password,
                        passwordBytes,
                        cipher,
                        isPkcs12,
                        contentsSpan,
                        pbeParameters,
                        salt,
                        encryptedRent,
                        iv);

                    encryptedSpan = encryptedRent.AsSpan(0, written);

                    writer = new AsnWriter(AsnEncodingRules.DER);

                    // EncryptedData
                    writer.PushSequence();

                    // version
                    // Since we're not writing unprotected attributes, version=0
                    writer.WriteInteger(0);

                    // encryptedContentInfo
                    {
                        writer.PushSequence();
                        writer.WriteObjectIdentifier(Oids.Pkcs7Data);

                        PasswordBasedEncryption.WritePbeAlgorithmIdentifier(
                            writer,
                            isPkcs12,
                            encryptionAlgorithmOid,
                            salt,
                            pbeParameters.IterationCount,
                            hmacOid,
                            iv);

                        writer.WriteOctetString(
                            new Asn1Tag(TagClass.ContextSpecific, 0),
                            encryptedSpan);

                        writer.PopSequence();
                    }

                    writer.PopSequence();

                    return(writer.Encode());
                }
                finally
                {
                    CryptographicOperations.ZeroMemory(encryptedSpan);
                    CryptoPool.Return(encryptedRent, clearSize: 0);
                    writer?.Dispose();
                }
            }
        }
Example #13
0
        public static void WriteAfterDispose(bool empty)
        {
            using (AsnWriter writer = new AsnWriter(AsnEncodingRules.DER))
            {
                if (!empty)
                {
                    writer.WriteNull();
                }

                writer.Dispose();

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteInteger(1));

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteInteger(1UL));

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteInteger(BigInteger.One));

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteInteger(BigInteger.One.ToByteArray(isBigEndian: true)));

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteInteger(Array.Empty <byte>()));

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteInteger(new byte[] { 0, 0 }));

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteInteger(new byte[] { 0xFF, 0xFF }));

                Assert.Throws <ArgumentException>(
                    "tag",
                    () => writer.WriteInteger(Asn1Tag.Boolean, 1));

                Assert.Throws <ArgumentException>(
                    "tag",
                    () => writer.WriteInteger(Asn1Tag.Boolean, 1UL));

                Assert.Throws <ArgumentException>(
                    "tag",
                    () => writer.WriteInteger(Asn1Tag.Boolean, BigInteger.One));

                Assert.Throws <ArgumentException>(
                    "tag",
                    () => writer.WriteInteger(Asn1Tag.Boolean, BigInteger.One.ToByteArray(isBigEndian: true)));

                Assert.Throws <ArgumentException>(
                    "tag",
                    () => writer.WriteInteger(Asn1Tag.Boolean, Array.Empty <byte>()));

                Assert.Throws <ArgumentException>(
                    "tag",
                    () => writer.WriteInteger(Asn1Tag.Boolean, new byte[] { 0, 0 }));

                Assert.Throws <ArgumentException>(
                    "tag",
                    () => writer.WriteInteger(Asn1Tag.Boolean, new byte[] { 0xFF, 0xFF }));

                Asn1Tag tag = new Asn1Tag(TagClass.Application, 0);

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteInteger(tag, 1));

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteInteger(tag, 1UL));

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteInteger(tag, BigInteger.One));

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteInteger(tag, BigInteger.One.ToByteArray(isBigEndian: true)));

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteInteger(tag, Array.Empty <byte>()));

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteInteger(tag, new byte[] { 0, 0 }));

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteInteger(tag, new byte[] { 0xFF, 0xFF }));
            }
        }
Example #14
0
        public static void WriteAfterDispose(bool empty)
        {
            using (AsnWriter writer = new AsnWriter(AsnEncodingRules.DER))
            {
                if (!empty)
                {
                    writer.WriteNull();
                }

                writer.Dispose();

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteObjectIdentifier("0.0"));

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteObjectIdentifier("0"));

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteObjectIdentifier("0.0q"));

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteObjectIdentifier("123"));

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteObjectIdentifier("4.0"));

                AssertExtensions.Throws <ArgumentNullException>(
                    "oidValue",
                    () => writer.WriteObjectIdentifier((string)null));

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteObjectIdentifier("0.0".AsSpan()));

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteObjectIdentifier("0".AsSpan()));

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteObjectIdentifier("0.0q".AsSpan()));

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteObjectIdentifier("123".AsSpan()));

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteObjectIdentifier("4.0".AsSpan()));

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteObjectIdentifier(new Oid("0.0", "valid")));

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteObjectIdentifier(new Oid("0", "short")));

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteObjectIdentifier(new Oid("0.0q", "invalid")));

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteObjectIdentifier(new Oid("123", "invalid")));

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteObjectIdentifier(new Oid("4.0", "invalid")));

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteObjectIdentifier(new Oid(null, "null")));

                AssertExtensions.Throws <ArgumentNullException>(
                    "oid",
                    () => writer.WriteObjectIdentifier((Oid)null));

                AssertExtensions.Throws <ArgumentException>(
                    "tag",
                    () => writer.WriteBoolean(Asn1Tag.Integer, false));

                AssertExtensions.Throws <ArgumentException>(
                    "tag",
                    () => writer.WriteObjectIdentifier(Asn1Tag.Integer, "0.0"));

                AssertExtensions.Throws <ArgumentException>(
                    "tag",
                    () => writer.WriteObjectIdentifier(Asn1Tag.Integer, "0"));

                AssertExtensions.Throws <ArgumentException>(
                    "tag",
                    () => writer.WriteObjectIdentifier(Asn1Tag.Integer, "0.0q"));

                AssertExtensions.Throws <ArgumentException>(
                    "tag",
                    () => writer.WriteObjectIdentifier(Asn1Tag.Integer, "123"));

                AssertExtensions.Throws <ArgumentException>(
                    "tag",
                    () => writer.WriteObjectIdentifier(Asn1Tag.Integer, "4.0"));

                AssertExtensions.Throws <ArgumentNullException>(
                    "oidValue",
                    () => writer.WriteObjectIdentifier(Asn1Tag.Integer, (string)null));

                AssertExtensions.Throws <ArgumentException>(
                    "tag",
                    () => writer.WriteObjectIdentifier(Asn1Tag.Integer, "0.0".AsSpan()));

                AssertExtensions.Throws <ArgumentException>(
                    "tag",
                    () => writer.WriteObjectIdentifier(Asn1Tag.Integer, "0".AsSpan()));

                AssertExtensions.Throws <ArgumentException>(
                    "tag",
                    () => writer.WriteObjectIdentifier(Asn1Tag.Integer, "0.0q".AsSpan()));

                AssertExtensions.Throws <ArgumentException>(
                    "tag",
                    () => writer.WriteObjectIdentifier(Asn1Tag.Integer, "123".AsSpan()));

                AssertExtensions.Throws <ArgumentException>(
                    "tag",
                    () => writer.WriteObjectIdentifier(Asn1Tag.Integer, "4.0".AsSpan()));

                AssertExtensions.Throws <ArgumentException>(
                    "tag",
                    () => writer.WriteObjectIdentifier(Asn1Tag.Integer, new Oid("0.0", "valid")));

                AssertExtensions.Throws <ArgumentException>(
                    "tag",
                    () => writer.WriteObjectIdentifier(Asn1Tag.Integer, new Oid("0", "short")));

                AssertExtensions.Throws <ArgumentException>(
                    "tag",
                    () => writer.WriteObjectIdentifier(Asn1Tag.Integer, new Oid("0.0q", "invalid")));

                AssertExtensions.Throws <ArgumentException>(
                    "tag",
                    () => writer.WriteObjectIdentifier(Asn1Tag.Integer, new Oid("123", "invalid")));

                AssertExtensions.Throws <ArgumentException>(
                    "tag",
                    () => writer.WriteObjectIdentifier(Asn1Tag.Integer, new Oid("4.0", "invalid")));

                AssertExtensions.Throws <ArgumentException>(
                    "tag",
                    () => writer.WriteObjectIdentifier(Asn1Tag.Integer, new Oid(null, "null")));

                AssertExtensions.Throws <ArgumentNullException>(
                    "oid",
                    () => writer.WriteObjectIdentifier(Asn1Tag.Integer, (Oid)null));

                Asn1Tag tag = new Asn1Tag(TagClass.ContextSpecific, 123);

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteObjectIdentifier(tag, "0.0"));

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteObjectIdentifier(tag, "0"));

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteObjectIdentifier(tag, "0.0q"));

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteObjectIdentifier(tag, "123"));

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteObjectIdentifier(tag, "4.0"));

                AssertExtensions.Throws <ArgumentNullException>(
                    "oidValue",
                    () => writer.WriteObjectIdentifier(tag, (string)null));

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteObjectIdentifier(tag, "0.0".AsSpan()));

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteObjectIdentifier(tag, "0".AsSpan()));

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteObjectIdentifier(tag, "0.0q".AsSpan()));

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteObjectIdentifier(tag, "123".AsSpan()));

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteObjectIdentifier(tag, "4.0".AsSpan()));

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteObjectIdentifier(tag, new Oid("0.0", "valid")));

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteObjectIdentifier(tag, new Oid("0", "short")));

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteObjectIdentifier(tag, new Oid("0.0q", "invalid")));

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteObjectIdentifier(tag, new Oid("123", "valid")));

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteObjectIdentifier(tag, new Oid("4.0", "valid")));

                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteObjectIdentifier(tag, new Oid(null, "null")));

                AssertExtensions.Throws <ArgumentNullException>(
                    "oid",
                    () => writer.WriteObjectIdentifier(tag, (Oid)null));
            }
        }
        public static void WriteAfterDispose(bool empty)
        {
            using (AsnWriter writer = new AsnWriter(AsnEncodingRules.DER))
            {
                if (!empty)
                {
                    writer.WriteNull();
                }

                writer.Dispose();

                // Type not enum
                AssertExtensions.Throws <ArgumentException>(
                    "enumType",
                    () => writer.WriteNamedBitList(false));

                // Type not enum
                AssertExtensions.Throws <ArgumentException>(
                    "enumType",
                    () => writer.WriteNamedBitList((object)"hi"));

                AssertExtensions.Throws <ArgumentNullException>(
                    "enumValue",
                    () => writer.WriteNamedBitList((object)null));

                // valid input
                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteNamedBitList(ReadNamedBitList.LongFlags.Mid));

                // Type is not [Flags]
                AssertExtensions.Throws <ArgumentException>(
                    "tEnum",
                    () => writer.WriteNamedBitList(ReadEnumerated.UIntBacked.Fluff));

                // valid input
                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteNamedBitList((object)ReadNamedBitList.ULongFlags.Mid));

                // Unboxed type is [Flags]
                AssertExtensions.Throws <ArgumentException>(
                    "tEnum",
                    () => writer.WriteNamedBitList((object)ReadEnumerated.SByteBacked.Fluff));

                AssertExtensions.Throws <ArgumentException>(
                    "tag",
                    () => writer.WriteNamedBitList(Asn1Tag.Integer, false));

                AssertExtensions.Throws <ArgumentException>(
                    "tag",
                    () => writer.WriteNamedBitList(Asn1Tag.Integer, (object)"hi"));

                AssertExtensions.Throws <ArgumentNullException>(
                    "enumValue",
                    () => writer.WriteNamedBitList(Asn1Tag.Integer, (object)null));

                AssertExtensions.Throws <ArgumentException>(
                    "tag",
                    () => writer.WriteNamedBitList(Asn1Tag.Integer, ReadNamedBitList.LongFlags.Mid));

                AssertExtensions.Throws <ArgumentException>(
                    "tag",
                    () => writer.WriteNamedBitList(Asn1Tag.Integer, ReadEnumerated.UIntBacked.Fluff));

                AssertExtensions.Throws <ArgumentException>(
                    "tag",
                    () => writer.WriteNamedBitList(Asn1Tag.Integer, (object)ReadNamedBitList.ULongFlags.Mid));

                AssertExtensions.Throws <ArgumentException>(
                    "tag",
                    () => writer.WriteNamedBitList(Asn1Tag.Integer, (object)ReadEnumerated.SByteBacked.Fluff));

                Asn1Tag tag = new Asn1Tag(TagClass.Private, 6);

                // Type not enum
                AssertExtensions.Throws <ArgumentException>(
                    "enumType",
                    () => writer.WriteNamedBitList(tag, false));

                // Type not enum
                AssertExtensions.Throws <ArgumentException>(
                    "enumType",
                    () => writer.WriteNamedBitList(tag, (object)"hi"));

                AssertExtensions.Throws <ArgumentNullException>(
                    "enumValue",
                    () => writer.WriteNamedBitList(tag, (object)null));

                // valid input
                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteNamedBitList(tag, ReadNamedBitList.LongFlags.Mid));

                // Type is [Flags]
                AssertExtensions.Throws <ArgumentException>(
                    "tEnum",
                    () => writer.WriteNamedBitList(tag, ReadEnumerated.UIntBacked.Fluff));

                // valid input
                Assert.Throws <ObjectDisposedException>(
                    () => writer.WriteNamedBitList(tag, (object)ReadNamedBitList.ULongFlags.Mid));

                // Unboxed type is not [Flags]
                AssertExtensions.Throws <ArgumentException>(
                    "tEnum",
                    () => writer.WriteNamedBitList(tag, (object)ReadEnumerated.SByteBacked.Fluff));
            }
        }
Example #16
0
        private byte[] ExportPfx(SafePasswordHandle password)
        {
            int certCount = 1;

            if (_singleCertPal == null)
            {
                Debug.Assert(_certs != null);
                certCount = _certs.Count;
            }

            CertBagAsn[] certBags = ArrayPool <CertBagAsn> .Shared.Rent(certCount);

            SafeBagAsn[] keyBags = ArrayPool <SafeBagAsn> .Shared.Rent(certCount);

            AttributeAsn[] certAttrs = ArrayPool <AttributeAsn> .Shared.Rent(certCount);

            certAttrs.AsSpan(0, certCount).Clear();

            AsnWriter           tmpWriter       = new AsnWriter(AsnEncodingRules.DER);
            ArraySegment <byte> encodedAuthSafe = default;

            bool gotRef = false;

            password.DangerousAddRef(ref gotRef);

            try
            {
                ReadOnlySpan <char> passwordSpan = password.DangerousGetSpan();

                int keyIdx  = 0;
                int certIdx = 0;

                if (_singleCertPal != null)
                {
                    BuildBags(
                        _singleCertPal,
                        passwordSpan,
                        tmpWriter,
                        certBags,
                        certAttrs,
                        keyBags,
                        ref certIdx,
                        ref keyIdx);
                }
                else
                {
                    foreach (X509Certificate2 cert in _certs)
                    {
                        BuildBags(
                            cert.Pal,
                            passwordSpan,
                            tmpWriter,
                            certBags,
                            certAttrs,
                            keyBags,
                            ref certIdx,
                            ref keyIdx);
                    }
                }

                encodedAuthSafe = EncodeAuthSafe(
                    tmpWriter,
                    keyBags,
                    keyIdx,
                    certBags,
                    certAttrs,
                    certIdx,
                    passwordSpan);

                return(MacAndEncode(tmpWriter, encodedAuthSafe, passwordSpan));
            }
            finally
            {
                password.DangerousRelease();
                tmpWriter.Dispose();
                certAttrs.AsSpan(0, certCount).Clear();
                certBags.AsSpan(0, certCount).Clear();
                keyBags.AsSpan(0, certCount).Clear();
                ArrayPool <AttributeAsn> .Shared.Return(certAttrs);

                ArrayPool <CertBagAsn> .Shared.Return(certBags);

                ArrayPool <SafeBagAsn> .Shared.Return(keyBags);

                if (encodedAuthSafe.Array != null)
                {
                    CryptoPool.Return(encodedAuthSafe);
                }
            }
        }