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);
        }
Esempio n. 2
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");
            }
        }
Esempio n. 3
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");
        }
Esempio n. 4
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());
        }
Esempio n. 5
0
        public static void CreatingBagSerializesInput()
        {
            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 });

            Pkcs12SafeContentsBag safeContentsBag = container.AddNestedContents(builtContents);

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

            Pkcs12SafeContents readContents = safeContentsBag.SafeContents;

            Assert.NotSame(readContents, builtContents);

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

            Assert.True(readContents.IsReadOnly);

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

            Assert.Equal(4, bags1.Count);
            Assert.Equal(3, 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");
            }
        }
Esempio n. 6
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());
                    }
        }
Esempio n. 7
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());
        }
Esempio n. 8
0
        private static void ProcessSafeContents(
            IndentedTextWriter writer,
            Pkcs12SafeContents safeContents,
            string scopeId,
            IDictionary <string, List <string> > keyMatches,
            ref string password)
        {
            writer.WriteLine($"ConfidentialityMode: {safeContents.ConfidentialityMode}");

            if (safeContents.ConfidentialityMode == Pkcs12ConfidentialityMode.Password)
            {
                if (password == null)
                {
                    try
                    {
                        safeContents.Decrypt(password);
                    }
                    catch (CryptographicException)
                    {
                        writer.Write("Enter password: "******"Password failed to decrypt contents");

                        return;
                    }
                }
            }
            else if (safeContents.ConfidentialityMode != Pkcs12ConfidentialityMode.None)
            {
                WriteLineWithColor(
                    ConsoleColor.Yellow,
                    writer,
                    "Cannot process contents, skipping.");

                return;
            }

            writer.WriteLine("Bags:");
            writer.Indent += 2;

            int j = -1;

            foreach (Pkcs12SafeBag bag in safeContents.GetBags())
            {
                j++;

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

                string localScopeId = $"Bag[{j}]";

                writer.Indent--;
                writer.WriteLine($"{localScopeId} ({bag.GetType().Name}): ({bag.GetBagId().Value})");
                writer.Indent++;

                ProcessBagDetails(
                    writer,
                    bag,
                    $"{scopeId}/{localScopeId}",
                    keyMatches,
                    ref password);

                writer.Indent--;
            }
        }