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)); }
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)); }
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()); }
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); }
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"); } }
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"); } }
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)); }
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)); }
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"); } }
private static void AddContents( Pkcs12SafeContents contents, Pkcs12Builder builder, string password, bool encrypt) { if (encrypt) { builder.AddSafeContentsEncrypted(contents, password, s_windowsPbe); } else { builder.AddSafeContentsUnencrypted(contents); } }
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)); }
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); } }
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()); }
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()); }
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); } }
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"); } }
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])); }
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); } }
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()); }