コード例 #1
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));
        }
コード例 #2
0
        public static void AddContentsAfterSealing()
        {
            Pkcs12SafeContents contents = new Pkcs12SafeContents();

            contents.AddSecret(s_zeroOid, s_derNull);

            Pkcs12Builder builder = new Pkcs12Builder();

            builder.SealWithoutIntegrity();

            Assert.Throws <InvalidOperationException>(
                () => builder.AddSafeContentsUnencrypted(contents));

            Assert.Throws <InvalidOperationException>(
                () => builder.AddSafeContentsEncrypted(contents, Array.Empty <byte>(), s_pbkdf2Parameters));

            Assert.Throws <InvalidOperationException>(
                () => builder.AddSafeContentsEncrypted(contents, ReadOnlySpan <byte> .Empty, s_pbkdf2Parameters));

            Assert.Throws <InvalidOperationException>(
                () => builder.AddSafeContentsEncrypted(contents, string.Empty, s_pbkdf2Parameters));

            Assert.Throws <InvalidOperationException>(
                () => builder.AddSafeContentsEncrypted(contents, ReadOnlySpan <char> .Empty, s_pbkdf2Parameters));
        }
コード例 #3
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());
        }
コード例 #4
0
        public static void BuildWithEmptySafeContents(bool encrypted)
        {
            string pw = nameof(BuildWithEmptySafeContents);

            Pkcs12Builder      builder = new Pkcs12Builder();
            Pkcs12SafeContents empty   = new Pkcs12SafeContents();

            if (encrypted)
            {
                builder.AddSafeContentsEncrypted(empty, pw, s_win7Pbe);
            }
            else
            {
                builder.AddSafeContentsUnencrypted(empty);
            }

            builder.SealWithMac(pw, HashAlgorithmName.SHA1, 1);
            byte[] pfxBytes = builder.Encode();

            X509Certificate2Collection coll = new X509Certificate2Collection();

            coll.Import(pfxBytes, pw, default);

            Assert.Equal(0, coll.Count);
        }
コード例 #5
0
        public static void WriteOneCertNoKeys_Encrypted()
        {
            Pkcs12SafeContents contents = new Pkcs12SafeContents();

            byte[] rawData;

            using (X509Certificate2 cert = Certificates.RSAKeyTransferCapi1.GetCertificate())
            {
                contents.AddCertificate(cert);
                rawData = cert.RawData;
            }

            const string password = nameof(WriteOneCertNoKeys_NoEncryption);

            Pkcs12Builder builder = new Pkcs12Builder();

            builder.AddSafeContentsEncrypted(
                contents,
                password,
                s_win7Pbe);

            builder.SealWithMac(password, HashAlgorithmName.SHA1, 1024);
            byte[] pfx = builder.Encode();

            ImportedCollection coll =
                ImportedCollection.Import(pfx, password, X509KeyStorageFlags.EphemeralKeySet);

            using (coll)
            {
                Assert.Equal(1, coll.Collection.Count);
                Assert.Equal(rawData, coll.Collection[0].RawData);
                Assert.False(coll.Collection[0].HasPrivateKey, "coll.Collection[0].HasPrivateKey");
            }
        }
コード例 #6
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");
            }
        }
コード例 #7
0
        public static void EncryptPkcs12KdfWithBytes()
        {
            Pkcs12SafeContents contents = new Pkcs12SafeContents();

            contents.AddSecret(s_zeroOid, s_derNull);

            Pkcs12Builder builder = new Pkcs12Builder();

            Assert.ThrowsAny <CryptographicException>(
                () => builder.AddSafeContentsEncrypted(contents, s_derNull.Span, s_win7Pbe));
        }
コード例 #8
0
        public static void AddWithNullPbeParameters()
        {
            Pkcs12Builder      builder  = new Pkcs12Builder();
            Pkcs12SafeContents contents = new Pkcs12SafeContents();

            AssertExtensions.Throws <ArgumentNullException>(
                "pbeParameters",
                () => builder.AddSafeContentsEncrypted(contents, Array.Empty <byte>(), null));

            AssertExtensions.Throws <ArgumentNullException>(
                "pbeParameters",
                () => builder.AddSafeContentsEncrypted(contents, ReadOnlySpan <byte> .Empty, null));

            AssertExtensions.Throws <ArgumentNullException>(
                "pbeParameters",
                () => builder.AddSafeContentsEncrypted(contents, string.Empty, null));

            AssertExtensions.Throws <ArgumentNullException>(
                "pbeParameters",
                () => builder.AddSafeContentsEncrypted(contents, ReadOnlySpan <char> .Empty, null));
        }
コード例 #9
0
        public static void WriteOneCertWithKey_LikeWindows()
        {
            Pkcs12SafeContents safe1 = new Pkcs12SafeContents();
            Pkcs12SafeContents safe2 = new Pkcs12SafeContents();

            byte[] rawData;

            Pkcs9LocalKeyId localKeyId = new Pkcs9LocalKeyId(new byte[] { 1 });
            const string    password   = nameof(WriteOneCertWithKey_LikeWindows);

            using (X509Certificate2 cert = Certificates.RSAKeyTransferCapi1.TryGetCertificateWithPrivateKey(true))
            {
                Pkcs12CertBag certBag = safe1.AddCertificate(cert);
                certBag.Attributes.Add(localKeyId);

                rawData = cert.RawData;

                Pkcs12ShroudedKeyBag keyBag;

                using (RSA rsa = cert.GetRSAPrivateKey())
                {
                    keyBag = safe2.AddShroudedKey(
                        rsa,
                        password,
                        s_win7Pbe);
                }

                keyBag.Attributes.Add(localKeyId);
            }

            Pkcs12Builder builder = new Pkcs12Builder();

            builder.AddSafeContentsEncrypted(
                safe1,
                password,
                s_win7Pbe);

            builder.AddSafeContentsUnencrypted(safe2);

            builder.SealWithMac(password, HashAlgorithmName.SHA1, 2068);
            byte[] pfx = builder.Encode();

            ImportedCollection coll =
                ImportedCollection.Import(pfx, password, X509KeyStorageFlags.EphemeralKeySet);

            using (coll)
            {
                Assert.Equal(1, coll.Collection.Count);
                Assert.Equal(rawData, coll.Collection[0].RawData);
                Assert.True(coll.Collection[0].HasPrivateKey, "coll.Collection[0].HasPrivateKey");
            }
        }
コード例 #10
0
 private static void AddContents(
     Pkcs12SafeContents contents,
     Pkcs12Builder builder,
     string password,
     bool encrypt)
 {
     if (encrypt)
     {
         builder.AddSafeContentsEncrypted(contents, password, s_windowsPbe);
     }
     else
     {
         builder.AddSafeContentsUnencrypted(contents);
     }
 }
コード例 #11
0
        public static void AddNullContents()
        {
            Pkcs12Builder builder = new Pkcs12Builder();

            AssertExtensions.Throws <ArgumentNullException>(
                "safeContents",
                () => builder.AddSafeContentsUnencrypted(null));

            AssertExtensions.Throws <ArgumentNullException>(
                "safeContents",
                () => builder.AddSafeContentsEncrypted(null, Array.Empty <byte>(), s_pbkdf2Parameters));

            AssertExtensions.Throws <ArgumentNullException>(
                "safeContents",
                () => builder.AddSafeContentsEncrypted(null, ReadOnlySpan <byte> .Empty, s_pbkdf2Parameters));

            AssertExtensions.Throws <ArgumentNullException>(
                "safeContents",
                () => builder.AddSafeContentsEncrypted(null, string.Empty, s_pbkdf2Parameters));

            AssertExtensions.Throws <ArgumentNullException>(
                "safeContents",
                () => builder.AddSafeContentsEncrypted(null, ReadOnlySpan <char> .Empty, s_pbkdf2Parameters));
        }
コード例 #12
0
        public void OneCert_NoKeys_EncryptedEmptyPassword_NoMac()
        {
            using (X509Certificate2 cert = new X509Certificate2(TestData.MsCertificate))
            {
                Pkcs12Builder      builder      = new Pkcs12Builder();
                Pkcs12SafeContents certContents = new Pkcs12SafeContents();
                certContents.AddCertificate(cert);
                builder.AddSafeContentsEncrypted(certContents, string.Empty, s_windowsPbe);
                builder.SealWithoutIntegrity();
                byte[] pfxBytes = builder.Encode();

                ReadPfx(pfxBytes, null, cert);
                ReadPfx(pfxBytes, string.Empty, cert);
            }
        }
コード例 #13
0
        public void Setup()
        {
            _certPath = $"{PathName}/leaf.p12";

            using var wrongKey = RSA.Create();
            var builder      = new Pkcs12Builder();
            var safeContents = new Pkcs12SafeContents();
            var pbeParams    = new PbeParameters(PbeEncryptionAlgorithm.TripleDes3KeyPkcs12, HashAlgorithmName.SHA1, 2048);          // openssl defaults

            safeContents.AddCertificate(_leaf);
            safeContents.AddShroudedKey(wrongKey, Password, pbeParams);
            builder.AddSafeContentsEncrypted(safeContents, Password, pbeParams);
            builder.SealWithMac(Password, HashAlgorithmName.SHA1, 2048);             //openssl defaults

            File.WriteAllBytes(_certPath, builder.Encode());
        }
コード例 #14
0
        public void Setup()
        {
            _certPath = $"{PathName}/bundle.p12";

            using var rsa = RSA.Create();
            rsa.ImportRSAPrivateKey(_leaf.GetRSAPrivateKey() !.ExportRSAPrivateKey(), out _);
            var builder      = new Pkcs12Builder();
            var safeContents = new Pkcs12SafeContents();
            var pbeParams    = new PbeParameters(PbeEncryptionAlgorithm.TripleDes3KeyPkcs12, HashAlgorithmName.SHA1, 2048);          // openssl defaults

            safeContents.AddShroudedKey(rsa, Password, pbeParams);
            builder.AddSafeContentsEncrypted(safeContents, Password, pbeParams);
            builder.SealWithMac(Password, HashAlgorithmName.SHA1, 2048);             //openssl defaults

            File.WriteAllBytes(_certPath, builder.Encode());
        }
コード例 #15
0
        public void OneCert_MismatchedKey()
        {
            string pw = nameof(OneCert_MismatchedKey);

            // Build the PFX in the normal Windows style, except the private key doesn't match.
            using (var cert = new X509Certificate2(TestData.PfxData, TestData.PfxDataPassword, s_exportableImportFlags))
                using (RSA realKey = cert.GetRSAPrivateKey())
                    using (RSA key = RSA.Create(realKey.KeySize))
                    {
                        Pkcs12Builder      builder      = new Pkcs12Builder();
                        Pkcs12SafeContents keyContents  = new Pkcs12SafeContents();
                        Pkcs12SafeBag      keyBag       = keyContents.AddShroudedKey(key, pw, s_windowsPbe);
                        Pkcs12SafeContents certContents = new Pkcs12SafeContents();
                        Pkcs12SafeBag      certBag      = certContents.AddCertificate(cert);

                        keyBag.Attributes.Add(s_keyIdOne);
                        certBag.Attributes.Add(s_keyIdOne);

                        builder.AddSafeContentsUnencrypted(keyContents);
                        builder.AddSafeContentsEncrypted(certContents, pw, s_windowsPbe);
                        builder.SealWithoutIntegrity();
                        byte[] pfxBytes = builder.Encode();

                        // On macOS the cert will come back with HasPrivateKey being false.
                        if (OperatingSystem.IsMacOS())
                        {
                            using (var publicCert = new X509Certificate2(cert.RawData))
                            {
                                ReadPfx(
                                    pfxBytes,
                                    pw,
                                    publicCert);
                            }

                            return;
                        }

                        ReadPfx(
                            pfxBytes,
                            pw,
                            cert,
                            CheckKeyConsistencyFails);
                    }
        }
コード例 #16
0
        public static void WriteOneCertWithKey_Encrypted_SameSafe()
        {
            Pkcs12SafeContents contents = new Pkcs12SafeContents();

            byte[] rawData;

            Pkcs9LocalKeyId localKeyId = new Pkcs9LocalKeyId(new byte[] { 1 });

            using (X509Certificate2 cert = Certificates.RSAKeyTransferCapi1.TryGetCertificateWithPrivateKey(true))
                using (RSA certKey = cert.GetRSAPrivateKey())
                    using (RSA exportableKey = certKey.MakeExportable())
                    {
                        Pkcs12CertBag certBag = contents.AddCertificate(cert);
                        certBag.Attributes.Add(localKeyId);

                        rawData = cert.RawData;

                        Pkcs12KeyBag keyBag = contents.AddKeyUnencrypted(exportableKey);
                        keyBag.Attributes.Add(localKeyId);
                    }

            const string password = nameof(WriteOneCertWithKey_Encrypted_SameSafe);

            Pkcs12Builder builder = new Pkcs12Builder();

            builder.AddSafeContentsEncrypted(
                contents,
                password,
                s_win7Pbe);

            builder.SealWithMac(password, HashAlgorithmName.SHA1, 1024);
            byte[] pfx = builder.Encode();

            ImportedCollection coll =
                ImportedCollection.Import(pfx, password, X509KeyStorageFlags.EphemeralKeySet);

            using (coll)
            {
                Assert.Equal(1, coll.Collection.Count);
                Assert.Equal(rawData, coll.Collection[0].RawData);
                Assert.True(coll.Collection[0].HasPrivateKey, "coll.Collection[0].HasPrivateKey");
            }
        }
コード例 #17
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]));
        }
コード例 #18
0
        public void OneCert_TwoKeys_FirstWins(bool correctKeyFirst)
        {
            string pw = nameof(OneCert_TwoKeys_FirstWins);

            // Build the PFX in the normal Windows style, except the private key doesn't match.
            using (var cert = new X509Certificate2(TestData.PfxData, TestData.PfxDataPassword, s_exportableImportFlags))
                using (RSA key = cert.GetRSAPrivateKey())
                    using (RSA unrelated = RSA.Create(key.KeySize))
                    {
                        Pkcs12Builder      builder      = new Pkcs12Builder();
                        Pkcs12SafeContents keyContents  = new Pkcs12SafeContents();
                        Pkcs12SafeContents certContents = new Pkcs12SafeContents();
                        Pkcs12SafeBag      keyBag;
                        Pkcs12SafeBag      keyBag2;
                        Pkcs12SafeBag      certBag = certContents.AddCertificate(cert);

                        if (correctKeyFirst)
                        {
                            keyBag  = keyContents.AddShroudedKey(key, pw, s_windowsPbe);
                            keyBag2 = keyContents.AddShroudedKey(unrelated, pw, s_windowsPbe);
                        }
                        else
                        {
                            keyBag  = keyContents.AddShroudedKey(unrelated, pw, s_windowsPbe);
                            keyBag2 = keyContents.AddShroudedKey(key, pw, s_windowsPbe);
                        }

                        keyBag.Attributes.Add(s_keyIdOne);
                        keyBag2.Attributes.Add(s_keyIdOne);
                        certBag.Attributes.Add(s_keyIdOne);

                        builder.AddSafeContentsUnencrypted(keyContents);
                        builder.AddSafeContentsEncrypted(certContents, pw, s_windowsPbe);
                        builder.SealWithoutIntegrity();
                        byte[] pfxBytes = builder.Encode();

                        // On macOS the cert will come back with HasPrivateKey being false when the
                        // incorrect key comes first
                        if (!correctKeyFirst && OperatingSystem.IsMacOS())
                        {
                            using (var publicCert = new X509Certificate2(cert.RawData))
                            {
                                ReadPfx(
                                    pfxBytes,
                                    pw,
                                    publicCert);
                            }

                            return;
                        }

                        // The RSA "self-test" should pass when the correct key is first,
                        // and fail when the unrelated key is first.
                        Action <X509Certificate2> followup = CheckKeyConsistency;

                        if (!correctKeyFirst)
                        {
                            followup = CheckKeyConsistencyFails;
                        }

                        ReadPfx(
                            pfxBytes,
                            pw,
                            cert,
                            followup);
                    }
        }
コード例 #19
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());
        }