Exemplo n.º 1
0
        public static void CopyEncryptedSafeContents(bool withSpan)
        {
            Pkcs12Builder builder1 = new Pkcs12Builder();
            Pkcs12Builder builder2 = new Pkcs12Builder();

            Pkcs12SafeContents contents = new Pkcs12SafeContents();

            contents.AddSecret(s_zeroOid, s_derNull);

            if (withSpan)
            {
                builder1.AddSafeContentsEncrypted(contents, ReadOnlySpan <byte> .Empty, s_pbkdf2Parameters);
            }
            else
            {
                builder1.AddSafeContentsEncrypted(contents, (byte[])null, s_pbkdf2Parameters);
            }

            builder1.SealWithoutIntegrity();

            byte[]     encoded1 = builder1.Encode();
            Pkcs12Info info     = Pkcs12Info.Decode(encoded1, out _, skipCopy: true);

            Assert.Equal(Pkcs12IntegrityMode.None, info.IntegrityMode);
            Assert.Equal(1, info.AuthenticatedSafe.Count);

            builder2.AddSafeContentsUnencrypted(info.AuthenticatedSafe[0]);
            builder2.SealWithoutIntegrity();

            byte[] encoded2 = builder2.Encode();
            Assert.Equal(encoded1.ByteArrayToHex(), encoded2.ByteArrayToHex());
        }
Exemplo n.º 2
0
 private static void CheckMac(Pkcs12Info info, string password)
 {
     Assert.True(info.VerifyMac(password), "VerifyMac (correct password)");
     Assert.False(info.VerifyMac(ReadOnlySpan <char> .Empty), "VerifyMac (empty password)");
     Assert.False(info.VerifyMac(password + password), "VerifyMac (doubled password)");
     Assert.False(info.VerifyMac(new string('a', 1048)), "VerifyMac (password > 1k)");
 }
Exemplo n.º 3
0
        private static bool TryReadPkcs12CertificateBundle
            (string certificatePath,
            string password,
            out X509Certificate2 certificate,
            out X509Certificate2Collection intermediates)
        {
            var pkcs12Info = Pkcs12Info.Decode(File.ReadAllBytes(certificatePath), out _);

            var certs = new X509Certificate2Collection();

            using var rsa = RSA.Create();
            var privateKeyFound = false;

            foreach (var safeContents in pkcs12Info.AuthenticatedSafe)
            {
                if (safeContents.ConfidentialityMode == Pkcs12ConfidentialityMode.Password)
                {
                    safeContents.Decrypt(password);
                }

                foreach (var bag in safeContents.GetBags())
                {
                    switch (bag)
                    {
                    case Pkcs12CertBag certBag:
                        certs.Add(certBag.GetCertificate());
                        break;

                    case Pkcs12ShroudedKeyBag shroudedKeyBag:
                    {
                        if (privateKeyFound)
                        {
                            throw new Exception("Multiple private keys found");
                        }
                        var encryptedKey = shroudedKeyBag.EncryptedPkcs8PrivateKey;
                        rsa.ImportEncryptedPkcs8PrivateKey(password.AsSpan(), encryptedKey.Span, out _);
                        privateKeyFound = true;
                        break;
                    }
                    }
                }
            }

            if (certs.Count == 0)
            {
                throw new Exception("No certificates found");
            }

            if (!privateKeyFound)
            {
                throw new Exception("No private keys found");
            }

            using var publicCertificate = certs[0];
            using var publicWithPrivate = publicCertificate.CopyWithPrivateKey(rsa);
            certs.RemoveAt(0);
            certificate   = new X509Certificate2(publicWithPrivate.Export(X509ContentType.Pfx));
            intermediates = certs.Count == 0 ? null : certs;
            return(true);
        }
Exemplo n.º 4
0
        public static void EncryptEncryptedSafeContents()
        {
            Pkcs12Builder builder1 = new Pkcs12Builder();
            Pkcs12Builder builder2 = new Pkcs12Builder();

            Pkcs12SafeContents contents = new Pkcs12SafeContents();

            contents.AddSecret(s_zeroOid, s_derNull);

            builder1.AddSafeContentsEncrypted(contents, ReadOnlySpan <byte> .Empty, s_pbkdf2Parameters);
            builder1.SealWithoutIntegrity();

            byte[]     encoded = builder1.Encode();
            Pkcs12Info info    = Pkcs12Info.Decode(encoded, out _, skipCopy: true);

            Assert.Equal(Pkcs12IntegrityMode.None, info.IntegrityMode);
            Assert.Equal(1, info.AuthenticatedSafe.Count);

            AssertExtensions.Throws <ArgumentException>(
                "safeContents",
                () => builder2.AddSafeContentsEncrypted(
                    info.AuthenticatedSafe[0],
                    "nope",
                    s_pbkdf2Parameters));

            AssertExtensions.Throws <ArgumentException>(
                "safeContents",
                () => builder2.AddSafeContentsEncrypted(
                    info.AuthenticatedSafe[0],
                    s_derNull.Span,
                    s_pbkdf2Parameters));
        }
Exemplo n.º 5
0
        public static void ReadCustomType()
        {
            byte[] input = (
                "3033020103302E06092A864886F70D010701A021041F301D301B06092A864886" +
                "F70D010701A00E040C300A3008060100A003040102").HexToByteArray();

            Pkcs12Info info = Pkcs12Info.Decode(input, out _, skipCopy: true);

            Assert.Equal(Pkcs12IntegrityMode.None, info.IntegrityMode);

            ReadOnlyCollection <Pkcs12SafeContents> allContents = info.AuthenticatedSafe;

            Assert.Equal(1, allContents.Count);

            Pkcs12SafeContents contents = allContents[0];

            Assert.Equal(Pkcs12ConfidentialityMode.None, contents.ConfidentialityMode);

            List <Pkcs12SafeBag> bags = contents.GetBags().ToList();

            Assert.Equal(1, bags.Count);

            Pkcs12SafeBag bag = bags[0];

            Assert.IsNotType <Pkcs12CertBag>(bag);
            Assert.IsNotType <Pkcs12KeyBag>(bag);
            Assert.IsNotType <Pkcs12SecretBag>(bag);
            Assert.IsNotType <Pkcs12ShroudedKeyBag>(bag);

            CustomBagType customBag = new CustomBagType(bag.EncodedBagValue);

            Assert.Equal(2, customBag.Value);
        }
Exemplo n.º 6
0
        public static void ReadEmptyPfx(int trailingByteCount)
        {
            ReadOnlyMemory <byte> source = PadContents(Pkcs12Documents.EmptyPfx, trailingByteCount);

            Pkcs12Info info =
                Pkcs12Info.Decode(source, out int bytesRead, skipCopy: true);

            Assert.Equal(Pkcs12Documents.EmptyPfx.Length, bytesRead);
            Assert.Equal(Pkcs12IntegrityMode.Password, info.IntegrityMode);

            Assert.False(info.VerifyMac("hello"), "Wrong password");
            Assert.True(info.VerifyMac(ReadOnlySpan <char> .Empty), "null password (ReadOnlySpan)");
            Assert.True(info.VerifyMac(null), "null password (string)");
            Assert.False(info.VerifyMac("".AsSpan()), "empty password (ReadOnlySpan)");
            Assert.False(info.VerifyMac(""), "empty password (string)");
            Assert.False(info.VerifyMac("hello".AsSpan(5)), "sliced out");
            Assert.False(info.VerifyMac("hello".AsSpan(0, 0)), "zero-sliced");
            Assert.False(info.VerifyMac(new char[0]), "empty array");
            Assert.False(info.VerifyMac((new char[1]).AsSpan(1)), "sliced out array");
            Assert.False(info.VerifyMac((new char[1]).AsSpan(0, 0)), "zero-sliced array");

            ReadOnlyCollection <Pkcs12SafeContents> safes = info.AuthenticatedSafe;

            Assert.Equal(0, safes.Count);
        }
Exemplo n.º 7
0
        public static void ReadSerializedData(bool encryptSafe)
        {
            Pkcs12SafeContents container = new Pkcs12SafeContents();

            Pkcs12SafeContents builtContents = new Pkcs12SafeContents();

            builtContents.AddSecret(s_zeroOid, s_derNull);

            builtContents.AddSecret(s_zeroOid, new byte[] { 4, 1, 2 }).Attributes.Add(
                new Pkcs9LocalKeyId(s_derNull.Span));

            builtContents.AddSecret(s_zeroOid, new byte[] { 4, 1, 3 });
            container.AddNestedContents(builtContents);

            Pkcs12Builder builder = new Pkcs12Builder();

            if (encryptSafe)
            {
                builder.AddSafeContentsEncrypted(container, s_derNull.Span, s_pbkdf2Parameters);
            }
            else
            {
                builder.AddSafeContentsUnencrypted(container);
            }

            builder.SealWithoutIntegrity();
            byte[] encoded = builder.Encode();

            Pkcs12Info         info     = Pkcs12Info.Decode(encoded, out _, skipCopy: true);
            Pkcs12SafeContents onlySafe = info.AuthenticatedSafe.Single();

            if (encryptSafe)
            {
                onlySafe.Decrypt(s_derNull.Span);
            }

            Pkcs12SafeBag         onlyBag         = onlySafe.GetBags().Single();
            Pkcs12SafeContentsBag safeContentsBag = Assert.IsType <Pkcs12SafeContentsBag>(onlyBag);
            Pkcs12SafeContents    readContents    = safeContentsBag.SafeContents;

            Assert.Equal(
                Pkcs12ConfidentialityMode.None,
                readContents.ConfidentialityMode);

            Assert.True(readContents.IsReadOnly);

            List <Pkcs12SafeBag> bags1 = builtContents.GetBags().ToList();
            List <Pkcs12SafeBag> bags2 = readContents.GetBags().ToList();

            Assert.Equal(bags1.Count, bags2.Count);

            for (int i = 0; i < bags2.Count; i++)
            {
                byte[] encoded1 = bags1[i].Encode();
                byte[] encoded2 = bags1[i].Encode();

                Assert.True(encoded1.AsSpan().SequenceEqual(encoded2), $"Bag {i} encodes the same");
            }
        }
Exemplo n.º 8
0
        public static void ReadOracleWallet(int trailingByteCount)
        {
            ReadOnlyMemory <byte> source = PadContents(Pkcs12Documents.SimpleOracleWallet, trailingByteCount);

            Pkcs12Info info = Pkcs12Info.Decode(
                source,
                out int bytesRead,
                skipCopy: true);

            Assert.Equal(Pkcs12Documents.SimpleOracleWallet.Length, bytesRead);
            Assert.Equal(Pkcs12IntegrityMode.Password, info.IntegrityMode);
            Assert.False(info.VerifyMac(ReadOnlySpan <char> .Empty), "VerifyMac(no password)");
            Assert.False(info.VerifyMac(""), "VerifyMac(empty password)");
            Assert.True(info.VerifyMac(Pkcs12Documents.OracleWalletPassword), "VerifyMac(correct password)");

            ReadOnlyCollection <Pkcs12SafeContents> authSafes = info.AuthenticatedSafe;

            Assert.Equal(1, authSafes.Count);

            Pkcs12SafeContents authSafe = authSafes[0];

            Assert.Equal(Pkcs12ConfidentialityMode.Password, authSafe.ConfidentialityMode);
            // Wrong password
            Assert.ThrowsAny <CryptographicException>(() => authSafe.Decrypt(ReadOnlySpan <char> .Empty));
            authSafe.Decrypt(Pkcs12Documents.OracleWalletPassword);

            Assert.Equal(Pkcs12ConfidentialityMode.None, authSafe.ConfidentialityMode);

            List <Pkcs12SafeBag> bags = authSafe.GetBags().ToList();

            Assert.Equal(4, bags.Count);

            CheckOracleSecretBag(
                bags[0],
                "oracle.security.client.connect_string1",
                "a_prod_db",
                "E6B652DD0000000400000000000000060000000300000000");

            CheckOracleSecretBag(
                bags[1],
                "a@#3#@b", "{pwd_cred_type}@#4#@NEVER_EXPIRE@#5#@c@#111#@d",
                "E6B652DD0000000400000000000000060000000200000000");

            CheckOracleSecretBag(
                bags[2],
                "oracle.security.client.username1",
                "a_test_user",
                "E6B652DD0000000400000000000000060000000100000000");

            CheckOracleSecretBag(
                bags[3],
                "oracle.security.client.password1",
                "potatos are tasty",
                "E6B652DD0000000400000000000000060000000000000000");
        }
Exemplo n.º 9
0
        public static void GetBagsThrowsForConfidentialData()
        {
            var loader = (CertLoaderFromRawData)Certificates.RSAKeyTransfer_ExplicitSki;
            ReadOnlyMemory <byte> pfxData       = loader.PfxData;
            Pkcs12Info            info          = Pkcs12Info.Decode(pfxData, out _, skipCopy: true);
            Pkcs12SafeContents    firstContents = info.AuthenticatedSafe[0];

            Assert.Equal(
                Pkcs12ConfidentialityMode.Password,
                firstContents.ConfidentialityMode);

            Assert.Throws <InvalidOperationException>(() => firstContents.GetBags());
        }
Exemplo n.º 10
0
        public static void DecryptThrowsForWrongPassword()
        {
            var loader = (CertLoaderFromRawData)Certificates.RSAKeyTransfer_ExplicitSki;
            ReadOnlyMemory <byte> pfxData       = loader.PfxData;
            Pkcs12Info            info          = Pkcs12Info.Decode(pfxData, out _, skipCopy: true);
            Pkcs12SafeContents    firstContents = info.AuthenticatedSafe[0];

            Assert.Equal(
                Pkcs12ConfidentialityMode.Password,
                firstContents.ConfidentialityMode);

            // This password experimentally encounters a PKCS7 padding verification error.
            Assert.ThrowsAny <CryptographicException>(() => firstContents.Decrypt("000"));
            // This password experimentally does not get a PKCS7 padding error,
            // but gets a deserialization error
            Assert.ThrowsAny <CryptographicException>(() => firstContents.Decrypt("0G7"));
        }
Exemplo n.º 11
0
        public static void AddEncryptedNestedContents()
        {
            Pkcs12Builder      builder  = new Pkcs12Builder();
            Pkcs12SafeContents contents = new Pkcs12SafeContents();

            contents.AddSecret(s_zeroOid, s_derNull);

            builder.AddSafeContentsEncrypted(contents, "hi", s_pbeParameters);
            builder.SealWithoutIntegrity();

            byte[]     encoded = builder.Encode();
            Pkcs12Info info    = Pkcs12Info.Decode(encoded, out _, skipCopy: true);

            Assert.Equal(Pkcs12IntegrityMode.None, info.IntegrityMode);
            Assert.Equal(1, info.AuthenticatedSafe.Count);

            Pkcs12SafeContents newContents = new Pkcs12SafeContents();

            AssertExtensions.Throws <ArgumentException>(
                "safeContents",
                () => newContents.AddNestedContents(info.AuthenticatedSafe[0]));
        }
Exemplo n.º 12
0
        public static void CopyCustomType()
        {
            const string startHex =
                "3033020103302E06092A864886F70D010701A021041F301D301B06092A864886" +
                "F70D010701A00E040C300A3008060100A003040102";

            Pkcs12Info info = Pkcs12Info.Decode(startHex.HexToByteArray(), out _, skipCopy: true);
            // This next line implicitly asserts no encryption, and a couple of Single
            Pkcs12SafeBag bag = info.AuthenticatedSafe.Single().GetBags().Single();

            Pkcs12SafeContents contents = new Pkcs12SafeContents();

            contents.AddSafeBag(bag);

            Pkcs12Builder builder = new Pkcs12Builder();

            builder.AddSafeContentsUnencrypted(contents);
            builder.SealWithoutIntegrity();
            byte[] encoded = builder.Encode();

            Assert.Equal(startHex, encoded.ByteArrayToHex());
        }
Exemplo n.º 13
0
        public static void Test1()
        {
            var loader = (CertLoaderFromRawData)Certificates.RSAKeyTransferCapi1;
            ReadOnlyMemory <byte> pfxData = loader.PfxData;

            Pkcs12Info info = Pkcs12Info.Decode(pfxData, out int bytesConsumed);

            Assert.Equal(pfxData.Length, bytesConsumed);

            Assert.Equal(Pkcs12IntegrityMode.Password, info.IntegrityMode);
            CheckMac(info, loader.Password);

            ReadOnlyCollection <Pkcs12SafeContents> authSafe = info.AuthenticatedSafe;

            Assert.Same(authSafe, info.AuthenticatedSafe);
            Assert.Equal(2, authSafe.Count);

            Assert.Equal(Pkcs12ConfidentialityMode.None, authSafe[0].ConfidentialityMode);
            Assert.Equal(Pkcs12ConfidentialityMode.None, authSafe[1].ConfidentialityMode);

            List <Pkcs12SafeBag> safe0Bags = new List <Pkcs12SafeBag>(authSafe[0].GetBags());

            Assert.Equal(1, safe0Bags.Count);
            Pkcs12ShroudedKeyBag shroudedKeyBag = Assert.IsType <Pkcs12ShroudedKeyBag>(safe0Bags[0]);

            CryptographicAttributeObjectCollection keyBagAttrs = shroudedKeyBag.Attributes;

            Assert.Same(keyBagAttrs, shroudedKeyBag.Attributes);
            Assert.Equal(2, keyBagAttrs.Count);
            Assert.Equal(Oids.LocalKeyId, keyBagAttrs[0].Oid.Value);
            Assert.Equal(1, keyBagAttrs[0].Values.Count);
            Pkcs9LocalKeyId keyKeyId = Assert.IsType <Pkcs9LocalKeyId>(keyBagAttrs[0].Values[0]);

            Assert.Equal("1.3.6.1.4.1.311.17.1", keyBagAttrs[1].Oid.Value);
            Assert.Equal(1, keyBagAttrs[1].Values.Count);
            Pkcs9AttributeObject cspNameAttr = Assert.IsType <Pkcs9AttributeObject>(keyBagAttrs[1].Values[0]);

            byte[] cspNameBytes = Encoding.BigEndianUnicode.GetBytes("Microsoft Strong Cryptographic Provider");

            Assert.Equal(
                $"1E{cspNameBytes.Length:X2}{cspNameBytes.ByteArrayToHex()}",
                cspNameAttr.RawData.ByteArrayToHex());

            List <Pkcs12SafeBag> safe1Bags = new List <Pkcs12SafeBag>(authSafe[1].GetBags());

            Assert.Equal(1, safe0Bags.Count);
            Assert.IsType <Pkcs12CertBag>(safe1Bags[0]);
            Pkcs12CertBag certBag = (Pkcs12CertBag)safe1Bags[0];

            Assert.True(certBag.IsX509Certificate, "certBag.IsX509Certificate");
            Assert.InRange(certBag.EncodedCertificate.Length, loader.CerData.Length + 2, int.MaxValue);

            CryptographicAttributeObjectCollection certBagAttrs = certBag.Attributes;

            Assert.Same(certBagAttrs, certBag.Attributes);
            Assert.Equal(1, certBagAttrs.Count);
            Assert.Equal(Oids.LocalKeyId, certBagAttrs[0].Oid.Value);
            Assert.Equal(1, certBagAttrs[0].Values.Count);
            Pkcs9LocalKeyId certKeyId = Assert.IsType <Pkcs9LocalKeyId>(certBagAttrs[0].Values[0]);

            Assert.Equal(keyKeyId.KeyId.ByteArrayToHex(), certKeyId.KeyId.ByteArrayToHex());

            byte[] data = { 9, 8, 7, 6, 5, 4, 3, 2, 1 };
            byte[] encrypted;

            using (X509Certificate2 fromLoader = loader.GetCertificate())
                using (X509Certificate2 fromBag = certBag.GetCertificate())
                    using (RSA loaderPub = fromLoader.GetRSAPublicKey())
                    {
                        Assert.Equal(fromLoader.RawData, fromBag.RawData);

                        encrypted = loaderPub.Encrypt(data, RSAEncryptionPadding.OaepSHA1);
                    }

            int bytesRead;

            using (RSA rsa = RSA.Create())
            {
                rsa.ImportEncryptedPkcs8PrivateKey(
                    loader.Password,
                    shroudedKeyBag.EncryptedPkcs8PrivateKey.Span,
                    out bytesRead);

                byte[] dec = rsa.Decrypt(encrypted, RSAEncryptionPadding.OaepSHA1);
                Assert.Equal(data, dec);
            }

            Assert.Equal(shroudedKeyBag.EncryptedPkcs8PrivateKey.Length, bytesRead);
        }
Exemplo n.º 14
0
        public static void EncryptDecryptMixBytesAndChars(bool encryptBytes, bool withSpan)
        {
            Pkcs12SafeContents contents = new Pkcs12SafeContents();

            contents.AddSecret(s_zeroOid, s_derNull);

            string      password          = nameof(EncryptDecryptMixBytesAndChars);
            Span <byte> passwordUtf8Bytes = stackalloc byte[password.Length];

            Encoding.UTF8.GetBytes(password, passwordUtf8Bytes);

            Pkcs12Builder builder = new Pkcs12Builder();

            if (encryptBytes)
            {
                builder.AddSafeContentsEncrypted(contents, passwordUtf8Bytes, s_pbkdf2Parameters);
            }
            else
            {
                builder.AddSafeContentsEncrypted(contents, password, s_pbkdf2Parameters);
            }

            builder.SealWithMac(password, HashAlgorithmName.SHA1, 2048);

            byte[]     encoded = builder.Encode();
            Pkcs12Info info    = Pkcs12Info.Decode(encoded, out _, skipCopy: true);

            Assert.True(info.VerifyMac(password));
            ReadOnlyCollection <Pkcs12SafeContents> authSafe = info.AuthenticatedSafe;

            Assert.Equal(1, authSafe.Count);

            Pkcs12SafeContents readContents = authSafe[0];

            Assert.Equal(
                Pkcs12ConfidentialityMode.Password,
                readContents.ConfidentialityMode);

            if (encryptBytes)
            {
                if (withSpan)
                {
                    readContents.Decrypt(password.AsSpan());
                }
                else
                {
                    readContents.Decrypt(password);
                }
            }
            else
            {
                if (withSpan)
                {
                    readContents.Decrypt(passwordUtf8Bytes);
                }
                else
                {
                    readContents.Decrypt(passwordUtf8Bytes.ToArray());
                }
            }

            Assert.Equal(
                Pkcs12ConfidentialityMode.None,
                readContents.ConfidentialityMode);

            List <Pkcs12SafeBag> bags = readContents.GetBags().ToList();

            Assert.Equal(1, bags.Count);
            Pkcs12SecretBag secretBag = Assert.IsType <Pkcs12SecretBag>(bags[0]);

            Assert.Equal(s_zeroOid.Value, secretBag.GetSecretType().Value);
            Assert.Equal(s_derNull.ByteArrayToHex(), secretBag.SecretValue.ByteArrayToHex());
        }
Exemplo n.º 15
0
        public static void ReadWithEncryptedContents()
        {
            var loader = (CertLoaderFromRawData)Certificates.RSAKeyTransfer_ExplicitSki;
            ReadOnlyMemory <byte> pfxData = loader.PfxData;

            Pkcs12Info info = Pkcs12Info.Decode(pfxData, out int bytesConsumed);

            Assert.Equal(pfxData.Length, bytesConsumed);

            Assert.Equal(Pkcs12IntegrityMode.Password, info.IntegrityMode);
            CheckMac(info, loader.Password);

            ReadOnlyCollection <Pkcs12SafeContents> authSafe = info.AuthenticatedSafe;

            Assert.Same(authSafe, info.AuthenticatedSafe);
            Assert.Equal(2, authSafe.Count);

            Assert.Equal(Pkcs12ConfidentialityMode.Password, authSafe[0].ConfidentialityMode);
            Assert.Equal(Pkcs12ConfidentialityMode.None, authSafe[1].ConfidentialityMode);

            Assert.ThrowsAny <CryptographicException>(
                () => authSafe[0].Decrypt(loader.Password.AsSpan().Slice(1)));

            Assert.Equal(Pkcs12ConfidentialityMode.Password, authSafe[0].ConfidentialityMode);
            authSafe[0].Decrypt(loader.Password);
            Assert.Equal(Pkcs12ConfidentialityMode.None, authSafe[0].ConfidentialityMode);

            List <Pkcs12SafeBag> safe0Bags = new List <Pkcs12SafeBag>(authSafe[0].GetBags());

            Assert.Equal(1, safe0Bags.Count);
            Pkcs12CertBag certBag = Assert.IsType <Pkcs12CertBag>(safe0Bags[0]);

            Assert.True(certBag.IsX509Certificate, "certBag.IsX509Certificate");
            Assert.InRange(certBag.EncodedCertificate.Length, loader.CerData.Length + 2, int.MaxValue);

            List <Pkcs12SafeBag> safe1Bags = new List <Pkcs12SafeBag>(authSafe[1].GetBags());

            Assert.Equal(1, safe0Bags.Count);
            Pkcs12ShroudedKeyBag shroudedKeyBag = Assert.IsType <Pkcs12ShroudedKeyBag>(safe1Bags[0]);

            byte[] data = { 9, 8, 7, 6, 5, 4, 3, 2, 1 };
            byte[] encrypted;

            using (X509Certificate2 fromLoader = loader.GetCertificate())
                using (X509Certificate2 fromBag = certBag.GetCertificate())
                    using (RSA loaderPub = fromLoader.GetRSAPublicKey())
                    {
                        Assert.Equal(fromLoader.RawData, fromBag.RawData);

                        encrypted = loaderPub.Encrypt(data, RSAEncryptionPadding.OaepSHA1);
                    }

            int bytesRead;

            using (RSA rsa = RSA.Create())
            {
                rsa.ImportEncryptedPkcs8PrivateKey(
                    loader.Password,
                    shroudedKeyBag.EncryptedPkcs8PrivateKey.Span,
                    out bytesRead);

                byte[] dec = rsa.Decrypt(encrypted, RSAEncryptionPadding.OaepSHA1);
                Assert.Equal(data, dec);
            }

            Assert.Equal(shroudedKeyBag.EncryptedPkcs8PrivateKey.Length, bytesRead);
        }
Exemplo n.º 16
0
        public static void ReadIndefiniteEncodingNoMac(int trailingByteCount)
        {
            ReadOnlyMemory <byte> source = PadContents(Pkcs12Documents.IndefiniteEncodingNoMac, trailingByteCount);

            Pkcs12Info info = Pkcs12Info.Decode(
                source,
                out int bytesRead,
                skipCopy: true);

            Assert.Equal(Pkcs12Documents.IndefiniteEncodingNoMac.Length, bytesRead);
            Assert.Equal(Pkcs12IntegrityMode.None, info.IntegrityMode);

            ReadOnlyCollection <Pkcs12SafeContents> safes = info.AuthenticatedSafe;

            Assert.Equal(2, safes.Count);

            Pkcs12SafeContents firstSafe  = safes[0];
            Pkcs12SafeContents secondSafe = safes[1];

            Assert.Equal(Pkcs12ConfidentialityMode.None, firstSafe.ConfidentialityMode);
            Assert.Equal(Pkcs12ConfidentialityMode.None, secondSafe.ConfidentialityMode);

            Assert.True(firstSafe.IsReadOnly, "firstSafe.IsReadOnly");
            Assert.True(secondSafe.IsReadOnly, "secondSafe.IsReadOnly");

            Pkcs12SafeBag[] firstContents  = firstSafe.GetBags().ToArray();
            Pkcs12SafeBag[] secondContents = secondSafe.GetBags().ToArray();

            Assert.Equal(1, firstContents.Length);
            Assert.Equal(1, secondContents.Length);

            Pkcs12KeyBag  keyBag  = Assert.IsType <Pkcs12KeyBag>(firstContents[0]);
            Pkcs12CertBag certBag = Assert.IsType <Pkcs12CertBag>(secondContents[0]);

            CryptographicAttributeObjectCollection keyBagAttrs  = keyBag.Attributes;
            CryptographicAttributeObjectCollection certBagAttrs = certBag.Attributes;

            Assert.Equal(2, keyBagAttrs.Count);
            Assert.Equal(2, certBagAttrs.Count);

            Assert.Equal(Oids.FriendlyName, keyBagAttrs[0].Oid.Value);
            Assert.Equal(1, keyBagAttrs[0].Values.Count);
            Assert.Equal(Oids.LocalKeyId, keyBagAttrs[1].Oid.Value);
            Assert.Equal(1, keyBagAttrs[1].Values.Count);

            Pkcs9AttributeObject keyFriendlyName =
                Assert.IsAssignableFrom <Pkcs9AttributeObject>(keyBagAttrs[0].Values[0]);

            Pkcs9LocalKeyId keyKeyId = Assert.IsType <Pkcs9LocalKeyId>(keyBagAttrs[1].Values[0]);

            Assert.Equal(Oids.FriendlyName, certBagAttrs[0].Oid.Value);
            Assert.Equal(1, certBagAttrs[0].Values.Count);
            Assert.Equal(Oids.LocalKeyId, certBagAttrs[1].Oid.Value);
            Assert.Equal(1, certBagAttrs[1].Values.Count);

            Pkcs9AttributeObject certFriendlyName =
                Assert.IsAssignableFrom <Pkcs9AttributeObject>(certBagAttrs[0].Values[0]);

            Pkcs9LocalKeyId certKeyId = Assert.IsType <Pkcs9LocalKeyId>(certBagAttrs[1].Values[0]);

            // This PFX gave a friendlyName value of "cert" to both the key and the cert.
            Assert.Equal("1E080063006500720074", keyFriendlyName.RawData.ByteArrayToHex());
            Assert.Equal(keyFriendlyName.RawData, certFriendlyName.RawData);

            // The private key (KeyBag) and the public key (CertBag) are matched from their keyId value.
            Assert.Equal("0414EDF3D122CF623CF0CFC9CD226261E8415A83E630", keyKeyId.RawData.ByteArrayToHex());
            Assert.Equal("EDF3D122CF623CF0CFC9CD226261E8415A83E630", keyKeyId.KeyId.ByteArrayToHex());
            Assert.Equal(keyKeyId.RawData, certKeyId.RawData);

            using (X509Certificate2 cert = certBag.GetCertificate())
                using (RSA privateKey = RSA.Create())
                    using (RSA publicKey = cert.GetRSAPublicKey())
                    {
                        privateKey.ImportPkcs8PrivateKey(keyBag.Pkcs8PrivateKey.Span, out _);

                        Assert.Equal(
                            publicKey.ExportSubjectPublicKeyInfo().ByteArrayToHex(),
                            privateKey.ExportSubjectPublicKeyInfo().ByteArrayToHex());
                    }
        }
Exemplo n.º 17
0
        private static int Main(string[] args)
        {
            byte[] pfxBytes    = null;
            string password    = null;
            string macPassword = null;
            SortedDictionary <string, List <string> > keyMatches = new SortedDictionary <string, List <string> >();

            if (args.Length > 0)
            {
                try
                {
                    pfxBytes = File.ReadAllBytes(args[0]);
                }
                catch
                {
                }

                if (args.Length > 1)
                {
                    if (PromptString != args[1])
                    {
                        password = args[1];
                    }
                }

                if (args.Length > 2)
                {
                    if (PromptString != args[2])
                    {
                        macPassword = args[2];
                    }
                }
                else
                {
                    macPassword = password;
                }
            }

            if (pfxBytes == null)
            {
                Console.WriteLine("Usage: PfxDataPrinter <pfxfile> [password] [macpassword]");
                Console.WriteLine();
                Console.WriteLine($"  Specify {PromptString} for both/either password to be prompted.");
                Console.WriteLine("  If no password is given and one is needed one prompt will apply to both passwords");
                Console.WriteLine();
                return(1);
            }

            try
            {
                using (IndentedTextWriter writer = new IndentedTextWriter(Console.Out, "  "))
                {
                    writer.WriteLine($"Opening {args[0]}.");
                    writer.Flush();

                    Pkcs12Info info = Pkcs12Info.Decode(pfxBytes, out int consumed, skipCopy: true);

                    writer.WriteLine($"{consumed}/{pfxBytes.Length} bytes read as a PFX.");
                    writer.WriteLine($"PFX integrity mode: {info.IntegrityMode}");

                    if (info.IntegrityMode != Pkcs12IntegrityMode.None)
                    {
                        if (info.VerifyMac(macPassword))
                        {
                            writer.WriteLine(
                                "MAC verified with {0} password.",
                                macPassword == null ? "default" : "provided");
                        }
                        else if (macPassword != null)
                        {
                            WriteLineWithColor(
                                ConsoleColor.Yellow,
                                writer,
                                "MAC does not verify with provided password.");
                            return(3);
                        }
                        else
                        {
                            writer.Write("Enter {0}password: "******"MAC " : "");
                            writer.Flush();
                            macPassword = Console.In.ReadLine();

                            if (info.VerifyMac(macPassword))
                            {
                                writer.WriteLine("MAC verified with provided password.");

                                // No password was given
                                if (args.Length == 1)
                                {
                                    password = macPassword;
                                }
                            }
                            else
                            {
                                WriteLineWithColor(
                                    ConsoleColor.Yellow,
                                    writer,
                                    "MAC does not verify with provided password.");

                                return(3);
                            }
                        }
                    }

                    writer.WriteLine();
                    writer.Indent++;

                    int i = -1;

                    foreach (Pkcs12SafeContents safeContents in info.AuthenticatedSafe)
                    {
                        i++;

                        if (i > 0)
                        {
                            writer.WriteLine();
                        }

                        string localScope = $"Safe[{i}]";

                        writer.Indent--;
                        writer.WriteLine($"AuthenticatedSafe[{i}]:");
                        writer.Indent++;

                        ProcessSafeContents(
                            writer,
                            safeContents,
                            localScope,
                            keyMatches,
                            ref password);

                        writer.Indent -= 2;
                    }

                    writer.Indent--;

                    writer.WriteLine();

                    if (keyMatches.Count == 0)
                    {
                        writer.WriteLine("No LocalKeyIds were present");
                    }
                    else
                    {
                        writer.WriteLine("Local Key IDs:");
                        writer.Indent++;
                        bool first = true;

                        foreach ((string keyId, List <string> scopes) in keyMatches)
                        {
                            if (!first)
                            {
                                writer.WriteLine();
                            }

                            first = false;

                            writer.WriteLine(keyId);

                            scopes.Sort();
                            writer.Indent++;

                            foreach (string scope in scopes)
                            {
                                writer.WriteLine(scope);
                            }

                            writer.Indent--;
                        }

                        writer.Indent--;
                    }
                }

                return(0);
            }
            catch (Exception e)
            {
                Console.WriteLine();
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("Exception:");
                Console.WriteLine(e);
                Console.ResetColor();
                return(2);
            }
        }