mirror of
https://github.com/VSadov/Satori.git
synced 2025-06-10 18:11:04 +09:00
Enable importing PEM-formatted keys into AsymmetricAlgorithm values
This commit is contained in:
parent
755b548206
commit
29df078d1b
22 changed files with 2491 additions and 3 deletions
|
@ -18,6 +18,7 @@
|
|||
"/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/EC/ECKeyFileTests.cs",
|
||||
"/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/EC/ECKeyFileTests.LimitedPrivate.cs",
|
||||
"/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSAKeyFileTests.cs",
|
||||
"/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSAKeyPemTests.cs",
|
||||
"/src/libraries/System.Data.Common/tests/System/Data/Common/DbConnectionStringBuilderTest.cs",
|
||||
"/src/libraries/System.Diagnostics.Process/tests/ProcessStartInfoTests.cs",
|
||||
"/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/constants.cs",
|
||||
|
|
|
@ -0,0 +1,170 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
#nullable enable
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace Internal.Cryptography
|
||||
{
|
||||
internal static class PemKeyImportHelpers
|
||||
{
|
||||
public delegate void ImportKeyAction(ReadOnlySpan<byte> source, out int bytesRead);
|
||||
public delegate ImportKeyAction? FindImportActionFunc(ReadOnlySpan<char> label);
|
||||
public delegate void ImportEncryptedKeyAction<TPass>(
|
||||
ReadOnlySpan<TPass> password,
|
||||
ReadOnlySpan<byte> source,
|
||||
out int bytesRead);
|
||||
|
||||
public static void ImportEncryptedPem<TPass>(
|
||||
ReadOnlySpan<char> input,
|
||||
ReadOnlySpan<TPass> password,
|
||||
ImportEncryptedKeyAction<TPass> importAction)
|
||||
{
|
||||
bool foundEncryptedPem = false;
|
||||
PemFields foundFields = default;
|
||||
ReadOnlySpan<char> foundSlice = default;
|
||||
|
||||
ReadOnlySpan<char> pem = input;
|
||||
while (PemEncoding.TryFind(pem, out PemFields fields))
|
||||
{
|
||||
ReadOnlySpan<char> label = pem[fields.Label];
|
||||
|
||||
if (label.SequenceEqual(PemLabels.EncryptedPkcs8PrivateKey))
|
||||
{
|
||||
if (foundEncryptedPem)
|
||||
{
|
||||
throw new ArgumentException(SR.Argument_PemImport_AmbiguousPem, nameof(input));
|
||||
}
|
||||
|
||||
foundEncryptedPem = true;
|
||||
foundFields = fields;
|
||||
foundSlice = pem;
|
||||
}
|
||||
|
||||
Index offset = fields.Location.End;
|
||||
pem = pem[offset..];
|
||||
}
|
||||
|
||||
if (!foundEncryptedPem)
|
||||
{
|
||||
throw new ArgumentException(SR.Argument_PemImport_NoPemFound, nameof(input));
|
||||
}
|
||||
|
||||
ReadOnlySpan<char> base64Contents = foundSlice[foundFields.Base64Data];
|
||||
int base64size = foundFields.DecodedDataLength;
|
||||
byte[] decodeBuffer = CryptoPool.Rent(base64size);
|
||||
int bytesWritten = 0;
|
||||
|
||||
try
|
||||
{
|
||||
if (!Convert.TryFromBase64Chars(base64Contents, decodeBuffer, out bytesWritten))
|
||||
{
|
||||
// Couldn't decode base64. We shouldn't get here since the
|
||||
// contents are pre-validated.
|
||||
Debug.Fail("Base64 decoding failed on already validated contents.");
|
||||
throw new ArgumentException();
|
||||
}
|
||||
|
||||
Debug.Assert(bytesWritten == base64size);
|
||||
Span<byte> decodedBase64 = decodeBuffer.AsSpan(0, bytesWritten);
|
||||
|
||||
// Don't need to check the bytesRead here. We're already operating
|
||||
// on an input which is already a parsed subset of the input.
|
||||
importAction(password, decodedBase64, out _);
|
||||
}
|
||||
finally
|
||||
{
|
||||
CryptoPool.Return(decodeBuffer, clearSize: bytesWritten);
|
||||
}
|
||||
}
|
||||
|
||||
public static void ImportPem(ReadOnlySpan<char> input, FindImportActionFunc callback)
|
||||
{
|
||||
ImportKeyAction? importAction = null;
|
||||
PemFields foundFields = default;
|
||||
ReadOnlySpan<char> foundSlice = default;
|
||||
bool containsEncryptedPem = false;
|
||||
|
||||
ReadOnlySpan<char> pem = input;
|
||||
while (PemEncoding.TryFind(pem, out PemFields fields))
|
||||
{
|
||||
ReadOnlySpan<char> label = pem[fields.Label];
|
||||
ImportKeyAction? action = callback(label);
|
||||
|
||||
// Caller knows how to handle this PEM by label.
|
||||
if (action != null)
|
||||
{
|
||||
// There was a previous PEM that could have been handled,
|
||||
// which means this is ambiguous and contains multiple
|
||||
// importable keys. Or, this contained an encrypted PEM.
|
||||
// For purposes of encrypted PKCS8 with another actionable
|
||||
// PEM, we will throw a duplicate exception.
|
||||
if (importAction != null || containsEncryptedPem)
|
||||
{
|
||||
throw new ArgumentException(SR.Argument_PemImport_AmbiguousPem, nameof(input));
|
||||
}
|
||||
|
||||
importAction = action;
|
||||
foundFields = fields;
|
||||
foundSlice = pem;
|
||||
}
|
||||
else if (label.SequenceEqual(PemLabels.EncryptedPkcs8PrivateKey))
|
||||
{
|
||||
if (importAction != null || containsEncryptedPem)
|
||||
{
|
||||
throw new ArgumentException(SR.Argument_PemImport_AmbiguousPem, nameof(input));
|
||||
}
|
||||
|
||||
containsEncryptedPem = true;
|
||||
}
|
||||
|
||||
Index offset = fields.Location.End;
|
||||
pem = pem[offset..];
|
||||
}
|
||||
|
||||
// The only PEM found that could potentially be used is encrypted PKCS8,
|
||||
// but we won't try to import it with a null or blank password, so
|
||||
// throw.
|
||||
if (containsEncryptedPem)
|
||||
{
|
||||
throw new ArgumentException(SR.Argument_PemImport_EncryptedPem, nameof(input));
|
||||
}
|
||||
|
||||
// We went through the PEM and found nothing that could be handled.
|
||||
if (importAction is null)
|
||||
{
|
||||
throw new ArgumentException(SR.Argument_PemImport_NoPemFound, nameof(input));
|
||||
}
|
||||
|
||||
ReadOnlySpan<char> base64Contents = foundSlice[foundFields.Base64Data];
|
||||
int base64size = foundFields.DecodedDataLength;
|
||||
byte[] decodeBuffer = CryptoPool.Rent(base64size);
|
||||
int bytesWritten = 0;
|
||||
|
||||
try
|
||||
{
|
||||
if (!Convert.TryFromBase64Chars(base64Contents, decodeBuffer, out bytesWritten))
|
||||
{
|
||||
// Couldn't decode base64. We shouldn't get here since the
|
||||
// contents are pre-validated.
|
||||
Debug.Fail("Base64 decoding failed on already validated contents.");
|
||||
throw new ArgumentException();
|
||||
}
|
||||
|
||||
Debug.Assert(bytesWritten == base64size);
|
||||
Span<byte> decodedBase64 = decodeBuffer.AsSpan(0, bytesWritten);
|
||||
|
||||
// Don't need to check the bytesRead here. We're already operating
|
||||
// on an input which is already a parsed subset of the input.
|
||||
importAction(decodedBase64, out _);
|
||||
}
|
||||
finally
|
||||
{
|
||||
CryptoPool.Return(decodeBuffer, clearSize: bytesWritten);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace System.Security.Cryptography
|
||||
{
|
||||
internal static class PemLabels
|
||||
{
|
||||
internal const string Pkcs8PrivateKey = "PRIVATE KEY";
|
||||
internal const string EncryptedPkcs8PrivateKey = "ENCRYPTED PRIVATE KEY";
|
||||
internal const string SpkiPublicKey = "PUBLIC KEY";
|
||||
internal const string RsaPublicKey = "RSA PUBLIC KEY";
|
||||
internal const string RsaPrivateKey = "RSA PRIVATE KEY";
|
||||
internal const string EcPrivateKey = "EC PRIVATE KEY";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,379 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Text;
|
||||
using Test.Cryptography;
|
||||
using Xunit;
|
||||
|
||||
namespace System.Security.Cryptography.Dsa.Tests
|
||||
{
|
||||
public static class DSAKeyPemTests
|
||||
{
|
||||
private const string AmbiguousExceptionMarker = "multiple keys";
|
||||
private const string EncryptedExceptionMarker = "encrypted key";
|
||||
private const string NoPemExceptionMarker = "No supported key";
|
||||
|
||||
[Fact]
|
||||
public static void ImportFromPem_NoPem()
|
||||
{
|
||||
using (DSA dsa = DSAFactory.Create())
|
||||
{
|
||||
string pem = "pem? what pem? there is no pem here.";
|
||||
ArgumentException ae = AssertExtensions.Throws<ArgumentException>("input", () => dsa.ImportFromPem(pem));
|
||||
Assert.Contains(NoPemExceptionMarker, ae.Message);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void ImportFromPem_Pkcs8UnEncrypted_Simple()
|
||||
{
|
||||
using (DSA dsa = DSAFactory.Create())
|
||||
{
|
||||
string pem = @"
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIHGAgEAMIGoBgcqhkjOOAQBMIGcAkEA1qi38cr3ppZNB2Y/xpHSL2q81Vw3rvWN
|
||||
IHRnQNgv4U4UY2NifZGSUULc3uOEvgoeBO1b9fRxSG9NmG1CoufflQIVAPq19iXV
|
||||
1eFkMKHvYw6+M4l8wiT5AkAIRMSQ5S71jgWQLGNtZNHV6yxggqDU87/RzgeOh7Q6
|
||||
fve77OGaTv4qbZwinTYAg86p9yHzmwW6+XBS3vxnpYorBBYCFC49eoTIW2Z4Xh9v
|
||||
55aYKyKwy5i8
|
||||
-----END PRIVATE KEY-----";
|
||||
dsa.ImportFromPem(pem);
|
||||
DSAParameters dsaParameters = dsa.ExportParameters(true);
|
||||
|
||||
DSAImportExport.AssertKeyEquals(DSATestData.Dsa512Parameters, dsaParameters);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void ImportFromPem_Pkcs8UnEncrypted_IgnoresUnrelatedAlgorithm()
|
||||
{
|
||||
using (DSA dsa = DSAFactory.Create())
|
||||
{
|
||||
string pem = @"
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIHChLC2xaEXtVv9oz8IaRys/BNfWhRv2NJ8tfVs0UrOKoAoGCCqGSM49
|
||||
AwEHoUQDQgAEgQHs5HRkpurXDPaabivT2IaRoyYtIsuk92Ner/JmgKjYoSumHVmS
|
||||
NfZ9nLTVjxeD08pD548KWrqmJAeZNsDDqQ==
|
||||
-----END EC PRIVATE KEY-----
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIHGAgEAMIGoBgcqhkjOOAQBMIGcAkEA1qi38cr3ppZNB2Y/xpHSL2q81Vw3rvWN
|
||||
IHRnQNgv4U4UY2NifZGSUULc3uOEvgoeBO1b9fRxSG9NmG1CoufflQIVAPq19iXV
|
||||
1eFkMKHvYw6+M4l8wiT5AkAIRMSQ5S71jgWQLGNtZNHV6yxggqDU87/RzgeOh7Q6
|
||||
fve77OGaTv4qbZwinTYAg86p9yHzmwW6+XBS3vxnpYorBBYCFC49eoTIW2Z4Xh9v
|
||||
55aYKyKwy5i8
|
||||
-----END PRIVATE KEY-----";
|
||||
dsa.ImportFromPem(pem);
|
||||
DSAParameters dsaParameters = dsa.ExportParameters(true);
|
||||
|
||||
DSAImportExport.AssertKeyEquals(DSATestData.Dsa512Parameters, dsaParameters);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void ImportFromPem_Pkcs8_UnrelatedPrecedingPem()
|
||||
{
|
||||
using (DSA dsa = DSAFactory.Create())
|
||||
{
|
||||
string pem = @"
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MII=
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIHGAgEAMIGoBgcqhkjOOAQBMIGcAkEA1qi38cr3ppZNB2Y/xpHSL2q81Vw3rvWN
|
||||
IHRnQNgv4U4UY2NifZGSUULc3uOEvgoeBO1b9fRxSG9NmG1CoufflQIVAPq19iXV
|
||||
1eFkMKHvYw6+M4l8wiT5AkAIRMSQ5S71jgWQLGNtZNHV6yxggqDU87/RzgeOh7Q6
|
||||
fve77OGaTv4qbZwinTYAg86p9yHzmwW6+XBS3vxnpYorBBYCFC49eoTIW2Z4Xh9v
|
||||
55aYKyKwy5i8
|
||||
-----END PRIVATE KEY-----";
|
||||
dsa.ImportFromPem(pem);
|
||||
DSAParameters dsaParameters = dsa.ExportParameters(true);
|
||||
|
||||
DSAImportExport.AssertKeyEquals(DSATestData.Dsa512Parameters, dsaParameters);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void ImportFromPem_Pkcs8_PrecedingMalformedPem()
|
||||
{
|
||||
using (DSA dsa = DSAFactory.Create())
|
||||
{
|
||||
string pem = @"
|
||||
-----BEGIN CERTIFICATE-----
|
||||
$$$ BAD PEM
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIHGAgEAMIGoBgcqhkjOOAQBMIGcAkEA1qi38cr3ppZNB2Y/xpHSL2q81Vw3rvWN
|
||||
IHRnQNgv4U4UY2NifZGSUULc3uOEvgoeBO1b9fRxSG9NmG1CoufflQIVAPq19iXV
|
||||
1eFkMKHvYw6+M4l8wiT5AkAIRMSQ5S71jgWQLGNtZNHV6yxggqDU87/RzgeOh7Q6
|
||||
fve77OGaTv4qbZwinTYAg86p9yHzmwW6+XBS3vxnpYorBBYCFC49eoTIW2Z4Xh9v
|
||||
55aYKyKwy5i8
|
||||
-----END PRIVATE KEY-----";
|
||||
dsa.ImportFromPem(pem);
|
||||
DSAParameters dsaParameters = dsa.ExportParameters(true);
|
||||
|
||||
DSAImportExport.AssertKeyEquals(DSATestData.Dsa512Parameters, dsaParameters);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void ImportFromPem_SubjectPublicKeyInfo_Simple()
|
||||
{
|
||||
using (DSA dsa = DSAFactory.Create())
|
||||
{
|
||||
string pem = @"
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIHxMIGoBgcqhkjOOAQBMIGcAkEA1qi38cr3ppZNB2Y/xpHSL2q81Vw3rvWNIHRn
|
||||
QNgv4U4UY2NifZGSUULc3uOEvgoeBO1b9fRxSG9NmG1CoufflQIVAPq19iXV1eFk
|
||||
MKHvYw6+M4l8wiT5AkAIRMSQ5S71jgWQLGNtZNHV6yxggqDU87/RzgeOh7Q6fve7
|
||||
7OGaTv4qbZwinTYAg86p9yHzmwW6+XBS3vxnpYorA0QAAkEAwwDg5n2HfmztOf7q
|
||||
qsHywr1WjmoyRnIn4Stq5FqNlHhUGkgKyAA4qshjgn1uOYQGGiWQXBi9JJmoOWY8
|
||||
PKRWBQ==
|
||||
-----END PUBLIC KEY-----";
|
||||
dsa.ImportFromPem(pem);
|
||||
DSAParameters dsaParameters = dsa.ExportParameters(false);
|
||||
|
||||
DSAImportExport.AssertKeyEquals(DSATestData.Dsa512Parameters.ToPublic(), dsaParameters);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void ImportFromPem_Pkcs8_AmbiguousKey_Pkcs8()
|
||||
{
|
||||
using (DSA dsa = DSAFactory.Create())
|
||||
{
|
||||
string pem = @"
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIHGAgEAMIGoBgcqhkjOOAQBMIGcAkEA1qi38cr3ppZNB2Y/xpHSL2q81Vw3rvWN
|
||||
IHRnQNgv4U4UY2NifZGSUULc3uOEvgoeBO1b9fRxSG9NmG1CoufflQIVAPq19iXV
|
||||
1eFkMKHvYw6+M4l8wiT5AkAIRMSQ5S71jgWQLGNtZNHV6yxggqDU87/RzgeOh7Q6
|
||||
fve77OGaTv4qbZwinTYAg86p9yHzmwW6+XBS3vxnpYorBBYCFC49eoTIW2Z4Xh9v
|
||||
55aYKyKwy5i8
|
||||
-----END PRIVATE KEY-----
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIHGAgEAMIGoBgcqhkjOOAQBMIGcAkEA1qi38cr3ppZNB2Y/xpHSL2q81Vw3rvWN
|
||||
IHRnQNgv4U4UY2NifZGSUULc3uOEvgoeBO1b9fRxSG9NmG1CoufflQIVAPq19iXV
|
||||
1eFkMKHvYw6+M4l8wiT5AkAIRMSQ5S71jgWQLGNtZNHV6yxggqDU87/RzgeOh7Q6
|
||||
fve77OGaTv4qbZwinTYAg86p9yHzmwW6+XBS3vxnpYorBBYCFC49eoTIW2Z4Xh9v
|
||||
55aYKyKwy5i8
|
||||
-----END PRIVATE KEY-----";
|
||||
ArgumentException ae = AssertExtensions.Throws<ArgumentException>("input", () => dsa.ImportFromPem(pem));
|
||||
Assert.Contains(AmbiguousExceptionMarker, ae.Message);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void ImportFromPem_Pkcs8_AmbiguousKey_Spki()
|
||||
{
|
||||
using (DSA dsa = DSAFactory.Create())
|
||||
{
|
||||
string pem = @"
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIHxMIGoBgcqhkjOOAQBMIGcAkEA1qi38cr3ppZNB2Y/xpHSL2q81Vw3rvWNIHRn
|
||||
QNgv4U4UY2NifZGSUULc3uOEvgoeBO1b9fRxSG9NmG1CoufflQIVAPq19iXV1eFk
|
||||
MKHvYw6+M4l8wiT5AkAIRMSQ5S71jgWQLGNtZNHV6yxggqDU87/RzgeOh7Q6fve7
|
||||
7OGaTv4qbZwinTYAg86p9yHzmwW6+XBS3vxnpYorA0QAAkEAwwDg5n2HfmztOf7q
|
||||
qsHywr1WjmoyRnIn4Stq5FqNlHhUGkgKyAA4qshjgn1uOYQGGiWQXBi9JJmoOWY8
|
||||
PKRWBQ==
|
||||
-----END PUBLIC KEY-----
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIHGAgEAMIGoBgcqhkjOOAQBMIGcAkEA1qi38cr3ppZNB2Y/xpHSL2q81Vw3rvWN
|
||||
IHRnQNgv4U4UY2NifZGSUULc3uOEvgoeBO1b9fRxSG9NmG1CoufflQIVAPq19iXV
|
||||
1eFkMKHvYw6+M4l8wiT5AkAIRMSQ5S71jgWQLGNtZNHV6yxggqDU87/RzgeOh7Q6
|
||||
fve77OGaTv4qbZwinTYAg86p9yHzmwW6+XBS3vxnpYorBBYCFC49eoTIW2Z4Xh9v
|
||||
55aYKyKwy5i8
|
||||
-----END PRIVATE KEY-----";
|
||||
ArgumentException ae = AssertExtensions.Throws<ArgumentException>("input", () => dsa.ImportFromPem(pem));
|
||||
Assert.Contains(AmbiguousExceptionMarker, ae.Message);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void ImportFromPem_Pkcs8_AmbiguousKey_EncryptedPkcs8()
|
||||
{
|
||||
using (DSA dsa = DSAFactory.Create())
|
||||
{
|
||||
string pem = @"
|
||||
-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||
MIIBIDBLBgkqhkiG9w0BBQ0wPjApBgkqhkiG9w0BBQwwHAQIkM/kCKe6rYsCAggA
|
||||
MAwGCCqGSIb3DQIJBQAwEQYFKw4DAgcECBOccveL65bDBIHQiCcCqwxJs93g1+16
|
||||
7Gx1D5lL4/nZ94fRa+Hl4nGEX4gmjuxH6pOHKyywwflAyXNTfVhOCP9zBedwENx9
|
||||
MGHbpaaShD6iJfoGMRX0frr0mMCtuOOZkkjBF9pSpkhaH0TDSq1PrVLxcM0/S4Vs
|
||||
+//2uPrP8U+CTW9W7CXCZw698BAuevZRuD0koT2Bn9ErhTiuVZZMcOjtLmN2oXHG
|
||||
dVYwfovccu8ktEAwk5XAOo0r+5CCw2lDDw/hbDeO87BToC5Cc5nu3F5LxAUj8Flc
|
||||
v8pi3w==
|
||||
-----END ENCRYPTED PRIVATE KEY-----
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIHGAgEAMIGoBgcqhkjOOAQBMIGcAkEA1qi38cr3ppZNB2Y/xpHSL2q81Vw3rvWN
|
||||
IHRnQNgv4U4UY2NifZGSUULc3uOEvgoeBO1b9fRxSG9NmG1CoufflQIVAPq19iXV
|
||||
1eFkMKHvYw6+M4l8wiT5AkAIRMSQ5S71jgWQLGNtZNHV6yxggqDU87/RzgeOh7Q6
|
||||
fve77OGaTv4qbZwinTYAg86p9yHzmwW6+XBS3vxnpYorBBYCFC49eoTIW2Z4Xh9v
|
||||
55aYKyKwy5i8
|
||||
-----END PRIVATE KEY-----";
|
||||
ArgumentException ae = AssertExtensions.Throws<ArgumentException>("input", () => dsa.ImportFromPem(pem));
|
||||
Assert.Contains(AmbiguousExceptionMarker, ae.Message);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void ImportFromPem_EncryptedPrivateKeyFails()
|
||||
{
|
||||
using (DSA dsa = DSAFactory.Create())
|
||||
{
|
||||
string pem = @"
|
||||
-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||
MIIBIDBLBgkqhkiG9w0BBQ0wPjApBgkqhkiG9w0BBQwwHAQIkM/kCKe6rYsCAggA
|
||||
MAwGCCqGSIb3DQIJBQAwEQYFKw4DAgcECBOccveL65bDBIHQiCcCqwxJs93g1+16
|
||||
7Gx1D5lL4/nZ94fRa+Hl4nGEX4gmjuxH6pOHKyywwflAyXNTfVhOCP9zBedwENx9
|
||||
MGHbpaaShD6iJfoGMRX0frr0mMCtuOOZkkjBF9pSpkhaH0TDSq1PrVLxcM0/S4Vs
|
||||
+//2uPrP8U+CTW9W7CXCZw698BAuevZRuD0koT2Bn9ErhTiuVZZMcOjtLmN2oXHG
|
||||
dVYwfovccu8ktEAwk5XAOo0r+5CCw2lDDw/hbDeO87BToC5Cc5nu3F5LxAUj8Flc
|
||||
v8pi3w==
|
||||
-----END ENCRYPTED PRIVATE KEY-----";
|
||||
ArgumentException ae = AssertExtensions.Throws<ArgumentException>("input", () => dsa.ImportFromPem(pem));
|
||||
Assert.Contains(EncryptedExceptionMarker, ae.Message);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void ImportFromPem_SpkiAlgorithmMismatch_Throws()
|
||||
{
|
||||
using (DSA dsa = DSAFactory.Create())
|
||||
{
|
||||
string pem = @"
|
||||
The below key is for an RSA SPKI
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALc/WfXui9VeJLf/AprRaoVDyW0lPlQx
|
||||
m5NTLEHDwUd7idstLzPXuah0WEjgao5oO1BEUR4byjYlJ+F89Cs4BhUCAwEAAQ==
|
||||
-----END PUBLIC KEY-----";
|
||||
Assert.Throws<CryptographicException>(() => dsa.ImportFromPem(pem));
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void ImportFromEncryptedPem_Pkcs8_Encrypted_Char_Simple()
|
||||
{
|
||||
using (DSA dsa = DSAFactory.Create())
|
||||
{
|
||||
string pem = @"
|
||||
-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||
MIIBIDBLBgkqhkiG9w0BBQ0wPjApBgkqhkiG9w0BBQwwHAQIkM/kCKe6rYsCAggA
|
||||
MAwGCCqGSIb3DQIJBQAwEQYFKw4DAgcECBOccveL65bDBIHQiCcCqwxJs93g1+16
|
||||
7Gx1D5lL4/nZ94fRa+Hl4nGEX4gmjuxH6pOHKyywwflAyXNTfVhOCP9zBedwENx9
|
||||
MGHbpaaShD6iJfoGMRX0frr0mMCtuOOZkkjBF9pSpkhaH0TDSq1PrVLxcM0/S4Vs
|
||||
+//2uPrP8U+CTW9W7CXCZw698BAuevZRuD0koT2Bn9ErhTiuVZZMcOjtLmN2oXHG
|
||||
dVYwfovccu8ktEAwk5XAOo0r+5CCw2lDDw/hbDeO87BToC5Cc5nu3F5LxAUj8Flc
|
||||
v8pi3w==
|
||||
-----END ENCRYPTED PRIVATE KEY-----";
|
||||
dsa.ImportFromEncryptedPem(pem, "test");
|
||||
DSAParameters dsaParameters = dsa.ExportParameters(true);
|
||||
|
||||
DSAImportExport.AssertKeyEquals(DSATestData.Dsa512Parameters, dsaParameters);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void ImportFromEncryptedPem_Pkcs8_Encrypted_Byte_Simple()
|
||||
{
|
||||
using (DSA dsa = DSAFactory.Create())
|
||||
{
|
||||
string pem = @"
|
||||
-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||
MIIBLDBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQIfcoipdEY/C4CAggA
|
||||
MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAECBBC9heEphj00fB89aP6chSOjBIHQ
|
||||
HF2RLrIw6654q2hjUdCG4PhhYNXlck0zD0mOuaVQHmnKIKArk/1DSpgSrYnKw6aE
|
||||
2eujwNdySLLEwUj5l+X/IXwhOnPIZDJqUN7oMagUYJX28gnQmXyDvrt3r16utbpd
|
||||
ho0YNYGUDSgOs6RxBpw1rJUCnAlHNU09peCjEP+aZSrhsxlejN/GpVS4e0JTmMeo
|
||||
xTL6VO9mx52x6h5WDAQAisMVeMkBoxQUWLANXiw1zSfVbsmB7mDknsRcvD3tcgMs
|
||||
7YLD7LQMiPAIjDlOP8XP/w==
|
||||
-----END ENCRYPTED PRIVATE KEY-----";
|
||||
byte[] passwordBytes = Encoding.UTF8.GetBytes("test");
|
||||
dsa.ImportFromEncryptedPem(pem, passwordBytes);
|
||||
DSAParameters dsaParameters = dsa.ExportParameters(true);
|
||||
|
||||
DSAImportExport.AssertKeyEquals(DSATestData.Dsa512Parameters, dsaParameters);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void ImportFromEncryptedPem_Pkcs8_Encrypted_AmbiguousPem()
|
||||
{
|
||||
using (DSA dsa = DSAFactory.Create())
|
||||
{
|
||||
string pem = @"
|
||||
-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||
MIIBLDBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQIfcoipdEY/C4CAggA
|
||||
MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAECBBC9heEphj00fB89aP6chSOjBIHQ
|
||||
HF2RLrIw6654q2hjUdCG4PhhYNXlck0zD0mOuaVQHmnKIKArk/1DSpgSrYnKw6aE
|
||||
2eujwNdySLLEwUj5l+X/IXwhOnPIZDJqUN7oMagUYJX28gnQmXyDvrt3r16utbpd
|
||||
ho0YNYGUDSgOs6RxBpw1rJUCnAlHNU09peCjEP+aZSrhsxlejN/GpVS4e0JTmMeo
|
||||
xTL6VO9mx52x6h5WDAQAisMVeMkBoxQUWLANXiw1zSfVbsmB7mDknsRcvD3tcgMs
|
||||
7YLD7LQMiPAIjDlOP8XP/w==
|
||||
-----END ENCRYPTED PRIVATE KEY-----
|
||||
-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||
MIIBIDBLBgkqhkiG9w0BBQ0wPjApBgkqhkiG9w0BBQwwHAQIkM/kCKe6rYsCAggA
|
||||
MAwGCCqGSIb3DQIJBQAwEQYFKw4DAgcECBOccveL65bDBIHQiCcCqwxJs93g1+16
|
||||
7Gx1D5lL4/nZ94fRa+Hl4nGEX4gmjuxH6pOHKyywwflAyXNTfVhOCP9zBedwENx9
|
||||
MGHbpaaShD6iJfoGMRX0frr0mMCtuOOZkkjBF9pSpkhaH0TDSq1PrVLxcM0/S4Vs
|
||||
+//2uPrP8U+CTW9W7CXCZw698BAuevZRuD0koT2Bn9ErhTiuVZZMcOjtLmN2oXHG
|
||||
dVYwfovccu8ktEAwk5XAOo0r+5CCw2lDDw/hbDeO87BToC5Cc5nu3F5LxAUj8Flc
|
||||
v8pi3w==
|
||||
-----END ENCRYPTED PRIVATE KEY-----";
|
||||
byte[] passwordBytes = Encoding.UTF8.GetBytes("test");
|
||||
ArgumentException ae = AssertExtensions.Throws<ArgumentException>("input", () =>
|
||||
dsa.ImportFromEncryptedPem(pem, passwordBytes));
|
||||
Assert.Contains(AmbiguousExceptionMarker, ae.Message);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void ImportFromEncryptedPem_Pkcs8_Byte_NoPem()
|
||||
{
|
||||
using (DSA dsa = DSAFactory.Create())
|
||||
{
|
||||
string pem = "";
|
||||
byte[] passwordBytes = Encoding.UTF8.GetBytes("test");
|
||||
ArgumentException ae = AssertExtensions.Throws<ArgumentException>("input", () =>
|
||||
dsa.ImportFromEncryptedPem(pem, passwordBytes));
|
||||
Assert.Contains(NoPemExceptionMarker, ae.Message);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void ImportFromEncryptedPem_Pkcs8_Char_NoPem()
|
||||
{
|
||||
using (DSA dsa = DSAFactory.Create())
|
||||
{
|
||||
string pem = "";
|
||||
ArgumentException ae = AssertExtensions.Throws<ArgumentException>("input", () =>
|
||||
dsa.ImportFromEncryptedPem(pem, ""));
|
||||
Assert.Contains(NoPemExceptionMarker, ae.Message);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void ImportFromEncryptedPem_Pkcs8_NoEncryptedPem()
|
||||
{
|
||||
using (DSA dsa = DSAFactory.Create())
|
||||
{
|
||||
string pem = @"
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIHGAgEAMIGoBgcqhkjOOAQBMIGcAkEA1qi38cr3ppZNB2Y/xpHSL2q81Vw3rvWN
|
||||
IHRnQNgv4U4UY2NifZGSUULc3uOEvgoeBO1b9fRxSG9NmG1CoufflQIVAPq19iXV
|
||||
1eFkMKHvYw6+M4l8wiT5AkAIRMSQ5S71jgWQLGNtZNHV6yxggqDU87/RzgeOh7Q6
|
||||
fve77OGaTv4qbZwinTYAg86p9yHzmwW6+XBS3vxnpYorBBYCFC49eoTIW2Z4Xh9v
|
||||
55aYKyKwy5i8
|
||||
-----END PRIVATE KEY-----";
|
||||
ArgumentException ae = AssertExtensions.Throws<ArgumentException>("input", () =>
|
||||
dsa.ImportFromEncryptedPem(pem, ""));
|
||||
Assert.Contains(NoPemExceptionMarker, ae.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private static DSAParameters ToPublic(this DSAParameters dsaParams)
|
||||
{
|
||||
dsaParams.X = null;
|
||||
return dsaParams;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,438 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Text;
|
||||
using Test.Cryptography;
|
||||
using Xunit;
|
||||
|
||||
namespace System.Security.Cryptography.Tests
|
||||
{
|
||||
public abstract class ECKeyPemTests<TAlg> where TAlg : AsymmetricAlgorithm
|
||||
{
|
||||
private const string AmbiguousExceptionMarker = "multiple keys";
|
||||
private const string EncryptedExceptionMarker = "encrypted key";
|
||||
private const string NoPemExceptionMarker = "No supported key";
|
||||
|
||||
protected abstract TAlg CreateKey();
|
||||
protected abstract ECParameters ExportParameters(TAlg key, bool includePrivateParameters);
|
||||
|
||||
[Fact]
|
||||
public void ImportFromPem_NoPem()
|
||||
{
|
||||
using (TAlg key = CreateKey())
|
||||
{
|
||||
ArgumentException ae = AssertExtensions.Throws<ArgumentException>("input", () => key.ImportFromPem(""));
|
||||
Assert.Contains(NoPemExceptionMarker, ae.Message);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ImportFromPem_ECPrivateKey_Simple()
|
||||
{
|
||||
using (TAlg key = CreateKey())
|
||||
{
|
||||
key.ImportFromPem(@"
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIHChLC2xaEXtVv9oz8IaRys/BNfWhRv2NJ8tfVs0UrOKoAoGCCqGSM49
|
||||
AwEHoUQDQgAEgQHs5HRkpurXDPaabivT2IaRoyYtIsuk92Ner/JmgKjYoSumHVmS
|
||||
NfZ9nLTVjxeD08pD548KWrqmJAeZNsDDqQ==
|
||||
-----END EC PRIVATE KEY-----");
|
||||
ECParameters ecParameters = ExportParameters(key, true);
|
||||
ECParameters expected = EccTestData.GetNistP256ReferenceKey();
|
||||
EccTestBase.AssertEqual(expected, ecParameters);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ImportFromPem_ECPrivateKey_IgnoresUnrelatedAlgorithm()
|
||||
{
|
||||
using (TAlg key = CreateKey())
|
||||
{
|
||||
key.ImportFromPem(@"
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIBOwIBAAJBALc/WfXui9VeJLf/AprRaoVDyW0lPlQxm5NTLEHDwUd7idstLzPX
|
||||
uah0WEjgao5oO1BEUR4byjYlJ+F89Cs4BhUCAwEAAQJBAK/m8jYvnK9exaSR+DAh
|
||||
Ij12ip5pB+HOFOdhCbS/coNoIowa6WJGrd3Np1m9BBhouWloF8UB6Iu8/e/wAg+F
|
||||
9ykCIQDzcnsehnYgVZTTxzoCJ01PGpgESilRyFzNEsb8V60ZewIhAMCyOujqUqn7
|
||||
Q079SlHzXuvocqIdt4IM1EmIlrlU9GGvAh8Ijv3FFPUSLfANgfOIH9mX7ldpzzGk
|
||||
rmaUzxQvyuVLAiEArCTM8dSbopUADWnD4jArhU50UhWAIaM6ZrKqC8k0RKsCIQDC
|
||||
yZWUxoxAdjfrBGsx+U6BHM0Myqqe7fY7hjWzj4aBCw==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIHChLC2xaEXtVv9oz8IaRys/BNfWhRv2NJ8tfVs0UrOKoAoGCCqGSM49
|
||||
AwEHoUQDQgAEgQHs5HRkpurXDPaabivT2IaRoyYtIsuk92Ner/JmgKjYoSumHVmS
|
||||
NfZ9nLTVjxeD08pD548KWrqmJAeZNsDDqQ==
|
||||
-----END EC PRIVATE KEY-----");
|
||||
ECParameters ecParameters = ExportParameters(key, true);
|
||||
ECParameters expected = EccTestData.GetNistP256ReferenceKey();
|
||||
EccTestBase.AssertEqual(expected, ecParameters);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ImportFromPem_Pkcs8_Simple()
|
||||
{
|
||||
using (TAlg key = CreateKey())
|
||||
{
|
||||
key.ImportFromPem(@"
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgcKEsLbFoRe1W/2jP
|
||||
whpHKz8E19aFG/Y0ny19WzRSs4qhRANCAASBAezkdGSm6tcM9ppuK9PYhpGjJi0i
|
||||
y6T3Y16v8maAqNihK6YdWZI19n2ctNWPF4PTykPnjwpauqYkB5k2wMOp
|
||||
-----END PRIVATE KEY-----");
|
||||
ECParameters ecParameters = ExportParameters(key, true);
|
||||
ECParameters expected = EccTestData.GetNistP256ReferenceKey();
|
||||
EccTestBase.AssertEqual(expected, ecParameters);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ImportFromPem_Pkcs8_IgnoresUnrelatedAlgorithm()
|
||||
{
|
||||
using (TAlg key = CreateKey())
|
||||
{
|
||||
key.ImportFromPem(@"
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIBOwIBAAJBALc/WfXui9VeJLf/AprRaoVDyW0lPlQxm5NTLEHDwUd7idstLzPX
|
||||
uah0WEjgao5oO1BEUR4byjYlJ+F89Cs4BhUCAwEAAQJBAK/m8jYvnK9exaSR+DAh
|
||||
Ij12ip5pB+HOFOdhCbS/coNoIowa6WJGrd3Np1m9BBhouWloF8UB6Iu8/e/wAg+F
|
||||
9ykCIQDzcnsehnYgVZTTxzoCJ01PGpgESilRyFzNEsb8V60ZewIhAMCyOujqUqn7
|
||||
Q079SlHzXuvocqIdt4IM1EmIlrlU9GGvAh8Ijv3FFPUSLfANgfOIH9mX7ldpzzGk
|
||||
rmaUzxQvyuVLAiEArCTM8dSbopUADWnD4jArhU50UhWAIaM6ZrKqC8k0RKsCIQDC
|
||||
yZWUxoxAdjfrBGsx+U6BHM0Myqqe7fY7hjWzj4aBCw==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgcKEsLbFoRe1W/2jP
|
||||
whpHKz8E19aFG/Y0ny19WzRSs4qhRANCAASBAezkdGSm6tcM9ppuK9PYhpGjJi0i
|
||||
y6T3Y16v8maAqNihK6YdWZI19n2ctNWPF4PTykPnjwpauqYkB5k2wMOp
|
||||
-----END PRIVATE KEY-----");
|
||||
ECParameters ecParameters = ExportParameters(key, true);
|
||||
ECParameters expected = EccTestData.GetNistP256ReferenceKey();
|
||||
EccTestBase.AssertEqual(expected, ecParameters);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ImportFromPem_Spki_Simple()
|
||||
{
|
||||
using (TAlg key = CreateKey())
|
||||
{
|
||||
key.ImportFromPem(@"
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEgQHs5HRkpurXDPaabivT2IaRoyYt
|
||||
Isuk92Ner/JmgKjYoSumHVmSNfZ9nLTVjxeD08pD548KWrqmJAeZNsDDqQ==
|
||||
-----END PUBLIC KEY-----");
|
||||
ECParameters ecParameters = ExportParameters(key, false);
|
||||
ECParameters expected = EccTestData.GetNistP256ReferenceKey();
|
||||
EccTestBase.ComparePublicKey(expected.Q, ecParameters.Q, isEqual: true);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ImportFromPem_Spki_PrecedingUnrelatedPemIsIgnored()
|
||||
{
|
||||
using (TAlg key = CreateKey())
|
||||
{
|
||||
key.ImportFromPem(@"
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICTzCCAgmgAwIBAgIJAMQtYhFJ0+5jMA0GCSqGSIb3DQEBBQUAMIGSMQswCQYD
|
||||
VQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3RvbjEQMA4GA1UEBwwHUmVkbW9uZDEY
|
||||
MBYGA1UECgwPTWljcm9zb2Z0IENvcnAuMSAwHgYDVQQLDBcuTkVUIEZyYW1ld29y
|
||||
ayAoQ29yZUZ4KTEgMB4GA1UEAwwXUlNBIDM4NC1iaXQgQ2VydGlmaWNhdGUwHhcN
|
||||
MTYwMzAyMTY1OTA0WhcNMTYwNDAxMTY1OTA0WjCBkjELMAkGA1UEBhMCVVMxEzAR
|
||||
BgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1JlZG1vbmQxGDAWBgNVBAoMD01p
|
||||
Y3Jvc29mdCBDb3JwLjEgMB4GA1UECwwXLk5FVCBGcmFtZXdvcmsgKENvcmVGeCkx
|
||||
IDAeBgNVBAMMF1JTQSAzODQtYml0IENlcnRpZmljYXRlMEwwDQYJKoZIhvcNAQEB
|
||||
BQADOwAwOAIxANrMIthuZxV1Ay4x8gbc/BksZeLVEInlES0JbyiCr9tbeM22Vy/S
|
||||
9h2zkEciMuPZ9QIDAQABo1AwTjAdBgNVHQ4EFgQU5FG2Fmi86hJOCf4KnjaxOGWV
|
||||
dRUwHwYDVR0jBBgwFoAU5FG2Fmi86hJOCf4KnjaxOGWVdRUwDAYDVR0TBAUwAwEB
|
||||
/zANBgkqhkiG9w0BAQUFAAMxAEzDg/u8TlApCnE8qxhcbTXk2MbX+2n5PCn+MVrW
|
||||
wggvPj3b2WMXsVWiPr4S1Y/nBA==
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEgQHs5HRkpurXDPaabivT2IaRoyYt
|
||||
Isuk92Ner/JmgKjYoSumHVmSNfZ9nLTVjxeD08pD548KWrqmJAeZNsDDqQ==
|
||||
-----END PUBLIC KEY-----");
|
||||
ECParameters ecParameters = ExportParameters(key, false);
|
||||
ECParameters expected = EccTestData.GetNistP256ReferenceKey();
|
||||
EccTestBase.ComparePublicKey(expected.Q, ecParameters.Q, isEqual: true);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ImportFromPem_Spki_IgnoresUnrelatedAlgorithms()
|
||||
{
|
||||
using (TAlg key = CreateKey())
|
||||
{
|
||||
key.ImportFromPem(@"
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIBOwIBAAJBALc/WfXui9VeJLf/AprRaoVDyW0lPlQxm5NTLEHDwUd7idstLzPX
|
||||
uah0WEjgao5oO1BEUR4byjYlJ+F89Cs4BhUCAwEAAQJBAK/m8jYvnK9exaSR+DAh
|
||||
Ij12ip5pB+HOFOdhCbS/coNoIowa6WJGrd3Np1m9BBhouWloF8UB6Iu8/e/wAg+F
|
||||
9ykCIQDzcnsehnYgVZTTxzoCJ01PGpgESilRyFzNEsb8V60ZewIhAMCyOujqUqn7
|
||||
Q079SlHzXuvocqIdt4IM1EmIlrlU9GGvAh8Ijv3FFPUSLfANgfOIH9mX7ldpzzGk
|
||||
rmaUzxQvyuVLAiEArCTM8dSbopUADWnD4jArhU50UhWAIaM6ZrKqC8k0RKsCIQDC
|
||||
yZWUxoxAdjfrBGsx+U6BHM0Myqqe7fY7hjWzj4aBCw==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEgQHs5HRkpurXDPaabivT2IaRoyYt
|
||||
Isuk92Ner/JmgKjYoSumHVmSNfZ9nLTVjxeD08pD548KWrqmJAeZNsDDqQ==
|
||||
-----END PUBLIC KEY-----");
|
||||
ECParameters ecParameters = ExportParameters(key, false);
|
||||
ECParameters expected = EccTestData.GetNistP256ReferenceKey();
|
||||
EccTestBase.ComparePublicKey(expected.Q, ecParameters.Q, isEqual: true);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ImportFromPem_Spki_PrecedingMalformedPem()
|
||||
{
|
||||
using (TAlg key = CreateKey())
|
||||
{
|
||||
key.ImportFromPem(@"
|
||||
-----BEGIN CERTIFICATE-----
|
||||
$$ I AM NOT A PEM
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEgQHs5HRkpurXDPaabivT2IaRoyYt
|
||||
Isuk92Ner/JmgKjYoSumHVmSNfZ9nLTVjxeD08pD548KWrqmJAeZNsDDqQ==
|
||||
-----END PUBLIC KEY-----");
|
||||
ECParameters ecParameters = ExportParameters(key, false);
|
||||
ECParameters expected = EccTestData.GetNistP256ReferenceKey();
|
||||
EccTestBase.ComparePublicKey(expected.Q, ecParameters.Q, isEqual: true);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ImportFromPem_Spki_AmbiguousKey_Spki()
|
||||
{
|
||||
using (TAlg key = CreateKey())
|
||||
{
|
||||
string pem = @"
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEgQHs5HRkpurXDPaabivT2IaRoyYt
|
||||
Isuk92Ner/JmgKjYoSumHVmSNfZ9nLTVjxeD08pD548KWrqmJAeZNsDDqQ==
|
||||
-----END PUBLIC KEY-----
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEgQHs5HRkpurXDPaabivT2IaRoyYt
|
||||
Isuk92Ner/JmgKjYoSumHVmSNfZ9nLTVjxeD08pD548KWrqmJAeZNsDDqQ==
|
||||
-----END PUBLIC KEY-----";
|
||||
ArgumentException ae = AssertExtensions.Throws<ArgumentException>("input", () => key.ImportFromPem(pem));
|
||||
Assert.Contains(AmbiguousExceptionMarker, ae.Message);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ImportFromPem_Spki_AmbiguousKey_EncryptedPkcs8()
|
||||
{
|
||||
using (TAlg key = CreateKey())
|
||||
{
|
||||
string pem = @"
|
||||
-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||
MIHgMEsGCSqGSIb3DQEFDTA+MCkGCSqGSIb3DQEFDDAcBAjVvm4KTLb0JgICCAAw
|
||||
DAYIKoZIhvcNAgkFADARBgUrDgMCBwQIuHgfok8Ytl0EgZDkDSJ9vt8UvSesdyV+
|
||||
Evt9yfvEjiP/6yITq59drw1Kcgp6buOCVCY7LZ06aD6WpogiqGDYMuzfvqg5hNFp
|
||||
opSAJ/pvHONL5kyAJLeNyG9c/mR2qyrP2L9gL0Z5fB9NyPejKTLi0PXMGQWdDTH8
|
||||
Qh0fqdrNovgFLubbJFMQN/MwwIAfIuf0Mn0WFYYeQiBJ3kg=
|
||||
-----END ENCRYPTED PRIVATE KEY-----
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEgQHs5HRkpurXDPaabivT2IaRoyYt
|
||||
Isuk92Ner/JmgKjYoSumHVmSNfZ9nLTVjxeD08pD548KWrqmJAeZNsDDqQ==
|
||||
-----END PUBLIC KEY-----";
|
||||
ArgumentException ae = AssertExtensions.Throws<ArgumentException>("input", () => key.ImportFromPem(pem));
|
||||
Assert.Contains(AmbiguousExceptionMarker, ae.Message);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ImportFromPem_Spki_AmbiguousKey_EncryptedPkcs8_Pkcs8First()
|
||||
{
|
||||
using (TAlg key = CreateKey())
|
||||
{
|
||||
string pem = @"
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEgQHs5HRkpurXDPaabivT2IaRoyYt
|
||||
Isuk92Ner/JmgKjYoSumHVmSNfZ9nLTVjxeD08pD548KWrqmJAeZNsDDqQ==
|
||||
-----END PUBLIC KEY-----
|
||||
-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||
MIHgMEsGCSqGSIb3DQEFDTA+MCkGCSqGSIb3DQEFDDAcBAjVvm4KTLb0JgICCAAw
|
||||
DAYIKoZIhvcNAgkFADARBgUrDgMCBwQIuHgfok8Ytl0EgZDkDSJ9vt8UvSesdyV+
|
||||
Evt9yfvEjiP/6yITq59drw1Kcgp6buOCVCY7LZ06aD6WpogiqGDYMuzfvqg5hNFp
|
||||
opSAJ/pvHONL5kyAJLeNyG9c/mR2qyrP2L9gL0Z5fB9NyPejKTLi0PXMGQWdDTH8
|
||||
Qh0fqdrNovgFLubbJFMQN/MwwIAfIuf0Mn0WFYYeQiBJ3kg=
|
||||
-----END ENCRYPTED PRIVATE KEY-----";
|
||||
ArgumentException ae = AssertExtensions.Throws<ArgumentException>("input", () => key.ImportFromPem(pem));
|
||||
Assert.Contains(AmbiguousExceptionMarker, ae.Message);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ImportFromPem_EncryptedPrivateKeyFails()
|
||||
{
|
||||
using (TAlg key = CreateKey())
|
||||
{
|
||||
string pem = @"
|
||||
-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||
MIHgMEsGCSqGSIb3DQEFDTA+MCkGCSqGSIb3DQEFDDAcBAjVvm4KTLb0JgICCAAw
|
||||
DAYIKoZIhvcNAgkFADARBgUrDgMCBwQIuHgfok8Ytl0EgZDkDSJ9vt8UvSesdyV+
|
||||
Evt9yfvEjiP/6yITq59drw1Kcgp6buOCVCY7LZ06aD6WpogiqGDYMuzfvqg5hNFp
|
||||
opSAJ/pvHONL5kyAJLeNyG9c/mR2qyrP2L9gL0Z5fB9NyPejKTLi0PXMGQWdDTH8
|
||||
Qh0fqdrNovgFLubbJFMQN/MwwIAfIuf0Mn0WFYYeQiBJ3kg=
|
||||
-----END ENCRYPTED PRIVATE KEY-----";
|
||||
ArgumentException ae = AssertExtensions.Throws<ArgumentException>("input", () => key.ImportFromPem(pem));
|
||||
Assert.Contains(EncryptedExceptionMarker, ae.Message);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ImportFromPem_MultipleEncryptedPrivateKeyAreAmbiguous()
|
||||
{
|
||||
using (TAlg key = CreateKey())
|
||||
{
|
||||
string pem = @"
|
||||
-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||
MIHgMEsGCSqGSIb3DQEFDTA+MCkGCSqGSIb3DQEFDDAcBAjVvm4KTLb0JgICCAAw
|
||||
DAYIKoZIhvcNAgkFADARBgUrDgMCBwQIuHgfok8Ytl0EgZDkDSJ9vt8UvSesdyV+
|
||||
Evt9yfvEjiP/6yITq59drw1Kcgp6buOCVCY7LZ06aD6WpogiqGDYMuzfvqg5hNFp
|
||||
opSAJ/pvHONL5kyAJLeNyG9c/mR2qyrP2L9gL0Z5fB9NyPejKTLi0PXMGQWdDTH8
|
||||
Qh0fqdrNovgFLubbJFMQN/MwwIAfIuf0Mn0WFYYeQiBJ3kg=
|
||||
-----END ENCRYPTED PRIVATE KEY-----
|
||||
-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||
MIHgMEsGCSqGSIb3DQEFDTA+MCkGCSqGSIb3DQEFDDAcBAjVvm4KTLb0JgICCAAw
|
||||
DAYIKoZIhvcNAgkFADARBgUrDgMCBwQIuHgfok8Ytl0EgZDkDSJ9vt8UvSesdyV+
|
||||
Evt9yfvEjiP/6yITq59drw1Kcgp6buOCVCY7LZ06aD6WpogiqGDYMuzfvqg5hNFp
|
||||
opSAJ/pvHONL5kyAJLeNyG9c/mR2qyrP2L9gL0Z5fB9NyPejKTLi0PXMGQWdDTH8
|
||||
Qh0fqdrNovgFLubbJFMQN/MwwIAfIuf0Mn0WFYYeQiBJ3kg=
|
||||
-----END ENCRYPTED PRIVATE KEY-----";
|
||||
ArgumentException ae = AssertExtensions.Throws<ArgumentException>("input", () => key.ImportFromPem(pem));
|
||||
Assert.Contains(AmbiguousExceptionMarker, ae.Message);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ImportFromEncryptedPem_Pkcs8_Char_Simple()
|
||||
{
|
||||
using (TAlg key = CreateKey())
|
||||
{
|
||||
string pem = @"
|
||||
-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||
MIHgMEsGCSqGSIb3DQEFDTA+MCkGCSqGSIb3DQEFDDAcBAjVvm4KTLb0JgICCAAw
|
||||
DAYIKoZIhvcNAgkFADARBgUrDgMCBwQIuHgfok8Ytl0EgZDkDSJ9vt8UvSesdyV+
|
||||
Evt9yfvEjiP/6yITq59drw1Kcgp6buOCVCY7LZ06aD6WpogiqGDYMuzfvqg5hNFp
|
||||
opSAJ/pvHONL5kyAJLeNyG9c/mR2qyrP2L9gL0Z5fB9NyPejKTLi0PXMGQWdDTH8
|
||||
Qh0fqdrNovgFLubbJFMQN/MwwIAfIuf0Mn0WFYYeQiBJ3kg=
|
||||
-----END ENCRYPTED PRIVATE KEY-----";
|
||||
key.ImportFromEncryptedPem(pem, "test");
|
||||
ECParameters ecParameters = ExportParameters(key, true);
|
||||
ECParameters expected = EccTestData.GetNistP256ReferenceKey();
|
||||
EccTestBase.AssertEqual(expected, ecParameters);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ImportFromEncryptedPem_Pkcs8_Byte_Simple()
|
||||
{
|
||||
using (TAlg key = CreateKey())
|
||||
{
|
||||
string pem = @"
|
||||
-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||
MIHsMFcGCSqGSIb3DQEFDTBKMCkGCSqGSIb3DQEFDDAcBAgf9krO2ZiPvAICCAAw
|
||||
DAYIKoZIhvcNAgkFADAdBglghkgBZQMEAQIEEEv4Re1ATH9lHzx+13GoZU0EgZAV
|
||||
iE/+pIb/4quf+Y524bXUKTGYXzdSUE8Dp1qdZFcwDiCYCTtpL+065fGhmf1KZS2c
|
||||
/OMt/tWvtMSj17+dJvShsu/NYJXF5fsfpSJbd3e50Y3AisW0Ob7mmF54KBfg6Y+4
|
||||
aATwwQdUIKVzUZsQctsHPjbriQKKn7GKSyUOikBUNQ+TozojX8/g7JAsl+T9jGM=
|
||||
-----END ENCRYPTED PRIVATE KEY-----";
|
||||
byte[] passwordBytes = Encoding.UTF8.GetBytes("test");
|
||||
key.ImportFromEncryptedPem(pem, passwordBytes);
|
||||
ECParameters ecParameters = ExportParameters(key, true);
|
||||
ECParameters expected = EccTestData.GetNistP256ReferenceKey();
|
||||
EccTestBase.AssertEqual(expected, ecParameters);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ImportFromEncryptedPem_AmbiguousPem_Byte()
|
||||
{
|
||||
using (TAlg key = CreateKey())
|
||||
{
|
||||
string pem = @"
|
||||
-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||
MIHsMFcGCSqGSIb3DQEFDTBKMCkGCSqGSIb3DQEFDDAcBAgf9krO2ZiPvAICCAAw
|
||||
DAYIKoZIhvcNAgkFADAdBglghkgBZQMEAQIEEEv4Re1ATH9lHzx+13GoZU0EgZAV
|
||||
iE/+pIb/4quf+Y524bXUKTGYXzdSUE8Dp1qdZFcwDiCYCTtpL+065fGhmf1KZS2c
|
||||
/OMt/tWvtMSj17+dJvShsu/NYJXF5fsfpSJbd3e50Y3AisW0Ob7mmF54KBfg6Y+4
|
||||
aATwwQdUIKVzUZsQctsHPjbriQKKn7GKSyUOikBUNQ+TozojX8/g7JAsl+T9jGM=
|
||||
-----END ENCRYPTED PRIVATE KEY-----
|
||||
-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||
MIHgMEsGCSqGSIb3DQEFDTA+MCkGCSqGSIb3DQEFDDAcBAjVvm4KTLb0JgICCAAw
|
||||
DAYIKoZIhvcNAgkFADARBgUrDgMCBwQIuHgfok8Ytl0EgZDkDSJ9vt8UvSesdyV+
|
||||
Evt9yfvEjiP/6yITq59drw1Kcgp6buOCVCY7LZ06aD6WpogiqGDYMuzfvqg5hNFp
|
||||
opSAJ/pvHONL5kyAJLeNyG9c/mR2qyrP2L9gL0Z5fB9NyPejKTLi0PXMGQWdDTH8
|
||||
Qh0fqdrNovgFLubbJFMQN/MwwIAfIuf0Mn0WFYYeQiBJ3kg=
|
||||
-----END ENCRYPTED PRIVATE KEY-----";
|
||||
byte[] passwordBytes = Encoding.UTF8.GetBytes("test");
|
||||
|
||||
ArgumentException ae = AssertExtensions.Throws<ArgumentException>("input", () =>
|
||||
key.ImportFromEncryptedPem(pem, passwordBytes));
|
||||
|
||||
Assert.Contains(AmbiguousExceptionMarker, ae.Message);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ImportFromEncryptedPem_AmbiguousPem_Char()
|
||||
{
|
||||
using (TAlg key = CreateKey())
|
||||
{
|
||||
string pem = @"
|
||||
-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||
MIHsMFcGCSqGSIb3DQEFDTBKMCkGCSqGSIb3DQEFDDAcBAgf9krO2ZiPvAICCAAw
|
||||
DAYIKoZIhvcNAgkFADAdBglghkgBZQMEAQIEEEv4Re1ATH9lHzx+13GoZU0EgZAV
|
||||
iE/+pIb/4quf+Y524bXUKTGYXzdSUE8Dp1qdZFcwDiCYCTtpL+065fGhmf1KZS2c
|
||||
/OMt/tWvtMSj17+dJvShsu/NYJXF5fsfpSJbd3e50Y3AisW0Ob7mmF54KBfg6Y+4
|
||||
aATwwQdUIKVzUZsQctsHPjbriQKKn7GKSyUOikBUNQ+TozojX8/g7JAsl+T9jGM=
|
||||
-----END ENCRYPTED PRIVATE KEY-----
|
||||
-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||
MIHgMEsGCSqGSIb3DQEFDTA+MCkGCSqGSIb3DQEFDDAcBAjVvm4KTLb0JgICCAAw
|
||||
DAYIKoZIhvcNAgkFADARBgUrDgMCBwQIuHgfok8Ytl0EgZDkDSJ9vt8UvSesdyV+
|
||||
Evt9yfvEjiP/6yITq59drw1Kcgp6buOCVCY7LZ06aD6WpogiqGDYMuzfvqg5hNFp
|
||||
opSAJ/pvHONL5kyAJLeNyG9c/mR2qyrP2L9gL0Z5fB9NyPejKTLi0PXMGQWdDTH8
|
||||
Qh0fqdrNovgFLubbJFMQN/MwwIAfIuf0Mn0WFYYeQiBJ3kg=
|
||||
-----END ENCRYPTED PRIVATE KEY-----";
|
||||
ArgumentException ae = AssertExtensions.Throws<ArgumentException>("input", () =>
|
||||
key.ImportFromEncryptedPem(pem, ""));
|
||||
Assert.Contains(AmbiguousExceptionMarker, ae.Message);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ImportFromEncryptedPem_UnencryptedPem_ThrowsNoPem()
|
||||
{
|
||||
using (TAlg key = CreateKey())
|
||||
{
|
||||
string pem = @"
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgcKEsLbFoRe1W/2jP
|
||||
whpHKz8E19aFG/Y0ny19WzRSs4qhRANCAASBAezkdGSm6tcM9ppuK9PYhpGjJi0i
|
||||
y6T3Y16v8maAqNihK6YdWZI19n2ctNWPF4PTykPnjwpauqYkB5k2wMOp
|
||||
-----END PRIVATE KEY-----";
|
||||
byte[] passwordBytes = Array.Empty<byte>();
|
||||
ArgumentException ae = AssertExtensions.Throws<ArgumentException>("input", () =>
|
||||
key.ImportFromEncryptedPem(pem, passwordBytes));
|
||||
Assert.Contains(NoPemExceptionMarker, ae.Message);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ImportFromEncryptedPem_NoPem()
|
||||
{
|
||||
using(TAlg key = CreateKey())
|
||||
{
|
||||
ArgumentException ae = AssertExtensions.Throws<ArgumentException>("input", () =>
|
||||
key.ImportFromEncryptedPem("", ""));
|
||||
Assert.Contains(NoPemExceptionMarker, ae.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Security.Cryptography.Tests;
|
||||
|
||||
namespace System.Security.Cryptography.EcDsa.Tests
|
||||
{
|
||||
public sealed class ECDiffieHellmanKeyPemTests : ECKeyPemTests<ECDiffieHellman>
|
||||
{
|
||||
protected override ECDiffieHellman CreateKey() => ECDiffieHellman.Create();
|
||||
protected override ECParameters ExportParameters(ECDiffieHellman key, bool includePrivateParameters) =>
|
||||
key.ExportParameters(includePrivateParameters);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Security.Cryptography.Tests;
|
||||
|
||||
namespace System.Security.Cryptography.EcDsa.Tests
|
||||
{
|
||||
public sealed class ECDsaKeyPemTests : ECKeyPemTests<ECDsa>
|
||||
{
|
||||
protected override ECDsa CreateKey() => ECDsa.Create();
|
||||
protected override ECParameters ExportParameters(ECDsa key, bool includePrivateParameters) =>
|
||||
key.ExportParameters(includePrivateParameters);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,530 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Text;
|
||||
using Test.Cryptography;
|
||||
using Xunit;
|
||||
|
||||
namespace System.Security.Cryptography.Rsa.Tests
|
||||
{
|
||||
public static class RSAKeyPemTests
|
||||
{
|
||||
private const string AmbiguousExceptionMarker = "multiple keys";
|
||||
private const string EncryptedExceptionMarker = "encrypted key";
|
||||
private const string NoPemExceptionMarker = "No supported key";
|
||||
|
||||
[Fact]
|
||||
public static void ImportFromPem_NoPem()
|
||||
{
|
||||
using (RSA rsa = RSAFactory.Create())
|
||||
{
|
||||
string pem = @"these aren't the PEMs you're looking for";
|
||||
ArgumentException ae = AssertExtensions.Throws<ArgumentException>("input", () => rsa.ImportFromPem(pem));
|
||||
Assert.Contains(NoPemExceptionMarker, ae.Message);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void ImportFromPem_RSAPrivateKey_Simple()
|
||||
{
|
||||
using (RSA rsa = RSAFactory.Create())
|
||||
{
|
||||
string pem = @"
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIBOwIBAAJBALc/WfXui9VeJLf/AprRaoVDyW0lPlQxm5NTLEHDwUd7idstLzPX
|
||||
uah0WEjgao5oO1BEUR4byjYlJ+F89Cs4BhUCAwEAAQJBAK/m8jYvnK9exaSR+DAh
|
||||
Ij12ip5pB+HOFOdhCbS/coNoIowa6WJGrd3Np1m9BBhouWloF8UB6Iu8/e/wAg+F
|
||||
9ykCIQDzcnsehnYgVZTTxzoCJ01PGpgESilRyFzNEsb8V60ZewIhAMCyOujqUqn7
|
||||
Q079SlHzXuvocqIdt4IM1EmIlrlU9GGvAh8Ijv3FFPUSLfANgfOIH9mX7ldpzzGk
|
||||
rmaUzxQvyuVLAiEArCTM8dSbopUADWnD4jArhU50UhWAIaM6ZrKqC8k0RKsCIQDC
|
||||
yZWUxoxAdjfrBGsx+U6BHM0Myqqe7fY7hjWzj4aBCw==
|
||||
-----END RSA PRIVATE KEY-----";
|
||||
|
||||
rsa.ImportFromPem(pem);
|
||||
RSAParameters rsaParameters = rsa.ExportParameters(true);
|
||||
|
||||
ImportExport.AssertKeyEquals(TestData.DiminishedDPParameters, rsaParameters);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void ImportFromPem_Pkcs8UnEncrypted_Simple()
|
||||
{
|
||||
using (RSA rsa = RSAFactory.Create())
|
||||
{
|
||||
string pem = @"
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAtz9Z9e6L1V4kt/8C
|
||||
mtFqhUPJbSU+VDGbk1MsQcPBR3uJ2y0vM9e5qHRYSOBqjmg7UERRHhvKNiUn4Xz0
|
||||
KzgGFQIDAQABAkEAr+byNi+cr17FpJH4MCEiPXaKnmkH4c4U52EJtL9yg2gijBrp
|
||||
Ykat3c2nWb0EGGi5aWgXxQHoi7z97/ACD4X3KQIhAPNyex6GdiBVlNPHOgInTU8a
|
||||
mARKKVHIXM0SxvxXrRl7AiEAwLI66OpSqftDTv1KUfNe6+hyoh23ggzUSYiWuVT0
|
||||
Ya8CHwiO/cUU9RIt8A2B84gf2ZfuV2nPMaSuZpTPFC/K5UsCIQCsJMzx1JuilQAN
|
||||
acPiMCuFTnRSFYAhozpmsqoLyTREqwIhAMLJlZTGjEB2N+sEazH5ToEczQzKqp7t
|
||||
9juGNbOPhoEL
|
||||
-----END PRIVATE KEY-----";
|
||||
|
||||
rsa.ImportFromPem(pem);
|
||||
RSAParameters rsaParameters = rsa.ExportParameters(true);
|
||||
|
||||
ImportExport.AssertKeyEquals(TestData.DiminishedDPParameters, rsaParameters);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void ImportFromPem_Pkcs8UnEncrypted_UnrelatedAlgorithmIsIgnored()
|
||||
{
|
||||
using (RSA rsa = RSAFactory.Create())
|
||||
{
|
||||
string pem = @"
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIHChLC2xaEXtVv9oz8IaRys/BNfWhRv2NJ8tfVs0UrOKoAoGCCqGSM49
|
||||
AwEHoUQDQgAEgQHs5HRkpurXDPaabivT2IaRoyYtIsuk92Ner/JmgKjYoSumHVmS
|
||||
NfZ9nLTVjxeD08pD548KWrqmJAeZNsDDqQ==
|
||||
-----END EC PRIVATE KEY-----
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAtz9Z9e6L1V4kt/8C
|
||||
mtFqhUPJbSU+VDGbk1MsQcPBR3uJ2y0vM9e5qHRYSOBqjmg7UERRHhvKNiUn4Xz0
|
||||
KzgGFQIDAQABAkEAr+byNi+cr17FpJH4MCEiPXaKnmkH4c4U52EJtL9yg2gijBrp
|
||||
Ykat3c2nWb0EGGi5aWgXxQHoi7z97/ACD4X3KQIhAPNyex6GdiBVlNPHOgInTU8a
|
||||
mARKKVHIXM0SxvxXrRl7AiEAwLI66OpSqftDTv1KUfNe6+hyoh23ggzUSYiWuVT0
|
||||
Ya8CHwiO/cUU9RIt8A2B84gf2ZfuV2nPMaSuZpTPFC/K5UsCIQCsJMzx1JuilQAN
|
||||
acPiMCuFTnRSFYAhozpmsqoLyTREqwIhAMLJlZTGjEB2N+sEazH5ToEczQzKqp7t
|
||||
9juGNbOPhoEL
|
||||
-----END PRIVATE KEY-----";
|
||||
|
||||
rsa.ImportFromPem(pem);
|
||||
RSAParameters rsaParameters = rsa.ExportParameters(true);
|
||||
|
||||
ImportExport.AssertKeyEquals(TestData.DiminishedDPParameters, rsaParameters);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void ImportFromPem_SubjectPublicKeyInfo_Simple()
|
||||
{
|
||||
using (RSA rsa = RSAFactory.Create())
|
||||
{
|
||||
string pem = @"
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALc/WfXui9VeJLf/AprRaoVDyW0lPlQx
|
||||
m5NTLEHDwUd7idstLzPXuah0WEjgao5oO1BEUR4byjYlJ+F89Cs4BhUCAwEAAQ==
|
||||
-----END PUBLIC KEY-----";
|
||||
rsa.ImportFromPem(pem);
|
||||
RSAParameters rsaParameters = rsa.ExportParameters(false);
|
||||
|
||||
ImportExport.AssertKeyEquals(TestData.DiminishedDPParameters.ToPublic(), rsaParameters);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void ImportFromPem_SubjectPublicKeyInfo_IgnoresUnrelatedAlgorithm()
|
||||
{
|
||||
using (RSA rsa = RSAFactory.Create())
|
||||
{
|
||||
string pem = @"
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIHChLC2xaEXtVv9oz8IaRys/BNfWhRv2NJ8tfVs0UrOKoAoGCCqGSM49
|
||||
AwEHoUQDQgAEgQHs5HRkpurXDPaabivT2IaRoyYtIsuk92Ner/JmgKjYoSumHVmS
|
||||
NfZ9nLTVjxeD08pD548KWrqmJAeZNsDDqQ==
|
||||
-----END EC PRIVATE KEY-----
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALc/WfXui9VeJLf/AprRaoVDyW0lPlQx
|
||||
m5NTLEHDwUd7idstLzPXuah0WEjgao5oO1BEUR4byjYlJ+F89Cs4BhUCAwEAAQ==
|
||||
-----END PUBLIC KEY-----";
|
||||
rsa.ImportFromPem(pem);
|
||||
RSAParameters rsaParameters = rsa.ExportParameters(false);
|
||||
|
||||
ImportExport.AssertKeyEquals(TestData.DiminishedDPParameters.ToPublic(), rsaParameters);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void ImportFromPem_RSAPublicKey_Simple()
|
||||
{
|
||||
using (RSA rsa = RSAFactory.Create())
|
||||
{
|
||||
string pem = @"
|
||||
-----BEGIN RSA PUBLIC KEY-----
|
||||
MEgCQQC3P1n17ovVXiS3/wKa0WqFQ8ltJT5UMZuTUyxBw8FHe4nbLS8z17modFhI
|
||||
4GqOaDtQRFEeG8o2JSfhfPQrOAYVAgMBAAE=
|
||||
-----END RSA PUBLIC KEY-----";
|
||||
|
||||
rsa.ImportFromPem(pem);
|
||||
RSAParameters rsaParameters = rsa.ExportParameters(false);
|
||||
|
||||
ImportExport.AssertKeyEquals(TestData.DiminishedDPParameters.ToPublic(), rsaParameters);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void ImportFromPem_RSAPrivateKey_PrecedingUnrelatedPem()
|
||||
{
|
||||
using (RSA rsa = RSAFactory.Create())
|
||||
{
|
||||
string pem = @"
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICTzCCAgmgAwIBAgIJAMQtYhFJ0+5jMA0GCSqGSIb3DQEBBQUAMIGSMQswCQYD
|
||||
VQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3RvbjEQMA4GA1UEBwwHUmVkbW9uZDEY
|
||||
MBYGA1UECgwPTWljcm9zb2Z0IENvcnAuMSAwHgYDVQQLDBcuTkVUIEZyYW1ld29y
|
||||
ayAoQ29yZUZ4KTEgMB4GA1UEAwwXUlNBIDM4NC1iaXQgQ2VydGlmaWNhdGUwHhcN
|
||||
MTYwMzAyMTY1OTA0WhcNMTYwNDAxMTY1OTA0WjCBkjELMAkGA1UEBhMCVVMxEzAR
|
||||
BgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1JlZG1vbmQxGDAWBgNVBAoMD01p
|
||||
Y3Jvc29mdCBDb3JwLjEgMB4GA1UECwwXLk5FVCBGcmFtZXdvcmsgKENvcmVGeCkx
|
||||
IDAeBgNVBAMMF1JTQSAzODQtYml0IENlcnRpZmljYXRlMEwwDQYJKoZIhvcNAQEB
|
||||
BQADOwAwOAIxANrMIthuZxV1Ay4x8gbc/BksZeLVEInlES0JbyiCr9tbeM22Vy/S
|
||||
9h2zkEciMuPZ9QIDAQABo1AwTjAdBgNVHQ4EFgQU5FG2Fmi86hJOCf4KnjaxOGWV
|
||||
dRUwHwYDVR0jBBgwFoAU5FG2Fmi86hJOCf4KnjaxOGWVdRUwDAYDVR0TBAUwAwEB
|
||||
/zANBgkqhkiG9w0BAQUFAAMxAEzDg/u8TlApCnE8qxhcbTXk2MbX+2n5PCn+MVrW
|
||||
wggvPj3b2WMXsVWiPr4S1Y/nBA==
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIBOwIBAAJBALc/WfXui9VeJLf/AprRaoVDyW0lPlQxm5NTLEHDwUd7idstLzPX
|
||||
uah0WEjgao5oO1BEUR4byjYlJ+F89Cs4BhUCAwEAAQJBAK/m8jYvnK9exaSR+DAh
|
||||
Ij12ip5pB+HOFOdhCbS/coNoIowa6WJGrd3Np1m9BBhouWloF8UB6Iu8/e/wAg+F
|
||||
9ykCIQDzcnsehnYgVZTTxzoCJ01PGpgESilRyFzNEsb8V60ZewIhAMCyOujqUqn7
|
||||
Q079SlHzXuvocqIdt4IM1EmIlrlU9GGvAh8Ijv3FFPUSLfANgfOIH9mX7ldpzzGk
|
||||
rmaUzxQvyuVLAiEArCTM8dSbopUADWnD4jArhU50UhWAIaM6ZrKqC8k0RKsCIQDC
|
||||
yZWUxoxAdjfrBGsx+U6BHM0Myqqe7fY7hjWzj4aBCw==
|
||||
-----END RSA PRIVATE KEY-----";
|
||||
rsa.ImportFromPem(pem);
|
||||
RSAParameters rsaParameters = rsa.ExportParameters(true);
|
||||
|
||||
ImportExport.AssertKeyEquals(TestData.DiminishedDPParameters, rsaParameters);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void ImportFromPem_RSAPrivateKey_PrecedingMalformedPem()
|
||||
{
|
||||
using (RSA rsa = RSAFactory.Create())
|
||||
{
|
||||
string pem = @"
|
||||
-----BEGIN CERTIFICATE-----
|
||||
$$ I AM NOT A PEM
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIBOwIBAAJBALc/WfXui9VeJLf/AprRaoVDyW0lPlQxm5NTLEHDwUd7idstLzPX
|
||||
uah0WEjgao5oO1BEUR4byjYlJ+F89Cs4BhUCAwEAAQJBAK/m8jYvnK9exaSR+DAh
|
||||
Ij12ip5pB+HOFOdhCbS/coNoIowa6WJGrd3Np1m9BBhouWloF8UB6Iu8/e/wAg+F
|
||||
9ykCIQDzcnsehnYgVZTTxzoCJ01PGpgESilRyFzNEsb8V60ZewIhAMCyOujqUqn7
|
||||
Q079SlHzXuvocqIdt4IM1EmIlrlU9GGvAh8Ijv3FFPUSLfANgfOIH9mX7ldpzzGk
|
||||
rmaUzxQvyuVLAiEArCTM8dSbopUADWnD4jArhU50UhWAIaM6ZrKqC8k0RKsCIQDC
|
||||
yZWUxoxAdjfrBGsx+U6BHM0Myqqe7fY7hjWzj4aBCw==
|
||||
-----END RSA PRIVATE KEY-----";
|
||||
rsa.ImportFromPem(pem);
|
||||
RSAParameters rsaParameters = rsa.ExportParameters(true);
|
||||
|
||||
ImportExport.AssertKeyEquals(TestData.DiminishedDPParameters, rsaParameters);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void ImportFromPem_RSAPrivateKey_IgnoresOtherAlgorithms()
|
||||
{
|
||||
using (RSA rsa = RSAFactory.Create())
|
||||
{
|
||||
string pem = @"
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIHChLC2xaEXtVv9oz8IaRys/BNfWhRv2NJ8tfVs0UrOKoAoGCCqGSM49
|
||||
AwEHoUQDQgAEgQHs5HRkpurXDPaabivT2IaRoyYtIsuk92Ner/JmgKjYoSumHVmS
|
||||
NfZ9nLTVjxeD08pD548KWrqmJAeZNsDDqQ==
|
||||
-----END EC PRIVATE KEY-----
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIBOwIBAAJBALc/WfXui9VeJLf/AprRaoVDyW0lPlQxm5NTLEHDwUd7idstLzPX
|
||||
uah0WEjgao5oO1BEUR4byjYlJ+F89Cs4BhUCAwEAAQJBAK/m8jYvnK9exaSR+DAh
|
||||
Ij12ip5pB+HOFOdhCbS/coNoIowa6WJGrd3Np1m9BBhouWloF8UB6Iu8/e/wAg+F
|
||||
9ykCIQDzcnsehnYgVZTTxzoCJ01PGpgESilRyFzNEsb8V60ZewIhAMCyOujqUqn7
|
||||
Q079SlHzXuvocqIdt4IM1EmIlrlU9GGvAh8Ijv3FFPUSLfANgfOIH9mX7ldpzzGk
|
||||
rmaUzxQvyuVLAiEArCTM8dSbopUADWnD4jArhU50UhWAIaM6ZrKqC8k0RKsCIQDC
|
||||
yZWUxoxAdjfrBGsx+U6BHM0Myqqe7fY7hjWzj4aBCw==
|
||||
-----END RSA PRIVATE KEY-----";
|
||||
rsa.ImportFromPem(pem);
|
||||
RSAParameters rsaParameters = rsa.ExportParameters(true);
|
||||
|
||||
ImportExport.AssertKeyEquals(TestData.DiminishedDPParameters, rsaParameters);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void ImportFromPem_RSAPrivateKey_AmbiguousKey_RSAPrivateKey()
|
||||
{
|
||||
using (RSA rsa = RSAFactory.Create())
|
||||
{
|
||||
string pem = @"
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MII=
|
||||
-----END RSA PRIVATE KEY-----
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIBOwIBAAJBALc/WfXui9VeJLf/AprRaoVDyW0lPlQxm5NTLEHDwUd7idstLzPX
|
||||
uah0WEjgao5oO1BEUR4byjYlJ+F89Cs4BhUCAwEAAQJBAK/m8jYvnK9exaSR+DAh
|
||||
Ij12ip5pB+HOFOdhCbS/coNoIowa6WJGrd3Np1m9BBhouWloF8UB6Iu8/e/wAg+F
|
||||
9ykCIQDzcnsehnYgVZTTxzoCJ01PGpgESilRyFzNEsb8V60ZewIhAMCyOujqUqn7
|
||||
Q079SlHzXuvocqIdt4IM1EmIlrlU9GGvAh8Ijv3FFPUSLfANgfOIH9mX7ldpzzGk
|
||||
rmaUzxQvyuVLAiEArCTM8dSbopUADWnD4jArhU50UhWAIaM6ZrKqC8k0RKsCIQDC
|
||||
yZWUxoxAdjfrBGsx+U6BHM0Myqqe7fY7hjWzj4aBCw==
|
||||
-----END RSA PRIVATE KEY-----";
|
||||
ArgumentException ae = AssertExtensions.Throws<ArgumentException>("input", () => rsa.ImportFromPem(pem));
|
||||
Assert.Contains(AmbiguousExceptionMarker, ae.Message);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void ImportFromPem_RSAPrivateKey_AmbiguousKey_SubjectPublicKeyInfo()
|
||||
{
|
||||
using (RSA rsa = RSAFactory.Create())
|
||||
{
|
||||
string pem = @"
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MII=
|
||||
-----END PUBLIC KEY-----
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIBOwIBAAJBALc/WfXui9VeJLf/AprRaoVDyW0lPlQxm5NTLEHDwUd7idstLzPX
|
||||
uah0WEjgao5oO1BEUR4byjYlJ+F89Cs4BhUCAwEAAQJBAK/m8jYvnK9exaSR+DAh
|
||||
Ij12ip5pB+HOFOdhCbS/coNoIowa6WJGrd3Np1m9BBhouWloF8UB6Iu8/e/wAg+F
|
||||
9ykCIQDzcnsehnYgVZTTxzoCJ01PGpgESilRyFzNEsb8V60ZewIhAMCyOujqUqn7
|
||||
Q079SlHzXuvocqIdt4IM1EmIlrlU9GGvAh8Ijv3FFPUSLfANgfOIH9mX7ldpzzGk
|
||||
rmaUzxQvyuVLAiEArCTM8dSbopUADWnD4jArhU50UhWAIaM6ZrKqC8k0RKsCIQDC
|
||||
yZWUxoxAdjfrBGsx+U6BHM0Myqqe7fY7hjWzj4aBCw==
|
||||
-----END RSA PRIVATE KEY-----";
|
||||
ArgumentException ae = AssertExtensions.Throws<ArgumentException>("input", () => rsa.ImportFromPem(pem));
|
||||
Assert.Contains(AmbiguousExceptionMarker, ae.Message);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void ImportFromPem_RSAPrivateKey_AmbiguousKey_RSAPublicKey()
|
||||
{
|
||||
using (RSA rsa = RSAFactory.Create())
|
||||
{
|
||||
string pem = @"
|
||||
-----BEGIN RSA PUBLIC KEY-----
|
||||
MII=
|
||||
-----END RSA PUBLIC KEY-----
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIBOwIBAAJBALc/WfXui9VeJLf/AprRaoVDyW0lPlQxm5NTLEHDwUd7idstLzPX
|
||||
uah0WEjgao5oO1BEUR4byjYlJ+F89Cs4BhUCAwEAAQJBAK/m8jYvnK9exaSR+DAh
|
||||
Ij12ip5pB+HOFOdhCbS/coNoIowa6WJGrd3Np1m9BBhouWloF8UB6Iu8/e/wAg+F
|
||||
9ykCIQDzcnsehnYgVZTTxzoCJ01PGpgESilRyFzNEsb8V60ZewIhAMCyOujqUqn7
|
||||
Q079SlHzXuvocqIdt4IM1EmIlrlU9GGvAh8Ijv3FFPUSLfANgfOIH9mX7ldpzzGk
|
||||
rmaUzxQvyuVLAiEArCTM8dSbopUADWnD4jArhU50UhWAIaM6ZrKqC8k0RKsCIQDC
|
||||
yZWUxoxAdjfrBGsx+U6BHM0Myqqe7fY7hjWzj4aBCw==
|
||||
-----END RSA PRIVATE KEY-----";
|
||||
ArgumentException ae = AssertExtensions.Throws<ArgumentException>("input", () => rsa.ImportFromPem(pem));
|
||||
Assert.Contains(AmbiguousExceptionMarker, ae.Message);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void ImportFromPem_RSAPrivateKey_AmbiguousKey_EncryptedPkcs8()
|
||||
{
|
||||
using (RSA rsa = RSAFactory.Create())
|
||||
{
|
||||
string pem = @"
|
||||
-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||
MII=
|
||||
-----END ENCRYPTED PRIVATE KEY-----
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIBOwIBAAJBALc/WfXui9VeJLf/AprRaoVDyW0lPlQxm5NTLEHDwUd7idstLzPX
|
||||
uah0WEjgao5oO1BEUR4byjYlJ+F89Cs4BhUCAwEAAQJBAK/m8jYvnK9exaSR+DAh
|
||||
Ij12ip5pB+HOFOdhCbS/coNoIowa6WJGrd3Np1m9BBhouWloF8UB6Iu8/e/wAg+F
|
||||
9ykCIQDzcnsehnYgVZTTxzoCJ01PGpgESilRyFzNEsb8V60ZewIhAMCyOujqUqn7
|
||||
Q079SlHzXuvocqIdt4IM1EmIlrlU9GGvAh8Ijv3FFPUSLfANgfOIH9mX7ldpzzGk
|
||||
rmaUzxQvyuVLAiEArCTM8dSbopUADWnD4jArhU50UhWAIaM6ZrKqC8k0RKsCIQDC
|
||||
yZWUxoxAdjfrBGsx+U6BHM0Myqqe7fY7hjWzj4aBCw==
|
||||
-----END RSA PRIVATE KEY-----";
|
||||
ArgumentException ae = AssertExtensions.Throws<ArgumentException>("input", () => rsa.ImportFromPem(pem));
|
||||
Assert.Contains(AmbiguousExceptionMarker, ae.Message);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void ImportFromPem_EncryptedPrivateKeyFails()
|
||||
{
|
||||
using (RSA rsa = RSAFactory.Create())
|
||||
{
|
||||
string pem = @"
|
||||
-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||
MIIBsTBLBgkqhkiG9w0BBQ0wPjApBgkqhkiG9w0BBQwwHAQIioaQaFwlfasCAggA
|
||||
MAwGCCqGSIb3DQIJBQAwEQYFKw4DAgcECJLGzSuIgnSkBIIBYHofFpp5AsrkNc9w
|
||||
s0uebkLBgMXbmhu+t6XQYXhnZXguT4KF4g49vIE3XwtZkXzEeSrNRIWZcPH1UWp2
|
||||
qbv2d+ub3wBpMdFDzv5Zty6e6gACWwyMRy/oX8gZqWDfDnQwm7BV21yLANEFnRuT
|
||||
K3c9EmQ9IAT2MLLRUeijyg6KUL0dZ5VmXbtQdDoovuhzU20HjSyQLXNbX8NzUhWy
|
||||
VMuNHs8NhiIgOuFKMoqlN42LBA1+iOA4MGR5XDXXmGyKPLCs0USbD9Dm4/Q1h7Fs
|
||||
x2yC94Mej7kgAusuNZk9GafsIQbM7jZT1PLxIKyMXAxIpS9sIYbegxK774npiy8/
|
||||
LiBC1SQXJ3sJdAeUE0QPJEci937f8SteWUmF5mUqznb/0nYjvSZh/GcZ4GWEAO8j
|
||||
RkMxT/C7OZVMOlb3HV3fJj7kDmOMqfc6aKEQjLdWtuYRB8CgaudldIpK4jP2+0b5
|
||||
pBORBb0=
|
||||
-----END ENCRYPTED PRIVATE KEY-----";
|
||||
ArgumentException ae = AssertExtensions.Throws<ArgumentException>("input", () => rsa.ImportFromPem(pem));
|
||||
Assert.Contains(EncryptedExceptionMarker, ae.Message);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void ImportFromPem_Pkcs8AlgorithmMismatch_Throws()
|
||||
{
|
||||
using (RSA rsa = RSAFactory.Create())
|
||||
{
|
||||
string pem = @"
|
||||
The below PEM is a 1024-bit DSA key.
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIBSgIBADCCASsGByqGSM44BAEwggEeAoGBAL5KGXEaazCA+k1pMcCBc/+bodFh
|
||||
0P4U2QDLyDtnmytusGPaHcFp69pVdJZWMBycwJdaFQkraQNmqQsjAmBHtpqMeJpE
|
||||
VLgjzve83oMAw5aysmaQC4Wy35vnBZnshvdzgbPRHZD2dWmFvWxToqBnxh74rb/H
|
||||
Nkpt8JrirFOdNuyvAhUA9+LZ6XHLZZKeFhDxYl+a9lYabdsCgYACRi+pc9joLRah
|
||||
A9ushrXVItFyOsq45hOB9hT37nyTEmane/YAjmoR28XyDYdF/Ql97iSVm3cY3OYT
|
||||
eDr38gQ/Hk0CgW3/RFrNWdbIpfMifs80vqCUNqDggcQixEmDVZ0gwq4+wz8EVyYG
|
||||
42+vM7ajN4O2VGvCA99Vl6zv69hOpAQWAhQtFFLZyKAUOQwUQh4hNw+oBgPhFw==
|
||||
-----END PRIVATE KEY-----";
|
||||
Assert.Throws<CryptographicException>(() => rsa.ImportFromPem(pem));
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void ImportFromEncryptedPem_Pkcs8Encrypted_Char_Simple()
|
||||
{
|
||||
using (RSA rsa = RSAFactory.Create())
|
||||
{
|
||||
string pem = @"
|
||||
-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||
MIIBsTBLBgkqhkiG9w0BBQ0wPjApBgkqhkiG9w0BBQwwHAQIcvgI1lw9LqYCAggA
|
||||
MAwGCCqGSIb3DQIJBQAwEQYFKw4DAgcECFDpLREQXt5pBIIBYOKuM5ljAvCViDL+
|
||||
nTFq7A/fI9rqdL20TMdf0wy7s43oXmsw5gCStoNEaoVToFCQWYYBRU99mK8YNFA8
|
||||
1ZJT53SDS7buJ0zX9oDltf2ByXRPI4mn2Il2HZvN2hi9ir1w8M3XoSFSurN9tC8r
|
||||
IOiGkVfK9Ll54knONewNiCNefFZFctRfVMbac5SwHokCkBMHukl0oPrpVuBE8kRo
|
||||
p7XtjM8ILtzLVz0iLqKXiNIf6kRdouCBmCn8VIQgIvPPIHD8vheMXWjN7g69P5n4
|
||||
1YI4c/acljcofmq1BBPTwvxaETrg2NHW0XMIgAxoaVP8lIIGlNk1glWTYpuMd69L
|
||||
AWvBUt33Sozc+dF0l7NGLAWL2tqkkpyDQuKn6UgYz/vxkFeQAVfSuaJVR+fUlHg0
|
||||
N4lD7/hJq7b+yYPhlN3Fvvt8M9MtRg1TLAve67CA2v4TITHB06M/ELe3y42bZuLW
|
||||
CA7ffFk=
|
||||
-----END ENCRYPTED PRIVATE KEY-----";
|
||||
rsa.ImportFromEncryptedPem(pem, "test");
|
||||
RSAParameters rsaParameters = rsa.ExportParameters(true);
|
||||
|
||||
ImportExport.AssertKeyEquals(TestData.DiminishedDPParameters, rsaParameters);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void ImportFromEncryptedPem_Pkcs8Encrypted_Byte_Simple()
|
||||
{
|
||||
using (RSA rsa = RSAFactory.Create())
|
||||
{
|
||||
string pem = @"
|
||||
-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||
MIIBvTBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQIciLWmWb33X0CAggA
|
||||
MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAECBBBVEmHhJdbi+HKzPttNjXm4BIIB
|
||||
YFejknurbot2VDXwc671A0mfA0cw/u7K44gsYXcZwAARC8j6f3lSzB0tN2kMEx/L
|
||||
TB+kpMBbfAoIPKoEc9Y4w9m3NXkQYrLRONh9AFiAnOjULHwkstQfN2ofFlolDfbH
|
||||
hAE6ga6aQJTQ8rDKTL4QkCg+s+qWlicPqs5ikSQfUz2Qiy8FKe7zZlJ0OWpT+zk7
|
||||
EYRrUSKQcEAjfNS7anlMps2ZXRc1LkLJNHZSl6h2BuFPfIKEV9REpy3Y7sH7vNZZ
|
||||
PWPa9/xM4CX/c/ommy6LqvZikUuUGc56/Hbz65SwG3voivIhOTmM28LiA6z0YXmY
|
||||
E+nr7hyinl51raM1RSHojJB22oOW+GwV7GgWYIjUgIEMDOhN10FcGNfTeC65PCXx
|
||||
5QSEe7EKVF0aHXBYB5SzMGVuxR/BqydDa26jlhVzO3LNvy9FYuqLKUslCrBCmPrt
|
||||
raZNyk8KAsLs+FJq9T2tda0=
|
||||
-----END ENCRYPTED PRIVATE KEY-----";
|
||||
rsa.ImportFromEncryptedPem(pem, Encoding.UTF8.GetBytes("test"));
|
||||
RSAParameters rsaParameters = rsa.ExportParameters(true);
|
||||
|
||||
ImportExport.AssertKeyEquals(TestData.DiminishedDPParameters, rsaParameters);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void ImportFromEncryptedPem_Pkcs8Encrypted_AmbiguousPem()
|
||||
{
|
||||
using (RSA rsa = RSAFactory.Create())
|
||||
{
|
||||
string pem = @"
|
||||
-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||
MIIBvTBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQIciLWmWb33X0CAggA
|
||||
MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAECBBBVEmHhJdbi+HKzPttNjXm4BIIB
|
||||
YFejknurbot2VDXwc671A0mfA0cw/u7K44gsYXcZwAARC8j6f3lSzB0tN2kMEx/L
|
||||
TB+kpMBbfAoIPKoEc9Y4w9m3NXkQYrLRONh9AFiAnOjULHwkstQfN2ofFlolDfbH
|
||||
hAE6ga6aQJTQ8rDKTL4QkCg+s+qWlicPqs5ikSQfUz2Qiy8FKe7zZlJ0OWpT+zk7
|
||||
EYRrUSKQcEAjfNS7anlMps2ZXRc1LkLJNHZSl6h2BuFPfIKEV9REpy3Y7sH7vNZZ
|
||||
PWPa9/xM4CX/c/ommy6LqvZikUuUGc56/Hbz65SwG3voivIhOTmM28LiA6z0YXmY
|
||||
E+nr7hyinl51raM1RSHojJB22oOW+GwV7GgWYIjUgIEMDOhN10FcGNfTeC65PCXx
|
||||
5QSEe7EKVF0aHXBYB5SzMGVuxR/BqydDa26jlhVzO3LNvy9FYuqLKUslCrBCmPrt
|
||||
raZNyk8KAsLs+FJq9T2tda0=
|
||||
-----END ENCRYPTED PRIVATE KEY-----
|
||||
-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||
MIIBsTBLBgkqhkiG9w0BBQ0wPjApBgkqhkiG9w0BBQwwHAQIcvgI1lw9LqYCAggA
|
||||
MAwGCCqGSIb3DQIJBQAwEQYFKw4DAgcECFDpLREQXt5pBIIBYOKuM5ljAvCViDL+
|
||||
nTFq7A/fI9rqdL20TMdf0wy7s43oXmsw5gCStoNEaoVToFCQWYYBRU99mK8YNFA8
|
||||
1ZJT53SDS7buJ0zX9oDltf2ByXRPI4mn2Il2HZvN2hi9ir1w8M3XoSFSurN9tC8r
|
||||
IOiGkVfK9Ll54knONewNiCNefFZFctRfVMbac5SwHokCkBMHukl0oPrpVuBE8kRo
|
||||
p7XtjM8ILtzLVz0iLqKXiNIf6kRdouCBmCn8VIQgIvPPIHD8vheMXWjN7g69P5n4
|
||||
1YI4c/acljcofmq1BBPTwvxaETrg2NHW0XMIgAxoaVP8lIIGlNk1glWTYpuMd69L
|
||||
AWvBUt33Sozc+dF0l7NGLAWL2tqkkpyDQuKn6UgYz/vxkFeQAVfSuaJVR+fUlHg0
|
||||
N4lD7/hJq7b+yYPhlN3Fvvt8M9MtRg1TLAve67CA2v4TITHB06M/ELe3y42bZuLW
|
||||
CA7ffFk=
|
||||
-----END ENCRYPTED PRIVATE KEY-----";
|
||||
byte[] passwordBytes = Encoding.UTF8.GetBytes("test");
|
||||
ArgumentException ae = AssertExtensions.Throws<ArgumentException>("input", () =>
|
||||
rsa.ImportFromEncryptedPem(pem, passwordBytes));
|
||||
Assert.Contains(AmbiguousExceptionMarker, ae.Message);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void ImportFromEncryptedPem_Pkcs8Encrypted_Byte_NoPem()
|
||||
{
|
||||
using (RSA rsa = RSAFactory.Create())
|
||||
{
|
||||
string pem = "these aren't the PEMs we're looking for.";
|
||||
byte[] passwordBytes = Encoding.UTF8.GetBytes("test");
|
||||
ArgumentException ae = AssertExtensions.Throws<ArgumentException>("input", () =>
|
||||
rsa.ImportFromEncryptedPem(pem, passwordBytes));
|
||||
Assert.Contains(NoPemExceptionMarker, ae.Message);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void ImportFromEncryptedPem_NoEncryptedPem()
|
||||
{
|
||||
using (RSA rsa = RSAFactory.Create())
|
||||
{
|
||||
string pem = @"
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAtz9Z9e6L1V4kt/8C
|
||||
mtFqhUPJbSU+VDGbk1MsQcPBR3uJ2y0vM9e5qHRYSOBqjmg7UERRHhvKNiUn4Xz0
|
||||
KzgGFQIDAQABAkEAr+byNi+cr17FpJH4MCEiPXaKnmkH4c4U52EJtL9yg2gijBrp
|
||||
Ykat3c2nWb0EGGi5aWgXxQHoi7z97/ACD4X3KQIhAPNyex6GdiBVlNPHOgInTU8a
|
||||
mARKKVHIXM0SxvxXrRl7AiEAwLI66OpSqftDTv1KUfNe6+hyoh23ggzUSYiWuVT0
|
||||
Ya8CHwiO/cUU9RIt8A2B84gf2ZfuV2nPMaSuZpTPFC/K5UsCIQCsJMzx1JuilQAN
|
||||
acPiMCuFTnRSFYAhozpmsqoLyTREqwIhAMLJlZTGjEB2N+sEazH5ToEczQzKqp7t
|
||||
9juGNbOPhoEL
|
||||
-----END PRIVATE KEY-----";
|
||||
byte[] passwordBytes = Encoding.UTF8.GetBytes("test");
|
||||
ArgumentException ae = AssertExtensions.Throws<ArgumentException>("input", () =>
|
||||
rsa.ImportFromEncryptedPem(pem, passwordBytes));
|
||||
Assert.Contains(NoPemExceptionMarker, ae.Message);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void ImportFromEncryptedPem_Pkcs8Encrypted_Char_NoPem()
|
||||
{
|
||||
using (RSA rsa = RSAFactory.Create())
|
||||
{
|
||||
string pem = "go about your business";
|
||||
string password = "test";
|
||||
ArgumentException ae = AssertExtensions.Throws<ArgumentException>("input", () =>
|
||||
rsa.ImportFromEncryptedPem(pem, password));
|
||||
Assert.Contains(NoPemExceptionMarker, ae.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private static RSAParameters ToPublic(this RSAParameters rsaParams)
|
||||
{
|
||||
return new RSAParameters
|
||||
{
|
||||
Exponent = rsaParams.Exponent,
|
||||
Modulus = rsaParams.Modulus
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -135,6 +135,9 @@ namespace System.Security.Cryptography
|
|||
protected virtual byte[] HashData(System.IO.Stream data, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { throw null; }
|
||||
public override void ImportEncryptedPkcs8PrivateKey(System.ReadOnlySpan<byte> passwordBytes, System.ReadOnlySpan<byte> source, out int bytesRead) { throw null; }
|
||||
public override void ImportEncryptedPkcs8PrivateKey(System.ReadOnlySpan<char> password, System.ReadOnlySpan<byte> source, out int bytesRead) { throw null; }
|
||||
public override void ImportFromEncryptedPem(System.ReadOnlySpan<char> input, System.ReadOnlySpan<byte> passwordBytes) { }
|
||||
public override void ImportFromEncryptedPem(System.ReadOnlySpan<char> input, System.ReadOnlySpan<char> password) { }
|
||||
public override void ImportFromPem(System.ReadOnlySpan<char> input) { }
|
||||
public abstract void ImportParameters(System.Security.Cryptography.DSAParameters parameters);
|
||||
public override void ImportPkcs8PrivateKey(System.ReadOnlySpan<byte> source, out int bytesRead) { throw null; }
|
||||
public override void ImportSubjectPublicKeyInfo(System.ReadOnlySpan<byte> source, out int bytesRead) { throw null; }
|
||||
|
@ -283,6 +286,9 @@ namespace System.Security.Cryptography
|
|||
public virtual void ImportECPrivateKey(System.ReadOnlySpan<byte> source, out int bytesRead) { throw null; }
|
||||
public override void ImportEncryptedPkcs8PrivateKey(System.ReadOnlySpan<byte> passwordBytes, System.ReadOnlySpan<byte> source, out int bytesRead) { throw null; }
|
||||
public override void ImportEncryptedPkcs8PrivateKey(System.ReadOnlySpan<char> password, System.ReadOnlySpan<byte> source, out int bytesRead) { throw null; }
|
||||
public override void ImportFromEncryptedPem(System.ReadOnlySpan<char> input, System.ReadOnlySpan<byte> passwordBytes) { }
|
||||
public override void ImportFromEncryptedPem(System.ReadOnlySpan<char> input, System.ReadOnlySpan<char> password) { }
|
||||
public override void ImportFromPem(System.ReadOnlySpan<char> input) { }
|
||||
public virtual void ImportParameters(System.Security.Cryptography.ECParameters parameters) { }
|
||||
public override void ImportPkcs8PrivateKey(System.ReadOnlySpan<byte> source, out int bytesRead) { throw null; }
|
||||
public override void ImportSubjectPublicKeyInfo(System.ReadOnlySpan<byte> source, out int bytesRead) { throw null; }
|
||||
|
@ -324,6 +330,9 @@ namespace System.Security.Cryptography
|
|||
public virtual void ImportECPrivateKey(System.ReadOnlySpan<byte> source, out int bytesRead) { throw null; }
|
||||
public override void ImportEncryptedPkcs8PrivateKey(System.ReadOnlySpan<byte> passwordBytes, System.ReadOnlySpan<byte> source, out int bytesRead) { throw null; }
|
||||
public override void ImportEncryptedPkcs8PrivateKey(System.ReadOnlySpan<char> password, System.ReadOnlySpan<byte> source, out int bytesRead) { throw null; }
|
||||
public override void ImportFromEncryptedPem(System.ReadOnlySpan<char> input, System.ReadOnlySpan<byte> passwordBytes) { }
|
||||
public override void ImportFromEncryptedPem(System.ReadOnlySpan<char> input, System.ReadOnlySpan<char> password) { }
|
||||
public override void ImportFromPem(System.ReadOnlySpan<char> input) { }
|
||||
public virtual void ImportParameters(System.Security.Cryptography.ECParameters parameters) { }
|
||||
public override void ImportPkcs8PrivateKey(System.ReadOnlySpan<byte> source, out int bytesRead) { throw null; }
|
||||
public override void ImportSubjectPublicKeyInfo(System.ReadOnlySpan<byte> source, out int bytesRead) { throw null; }
|
||||
|
@ -573,6 +582,9 @@ namespace System.Security.Cryptography
|
|||
protected virtual byte[] HashData(System.IO.Stream data, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { throw null; }
|
||||
public override void ImportEncryptedPkcs8PrivateKey(System.ReadOnlySpan<byte> passwordBytes, System.ReadOnlySpan<byte> source, out int bytesRead) { throw null; }
|
||||
public override void ImportEncryptedPkcs8PrivateKey(System.ReadOnlySpan<char> password, System.ReadOnlySpan<byte> source, out int bytesRead) { throw null; }
|
||||
public override void ImportFromEncryptedPem(System.ReadOnlySpan<char> input, System.ReadOnlySpan<byte> passwordBytes) { }
|
||||
public override void ImportFromEncryptedPem(System.ReadOnlySpan<char> input, System.ReadOnlySpan<char> password) { }
|
||||
public override void ImportFromPem(System.ReadOnlySpan<char> input) { }
|
||||
public abstract void ImportParameters(System.Security.Cryptography.RSAParameters parameters);
|
||||
public override void ImportPkcs8PrivateKey(System.ReadOnlySpan<byte> source, out int bytesRead) { throw null; }
|
||||
public virtual void ImportRSAPrivateKey(System.ReadOnlySpan<byte> source, out int bytesRead) { throw null; }
|
||||
|
|
|
@ -81,6 +81,15 @@
|
|||
<data name="ArgumentNull_Buffer" xml:space="preserve">
|
||||
<value>Buffer cannot be null.</value>
|
||||
</data>
|
||||
<data name="Argument_PemImport_NoPemFound" xml:space="preserve">
|
||||
<value>No supported key formats were found. Check that the input represents the contents of a PEM-encoded key file, not the path to such a file.</value>
|
||||
</data>
|
||||
<data name="Argument_PemImport_AmbiguousPem" xml:space="preserve">
|
||||
<value>The input contains multiple keys, but only one key can be imported.</value>
|
||||
</data>
|
||||
<data name="Argument_PemImport_EncryptedPem" xml:space="preserve">
|
||||
<value>An encrypted key was found, but no password was provided. Use ImportFromEncryptedPem to import this key.</value>
|
||||
</data>
|
||||
<data name="Arg_CryptographyException" xml:space="preserve">
|
||||
<value>Error occurred during a cryptographic operation.</value>
|
||||
</data>
|
||||
|
@ -320,7 +329,7 @@
|
|||
</data>
|
||||
<data name="NotSupported_Method" xml:space="preserve">
|
||||
<value>Method not supported.</value>
|
||||
</data>
|
||||
</data>
|
||||
<data name="NotSupported_SubclassOverride" xml:space="preserve">
|
||||
<value>Method not supported. Derived class must override.</value>
|
||||
</data>
|
||||
|
|
|
@ -98,6 +98,9 @@
|
|||
<Compile Include="$(CommonPath)Internal\Cryptography\HashProvider.cs">
|
||||
<Link>Internal\Cryptography\HashProvider.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)Internal\Cryptography\PemKeyImportHelpers.cs">
|
||||
<Link>Common\Internal\Cryptography\PemKeyImportHelpers.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)Internal\Cryptography\UniversalCryptoTransform.cs">
|
||||
<Link>Internal\Cryptography\UniversalCryptoTransform.cs</Link>
|
||||
</Compile>
|
||||
|
@ -134,6 +137,9 @@
|
|||
<Compile Include="$(CommonPath)System\Security\Cryptography\PasswordBasedEncryption.cs">
|
||||
<Link>Common\System\Security\Cryptography\PasswordBasedEncryption.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)System\Security\Cryptography\PemLabels.cs">
|
||||
<Link>Common\System\Security\Cryptography\PemLabels.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)System\Security\Cryptography\Pkcs12Kdf.cs">
|
||||
<Link>Common\System\Security\Cryptography\Pkcs12Kdf.cs</Link>
|
||||
</Compile>
|
||||
|
|
|
@ -1125,5 +1125,197 @@ namespace System.Security.Cryptography
|
|||
throw new ArgumentOutOfRangeException(nameof(signatureFormat));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Imports an RFC 7468 PEM-encoded key, replacing the keys for this object.
|
||||
/// </summary>
|
||||
/// <param name="input">The PEM text of the key to import.</param>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// <para>
|
||||
/// <paramref name="input"/> does not contain a PEM-encoded key with a recognized label.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// <paramref name="input"/> contains multiple PEM-encoded keys with a recognized label.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// <paramref name="input"/> contains an encrypted PEM-encoded key.
|
||||
/// </para>
|
||||
/// </exception>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// Unsupported or malformed PEM-encoded objects will be ignored. If multiple supported PEM labels
|
||||
/// are found, an exception is raised to prevent importing a key when
|
||||
/// the key is ambiguous.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// This method supports the following PEM labels:
|
||||
/// <list type="bullet">
|
||||
/// <item><description>PUBLIC KEY</description></item>
|
||||
/// <item><description>PRIVATE KEY</description></item>
|
||||
/// </list>
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public override void ImportFromPem(ReadOnlySpan<char> input)
|
||||
{
|
||||
PemKeyImportHelpers.ImportPem(input, label => {
|
||||
if (label.SequenceEqual(PemLabels.Pkcs8PrivateKey))
|
||||
{
|
||||
return ImportPkcs8PrivateKey;
|
||||
}
|
||||
else if (label.SequenceEqual(PemLabels.SpkiPublicKey))
|
||||
{
|
||||
return ImportSubjectPublicKeyInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Imports an encrypted RFC 7468 PEM-encoded private key, replacing the keys for this object.
|
||||
/// </summary>
|
||||
/// <param name="input">The PEM text of the encrypted key to import.</param>
|
||||
/// <param name="password">
|
||||
/// The password to use for decrypting the key material.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// <para>
|
||||
/// <paramref name="input"/> does not contain a PEM-encoded key with a recognized label.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// <paramref name="input"/> contains multiple PEM-encoded keys with a recognized label.
|
||||
/// </para>
|
||||
/// </exception>
|
||||
/// <exception cref="CryptographicException">
|
||||
/// <para>
|
||||
/// The password is incorrect.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The base-64 decoded contents of the PEM text from <paramref name="input" />
|
||||
/// do not represent an ASN.1-BER-encoded PKCS#8 EncryptedPrivateKeyInfo structure.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The base-64 decoded contents of the PEM text from <paramref name="input" />
|
||||
/// indicate the key is for an algorithm other than the algorithm
|
||||
/// represented by this instance.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The base-64 decoded contents of the PEM text from <paramref name="input" />
|
||||
/// represent the key in a format that is not supported.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The algorithm-specific key import failed.
|
||||
/// </para>
|
||||
/// </exception>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// When the base-64 decoded contents of <paramref name="input" /> indicate an algorithm that uses PBKDF1
|
||||
/// (Password-Based Key Derivation Function 1) or PBKDF2 (Password-Based Key Derivation Function 2),
|
||||
/// the password is converted to bytes via the UTF-8 encoding.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Unsupported or malformed PEM-encoded objects will be ignored. If multiple supported PEM labels
|
||||
/// are found, an exception is thrown to prevent importing a key when
|
||||
/// the key is ambiguous.
|
||||
/// </para>
|
||||
/// <para>This method supports the <c>ENCRYPTED PRIVATE KEY</c> PEM label.</para>
|
||||
/// </remarks>
|
||||
public override void ImportFromEncryptedPem(ReadOnlySpan<char> input, ReadOnlySpan<char> password)
|
||||
{
|
||||
PemKeyImportHelpers.ImportEncryptedPem<char>(input, password, ImportEncryptedPkcs8PrivateKey);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Imports an encrypted RFC 7468 PEM-encoded private key, replacing the keys for this object.
|
||||
/// </summary>
|
||||
/// <param name="input">The PEM text of the encrypted key to import.</param>
|
||||
/// <param name="passwordBytes">
|
||||
/// The bytes to use as a password when decrypting the key material.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// <para>
|
||||
/// <paramref name="input"/> does not contain a PEM-encoded key with a recognized label.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// <paramref name="input"/> contains multiple PEM-encoded keys with a recognized label.
|
||||
/// </para>
|
||||
/// </exception>
|
||||
/// <exception cref="CryptographicException">
|
||||
/// <para>
|
||||
/// The password is incorrect.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The base-64 decoded contents of the PEM text from <paramref name="input" />
|
||||
/// do not represent an ASN.1-BER-encoded PKCS#8 EncryptedPrivateKeyInfo structure.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The base-64 decoded contents of the PEM text from <paramref name="input" />
|
||||
/// indicate the key is for an algorithm other than the algorithm
|
||||
/// represented by this instance.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The base-64 decoded contents of the PEM text from <paramref name="input" />
|
||||
/// represent the key in a format that is not supported.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The algorithm-specific key import failed.
|
||||
/// </para>
|
||||
/// </exception>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// The password bytes are passed directly into the Key Derivation Function (KDF)
|
||||
/// used by the algorithm indicated by <c>pbeParameters</c>. This enables compatibility
|
||||
/// with other systems which use a text encoding other than UTF-8 when processing
|
||||
/// passwords with PBKDF2 (Password-Based Key Derivation Function 2).
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Unsupported or malformed PEM-encoded objects will be ignored. If multiple supported PEM labels
|
||||
/// are found, an exception is thrown to prevent importing a key when
|
||||
/// the key is ambiguous.
|
||||
/// </para>
|
||||
/// <para>This method supports the <c>ENCRYPTED PRIVATE KEY</c> PEM label.</para>
|
||||
/// </remarks>
|
||||
public override void ImportFromEncryptedPem(ReadOnlySpan<char> input, ReadOnlySpan<byte> passwordBytes)
|
||||
{
|
||||
PemKeyImportHelpers.ImportEncryptedPem<byte>(input, passwordBytes, ImportEncryptedPkcs8PrivateKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using Internal.Cryptography;
|
||||
using System.Security.Cryptography.Asn1;
|
||||
|
||||
namespace System.Security.Cryptography
|
||||
|
@ -433,5 +434,202 @@ namespace System.Security.Cryptography
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Imports an RFC 7468 PEM-encoded key, replacing the keys for this object.
|
||||
/// </summary>
|
||||
/// <param name="input">The PEM text of the key to import.</param>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// <para>
|
||||
/// <paramref name="input"/> does not contain a PEM-encoded key with a recognized label.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// <paramref name="input"/> contains multiple PEM-encoded keys with a recognized label.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// <paramref name="input"/> contains an encrypted PEM-encoded key.
|
||||
/// </para>
|
||||
/// </exception>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// Unsupported or malformed PEM-encoded objects will be ignored. If multiple supported PEM labels
|
||||
/// are found, an exception is raised to prevent importing a key when
|
||||
/// the key is ambiguous.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// This method supports the following PEM labels:
|
||||
/// <list type="bullet">
|
||||
/// <item><description>PUBLIC KEY</description></item>
|
||||
/// <item><description>PRIVATE KEY</description></item>
|
||||
/// <item><description>EC PRIVATE KEY</description></item>
|
||||
/// </list>
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public override void ImportFromPem(ReadOnlySpan<char> input)
|
||||
{
|
||||
PemKeyImportHelpers.ImportPem(input, label => {
|
||||
if (label.SequenceEqual(PemLabels.Pkcs8PrivateKey))
|
||||
{
|
||||
return ImportPkcs8PrivateKey;
|
||||
}
|
||||
else if (label.SequenceEqual(PemLabels.SpkiPublicKey))
|
||||
{
|
||||
return ImportSubjectPublicKeyInfo;
|
||||
}
|
||||
else if (label.SequenceEqual(PemLabels.EcPrivateKey))
|
||||
{
|
||||
return ImportECPrivateKey;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Imports an encrypted RFC 7468 PEM-encoded private key, replacing the keys for this object.
|
||||
/// </summary>
|
||||
/// <param name="input">The PEM text of the encrypted key to import.</param>
|
||||
/// <param name="password">
|
||||
/// The password to use for decrypting the key material.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// <para>
|
||||
/// <paramref name="input"/> does not contain a PEM-encoded key with a recognized label.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// <paramref name="input"/> contains multiple PEM-encoded keys with a recognized label.
|
||||
/// </para>
|
||||
/// </exception>
|
||||
/// <exception cref="CryptographicException">
|
||||
/// <para>
|
||||
/// The password is incorrect.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The base-64 decoded contents of the PEM text from <paramref name="input" />
|
||||
/// do not represent an ASN.1-BER-encoded PKCS#8 EncryptedPrivateKeyInfo structure.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The base-64 decoded contents of the PEM text from <paramref name="input" />
|
||||
/// indicate the key is for an algorithm other than the algorithm
|
||||
/// represented by this instance.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The base-64 decoded contents of the PEM text from <paramref name="input" />
|
||||
/// represent the key in a format that is not supported.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The algorithm-specific key import failed.
|
||||
/// </para>
|
||||
/// </exception>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// When the base-64 decoded contents of <paramref name="input" /> indicate an algorithm that uses PBKDF1
|
||||
/// (Password-Based Key Derivation Function 1) or PBKDF2 (Password-Based Key Derivation Function 2),
|
||||
/// the password is converted to bytes via the UTF-8 encoding.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Unsupported or malformed PEM-encoded objects will be ignored. If multiple supported PEM labels
|
||||
/// are found, an exception is thrown to prevent importing a key when
|
||||
/// the key is ambiguous.
|
||||
/// </para>
|
||||
/// <para>This method supports the <c>ENCRYPTED PRIVATE KEY</c> PEM label.</para>
|
||||
/// </remarks>
|
||||
public override void ImportFromEncryptedPem(ReadOnlySpan<char> input, ReadOnlySpan<char> password)
|
||||
{
|
||||
PemKeyImportHelpers.ImportEncryptedPem<char>(input, password, ImportEncryptedPkcs8PrivateKey);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Imports an encrypted RFC 7468 PEM-encoded private key, replacing the keys for this object.
|
||||
/// </summary>
|
||||
/// <param name="input">The PEM text of the encrypted key to import.</param>
|
||||
/// <param name="passwordBytes">
|
||||
/// The bytes to use as a password when decrypting the key material.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// <para>
|
||||
/// <paramref name="input"/> does not contain a PEM-encoded key with a recognized label.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// <paramref name="input"/> contains multiple PEM-encoded keys with a recognized label.
|
||||
/// </para>
|
||||
/// </exception>
|
||||
/// <exception cref="CryptographicException">
|
||||
/// <para>
|
||||
/// The password is incorrect.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The base-64 decoded contents of the PEM text from <paramref name="input" />
|
||||
/// do not represent an ASN.1-BER-encoded PKCS#8 EncryptedPrivateKeyInfo structure.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The base-64 decoded contents of the PEM text from <paramref name="input" />
|
||||
/// indicate the key is for an algorithm other than the algorithm
|
||||
/// represented by this instance.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The base-64 decoded contents of the PEM text from <paramref name="input" />
|
||||
/// represent the key in a format that is not supported.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The algorithm-specific key import failed.
|
||||
/// </para>
|
||||
/// </exception>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// The password bytes are passed directly into the Key Derivation Function (KDF)
|
||||
/// used by the algorithm indicated by <c>pbeParameters</c>. This enables compatibility
|
||||
/// with other systems which use a text encoding other than UTF-8 when processing
|
||||
/// passwords with PBKDF2 (Password-Based Key Derivation Function 2).
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Unsupported or malformed PEM-encoded objects will be ignored. If multiple supported PEM labels
|
||||
/// are found, an exception is thrown to prevent importing a key when
|
||||
/// the key is ambiguous.
|
||||
/// </para>
|
||||
/// <para>This method supports the <c>ENCRYPTED PRIVATE KEY</c> PEM label.</para>
|
||||
/// </remarks>
|
||||
public override void ImportFromEncryptedPem(ReadOnlySpan<char> input, ReadOnlySpan<byte> passwordBytes)
|
||||
{
|
||||
PemKeyImportHelpers.ImportEncryptedPem<byte>(input, passwordBytes, ImportEncryptedPkcs8PrivateKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1298,5 +1298,202 @@ namespace System.Security.Cryptography
|
|||
throw new ArgumentOutOfRangeException(nameof(signatureFormat));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Imports an RFC 7468 PEM-encoded key, replacing the keys for this object.
|
||||
/// </summary>
|
||||
/// <param name="input">The PEM text of the key to import.</param>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// <para>
|
||||
/// <paramref name="input"/> does not contain a PEM-encoded key with a recognized label.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// <paramref name="input"/> contains multiple PEM-encoded keys with a recognized label.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// <paramref name="input"/> contains an encrypted PEM-encoded key.
|
||||
/// </para>
|
||||
/// </exception>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// Unsupported or malformed PEM-encoded objects will be ignored. If multiple supported PEM labels
|
||||
/// are found, an exception is raised to prevent importing a key when
|
||||
/// the key is ambiguous.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// This method supports the following PEM labels:
|
||||
/// <list type="bullet">
|
||||
/// <item><description>PUBLIC KEY</description></item>
|
||||
/// <item><description>PRIVATE KEY</description></item>
|
||||
/// <item><description>EC PRIVATE KEY</description></item>
|
||||
/// </list>
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public override void ImportFromPem(ReadOnlySpan<char> input)
|
||||
{
|
||||
PemKeyImportHelpers.ImportPem(input, label => {
|
||||
if (label.SequenceEqual(PemLabels.Pkcs8PrivateKey))
|
||||
{
|
||||
return ImportPkcs8PrivateKey;
|
||||
}
|
||||
else if (label.SequenceEqual(PemLabels.SpkiPublicKey))
|
||||
{
|
||||
return ImportSubjectPublicKeyInfo;
|
||||
}
|
||||
else if (label.SequenceEqual(PemLabels.EcPrivateKey))
|
||||
{
|
||||
return ImportECPrivateKey;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Imports an encrypted RFC 7468 PEM-encoded private key, replacing the keys for this object.
|
||||
/// </summary>
|
||||
/// <param name="input">The PEM text of the encrypted key to import.</param>
|
||||
/// <param name="password">
|
||||
/// The password to use for decrypting the key material.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// <para>
|
||||
/// <paramref name="input"/> does not contain a PEM-encoded key with a recognized label.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// <paramref name="input"/> contains multiple PEM-encoded keys with a recognized label.
|
||||
/// </para>
|
||||
/// </exception>
|
||||
/// <exception cref="CryptographicException">
|
||||
/// <para>
|
||||
/// The password is incorrect.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The base-64 decoded contents of the PEM text from <paramref name="input" />
|
||||
/// do not represent an ASN.1-BER-encoded PKCS#8 EncryptedPrivateKeyInfo structure.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The base-64 decoded contents of the PEM text from <paramref name="input" />
|
||||
/// indicate the key is for an algorithm other than the algorithm
|
||||
/// represented by this instance.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The base-64 decoded contents of the PEM text from <paramref name="input" />
|
||||
/// represent the key in a format that is not supported.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The algorithm-specific key import failed.
|
||||
/// </para>
|
||||
/// </exception>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// When the base-64 decoded contents of <paramref name="input" /> indicate an algorithm that uses PBKDF1
|
||||
/// (Password-Based Key Derivation Function 1) or PBKDF2 (Password-Based Key Derivation Function 2),
|
||||
/// the password is converted to bytes via the UTF-8 encoding.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Unsupported or malformed PEM-encoded objects will be ignored. If multiple supported PEM labels
|
||||
/// are found, an exception is thrown to prevent importing a key when
|
||||
/// the key is ambiguous.
|
||||
/// </para>
|
||||
/// <para>This method supports the <c>ENCRYPTED PRIVATE KEY</c> PEM label.</para>
|
||||
/// </remarks>
|
||||
public override void ImportFromEncryptedPem(ReadOnlySpan<char> input, ReadOnlySpan<char> password)
|
||||
{
|
||||
PemKeyImportHelpers.ImportEncryptedPem<char>(input, password, ImportEncryptedPkcs8PrivateKey);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Imports an encrypted RFC 7468 PEM-encoded private key, replacing the keys for this object.
|
||||
/// </summary>
|
||||
/// <param name="input">The PEM text of the encrypted key to import.</param>
|
||||
/// <param name="passwordBytes">
|
||||
/// The bytes to use as a password when decrypting the key material.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// <para>
|
||||
/// <paramref name="input"/> does not contain a PEM-encoded key with a recognized label.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// <paramref name="input"/> contains multiple PEM-encoded keys with a recognized label.
|
||||
/// </para>
|
||||
/// </exception>
|
||||
/// <exception cref="CryptographicException">
|
||||
/// <para>
|
||||
/// The password is incorrect.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The base-64 decoded contents of the PEM text from <paramref name="input" />
|
||||
/// do not represent an ASN.1-BER-encoded PKCS#8 EncryptedPrivateKeyInfo structure.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The base-64 decoded contents of the PEM text from <paramref name="input" />
|
||||
/// indicate the key is for an algorithm other than the algorithm
|
||||
/// represented by this instance.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The base-64 decoded contents of the PEM text from <paramref name="input" />
|
||||
/// represent the key in a format that is not supported.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The algorithm-specific key import failed.
|
||||
/// </para>
|
||||
/// </exception>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// The password bytes are passed directly into the Key Derivation Function (KDF)
|
||||
/// used by the algorithm indicated by <c>pbeParameters</c>. This enables compatibility
|
||||
/// with other systems which use a text encoding other than UTF-8 when processing
|
||||
/// passwords with PBKDF2 (Password-Based Key Derivation Function 2).
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Unsupported or malformed PEM-encoded objects will be ignored. If multiple supported PEM labels
|
||||
/// are found, an exception is thrown to prevent importing a key when
|
||||
/// the key is ambiguous.
|
||||
/// </para>
|
||||
/// <para>This method supports the <c>ENCRYPTED PRIVATE KEY</c> PEM label.</para>
|
||||
/// </remarks>
|
||||
public override void ImportFromEncryptedPem(ReadOnlySpan<char> input, ReadOnlySpan<byte> passwordBytes)
|
||||
{
|
||||
PemKeyImportHelpers.ImportEncryptedPem<byte>(input, passwordBytes, ImportEncryptedPkcs8PrivateKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -625,6 +625,208 @@ namespace System.Security.Cryptography
|
|||
bytesRead = localRead;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Imports an RFC 7468 PEM-encoded key, replacing the keys for this object.
|
||||
/// </summary>
|
||||
/// <param name="input">The PEM text of the key to import.</param>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// <para>
|
||||
/// <paramref name="input"/> does not contain a PEM-encoded key with a recognized label.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// <paramref name="input"/> contains multiple PEM-encoded keys with a recognized label.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// <paramref name="input"/> contains an encrypted PEM-encoded key.
|
||||
/// </para>
|
||||
/// </exception>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// Unsupported or malformed PEM-encoded objects will be ignored. If multiple supported PEM labels
|
||||
/// are found, an exception is raised to prevent importing a key when
|
||||
/// the key is ambiguous.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// This method supports the following PEM labels:
|
||||
/// <list type="bullet">
|
||||
/// <item><description>PUBLIC KEY</description></item>
|
||||
/// <item><description>PRIVATE KEY</description></item>
|
||||
/// <item><description>RSA PRIVATE KEY</description></item>
|
||||
/// <item><description>RSA PUBLIC KEY</description></item>
|
||||
/// </list>
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public override void ImportFromPem(ReadOnlySpan<char> input)
|
||||
{
|
||||
PemKeyImportHelpers.ImportPem(input, label => {
|
||||
if (label.SequenceEqual(PemLabels.RsaPrivateKey))
|
||||
{
|
||||
return ImportRSAPrivateKey;
|
||||
}
|
||||
else if (label.SequenceEqual(PemLabels.Pkcs8PrivateKey))
|
||||
{
|
||||
return ImportPkcs8PrivateKey;
|
||||
}
|
||||
else if (label.SequenceEqual(PemLabels.RsaPublicKey))
|
||||
{
|
||||
return ImportRSAPublicKey;
|
||||
}
|
||||
else if (label.SequenceEqual(PemLabels.SpkiPublicKey))
|
||||
{
|
||||
return ImportSubjectPublicKeyInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Imports an encrypted RFC 7468 PEM-encoded private key, replacing the keys for this object.
|
||||
/// </summary>
|
||||
/// <param name="input">The PEM text of the encrypted key to import.</param>
|
||||
/// <param name="password">
|
||||
/// The password to use for decrypting the key material.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// <para>
|
||||
/// <paramref name="input"/> does not contain a PEM-encoded key with a recognized label.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// <paramref name="input"/> contains multiple PEM-encoded keys with a recognized label.
|
||||
/// </para>
|
||||
/// </exception>
|
||||
/// <exception cref="CryptographicException">
|
||||
/// <para>
|
||||
/// The password is incorrect.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The base-64 decoded contents of the PEM text from <paramref name="input" />
|
||||
/// do not represent an ASN.1-BER-encoded PKCS#8 EncryptedPrivateKeyInfo structure.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The base-64 decoded contents of the PEM text from <paramref name="input" />
|
||||
/// indicate the key is for an algorithm other than the algorithm
|
||||
/// represented by this instance.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The base-64 decoded contents of the PEM text from <paramref name="input" />
|
||||
/// represent the key in a format that is not supported.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The algorithm-specific key import failed.
|
||||
/// </para>
|
||||
/// </exception>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// When the base-64 decoded contents of <paramref name="input" /> indicate an algorithm that uses PBKDF1
|
||||
/// (Password-Based Key Derivation Function 1) or PBKDF2 (Password-Based Key Derivation Function 2),
|
||||
/// the password is converted to bytes via the UTF-8 encoding.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Unsupported or malformed PEM-encoded objects will be ignored. If multiple supported PEM labels
|
||||
/// are found, an exception is thrown to prevent importing a key when
|
||||
/// the key is ambiguous.
|
||||
/// </para>
|
||||
/// <para>This method supports the <c>ENCRYPTED PRIVATE KEY</c> PEM label.</para>
|
||||
/// </remarks>
|
||||
public override void ImportFromEncryptedPem(ReadOnlySpan<char> input, ReadOnlySpan<char> password)
|
||||
{
|
||||
PemKeyImportHelpers.ImportEncryptedPem<char>(input, password, ImportEncryptedPkcs8PrivateKey);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Imports an encrypted RFC 7468 PEM-encoded private key, replacing the keys for this object.
|
||||
/// </summary>
|
||||
/// <param name="input">The PEM text of the encrypted key to import.</param>
|
||||
/// <param name="passwordBytes">
|
||||
/// The bytes to use as a password when decrypting the key material.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// <para>
|
||||
/// <paramref name="input"/> does not contain a PEM-encoded key with a recognized label.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// <paramref name="input"/> contains multiple PEM-encoded keys with a recognized label.
|
||||
/// </para>
|
||||
/// </exception>
|
||||
/// <exception cref="CryptographicException">
|
||||
/// <para>
|
||||
/// The password is incorrect.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The base-64 decoded contents of the PEM text from <paramref name="input" />
|
||||
/// do not represent an ASN.1-BER-encoded PKCS#8 EncryptedPrivateKeyInfo structure.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The base-64 decoded contents of the PEM text from <paramref name="input" />
|
||||
/// indicate the key is for an algorithm other than the algorithm
|
||||
/// represented by this instance.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The base-64 decoded contents of the PEM text from <paramref name="input" />
|
||||
/// represent the key in a format that is not supported.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The algorithm-specific key import failed.
|
||||
/// </para>
|
||||
/// </exception>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// The password bytes are passed directly into the Key Derivation Function (KDF)
|
||||
/// used by the algorithm indicated by <c>pbeParameters</c>. This enables compatibility
|
||||
/// with other systems which use a text encoding other than UTF-8 when processing
|
||||
/// passwords with PBKDF2 (Password-Based Key Derivation Function 2).
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Unsupported or malformed PEM-encoded objects will be ignored. If multiple supported PEM labels
|
||||
/// are found, an exception is thrown to prevent importing a key when
|
||||
/// the key is ambiguous.
|
||||
/// </para>
|
||||
/// <para>This method supports the <c>ENCRYPTED PRIVATE KEY</c> PEM label.</para>
|
||||
/// </remarks>
|
||||
public override void ImportFromEncryptedPem(ReadOnlySpan<char> input, ReadOnlySpan<byte> passwordBytes)
|
||||
{
|
||||
PemKeyImportHelpers.ImportEncryptedPem<byte>(input, passwordBytes, ImportEncryptedPkcs8PrivateKey);
|
||||
}
|
||||
|
||||
private static void ClearPrivateParameters(in RSAParameters rsaParameters)
|
||||
{
|
||||
CryptographicOperations.ZeroMemory(rsaParameters.D);
|
||||
|
|
|
@ -141,15 +141,24 @@
|
|||
<Compile Include="$(CommonTestPath)System\Security\Cryptography\AlgorithmImplementations\DSA\DSAKeyFileTests.cs">
|
||||
<Link>CommonTest\System\Security\Cryptography\AlgorithmImplementations\DSA\DSAKeyFileTests.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonTestPath)System\Security\Cryptography\AlgorithmImplementations\DSA\DSAKeyPemTests.cs">
|
||||
<Link>CommonTest\System\Security\Cryptography\AlgorithmImplementations\DSA\DSAKeyPemTests.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonTestPath)System\Security\Cryptography\AlgorithmImplementations\EC\ECKeyFileTests.cs">
|
||||
<Link>CommonTest\System\Security\Cryptography\AlgorithmImplementations\EC\ECKeyFileTests.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonTestPath)System\Security\Cryptography\AlgorithmImplementations\EC\ECKeyFileTests.LimitedPrivate.cs">
|
||||
<Link>CommonTest\System\Security\Cryptography\AlgorithmImplementations\EC\ECKeyFileTests.LimitedPrivate.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonTestPath)System\Security\Cryptography\AlgorithmImplementations\EC\ECKeyPemTests.cs">
|
||||
<Link>CommonTest\System\Security\Cryptography\AlgorithmImplementations\EC\ECKeyPemTests.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonTestPath)System\Security\Cryptography\AlgorithmImplementations\ECDiffieHellman\ECDhKeyFileTests.cs">
|
||||
<Link>CommonTest\System\Security\Cryptography\AlgorithmImplementations\ECDiffieHellman\ECDhKeyFileTests.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonTestPath)System\Security\Cryptography\AlgorithmImplementations\ECDiffieHellman\ECDiffieHellmanKeyPemTests.cs">
|
||||
<Link>CommonTest\System\Security\Cryptography\AlgorithmImplementations\ECDiffieHellman\ECDiffieHellmanKeyPemTests.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonTestPath)System\Security\Cryptography\AlgorithmImplementations\ECDiffieHellman\ECDiffieHellmanFactory.cs">
|
||||
<Link>CommonTest\System\Security\Cryptography\AlgorithmImplementations\ECDiffieHellman\ECDiffieHellmanFactory.cs</Link>
|
||||
</Compile>
|
||||
|
@ -177,9 +186,15 @@
|
|||
<Compile Include="$(CommonTestPath)System\Security\Cryptography\AlgorithmImplementations\ECDsa\ECDsaKeyFileTests.cs">
|
||||
<Link>CommonTest\System\Security\Cryptography\AlgorithmImplementations\ECDsa\ECDsaKeyFileTests.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonTestPath)System\Security\Cryptography\AlgorithmImplementations\ECDsa\ECDsaKeyPemTests.cs">
|
||||
<Link>CommonTest\System\Security\Cryptography\AlgorithmImplementations\ECDsa\ECDsaKeyPemTests.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonTestPath)System\Security\Cryptography\AlgorithmImplementations\RSA\RSAKeyFileTests.cs">
|
||||
<Link>CommonTest\System\Security\Cryptography\AlgorithmImplementations\RSA\RSAKeyFileTests.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonTestPath)System\Security\Cryptography\AlgorithmImplementations\RSA\RSAKeyPemTests.cs">
|
||||
<Link>CommonTest\System\Security\Cryptography\AlgorithmImplementations\RSA\RSAKeyPemTests.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="AesManagedTests.cs" />
|
||||
<Compile Include="AsymmetricSignatureFormatterTests.cs" />
|
||||
<Compile Include="BlockSizeValueTests.cs" />
|
||||
|
@ -283,4 +298,4 @@
|
|||
<Compile Include="AesGcmTests.cs" />
|
||||
<Compile Include="HKDFTests.cs" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -117,6 +117,9 @@
|
|||
<Compile Include="$(CommonTestPath)System\Security\Cryptography\AlgorithmImplementations\DSA\DSAKeyFileTests.cs">
|
||||
<Link>CommonTest\System\Security\Cryptography\AlgorithmImplementations\DSA\DSAKeyFileTests.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonTestPath)System\Security\Cryptography\AlgorithmImplementations\DSA\DSAKeyPemTests.cs">
|
||||
<Link>CommonTest\System\Security\Cryptography\AlgorithmImplementations\DSA\DSAKeyPemTests.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonTestPath)System\Security\Cryptography\AlgorithmImplementations\DSA\DSASignatureFormatter.cs">
|
||||
<Link>CommonTest\System\Security\Cryptography\AlgorithmImplementations\DSA\DSASignatureFormatter.cs</Link>
|
||||
</Compile>
|
||||
|
@ -138,15 +141,24 @@
|
|||
<Compile Include="$(CommonTestPath)System\Security\Cryptography\AlgorithmImplementations\EC\ECKeyFileTests.LimitedPrivate.cs">
|
||||
<Link>CommonTest\System\Security\Cryptography\AlgorithmImplementations\EC\ECKeyFileTests.LimitedPrivate.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonTestPath)System\Security\Cryptography\AlgorithmImplementations\EC\ECKeyPemTests.cs">
|
||||
<Link>CommonTest\System\Security\Cryptography\AlgorithmImplementations\EC\ECKeyPemTests.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonTestPath)System\Security\Cryptography\AlgorithmImplementations\ECDiffieHellman\ECDhKeyFileTests.cs">
|
||||
<Link>CommonTest\System\Security\Cryptography\AlgorithmImplementations\ECDiffieHellman\ECDhKeyFileTests.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonTestPath)System\Security\Cryptography\AlgorithmImplementations\ECDiffieHellman\ECDiffieHellmanKeyPemTests.cs">
|
||||
<Link>CommonTest\System\Security\Cryptography\AlgorithmImplementations\ECDiffieHellman\ECDiffieHellmanKeyPemTests.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonTestPath)System\Security\Cryptography\AlgorithmImplementations\ECDsa\ECDsaTests.netcoreapp.cs">
|
||||
<Link>CommonTest\System\Security\Cryptography\AlgorithmImplementations\ECDsa\ECDsaTests.netcoreapp.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonTestPath)System\Security\Cryptography\AlgorithmImplementations\ECDsa\ECDsaKeyFileTests.cs">
|
||||
<Link>CommonTest\System\Security\Cryptography\AlgorithmImplementations\ECDsa\ECDsaKeyFileTests.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonTestPath)System\Security\Cryptography\AlgorithmImplementations\ECDsa\ECDsaKeyPemTests.cs">
|
||||
<Link>CommonTest\System\Security\Cryptography\AlgorithmImplementations\ECDsa\ECDsaKeyPemTests.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonTestPath)System\Security\Cryptography\AlgorithmImplementations\ECDsa\ECDsaSignatureFormatTests.cs">
|
||||
<Link>CommonTest\System\Security\Cryptography\AlgorithmImplementations\ECDsa\ECDsaSignatureFormatTests.cs</Link>
|
||||
</Compile>
|
||||
|
@ -162,6 +174,9 @@
|
|||
<Compile Include="$(CommonTestPath)System\Security\Cryptography\AlgorithmImplementations\RSA\RSAKeyFileTests.cs">
|
||||
<Link>CommonTest\System\Security\Cryptography\AlgorithmImplementations\RSA\RSAKeyFileTests.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonTestPath)System\Security\Cryptography\AlgorithmImplementations\RSA\RSAKeyPemTests.cs">
|
||||
<Link>CommonTest\System\Security\Cryptography\AlgorithmImplementations\RSA\RSAKeyPemTests.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonTestPath)System\Security\Cryptography\AlgorithmImplementations\RSA\RSASignatureFormatter.cs">
|
||||
<Link>CommonTest\System\Security\Cryptography\AlgorithmImplementations\RSA\RSASignatureFormatter.cs</Link>
|
||||
</Compile>
|
||||
|
|
|
@ -51,6 +51,9 @@ namespace System.Security.Cryptography.Csp.Tests
|
|||
// DecryptValue and EncryptValue throw PNSE in base class, so they don't need to be checked.
|
||||
"DecryptValue",
|
||||
"EncryptValue",
|
||||
// PEM Import/Export defers to Import methods.
|
||||
"ImportFromPem",
|
||||
"ImportFromEncryptedPem",
|
||||
// Key Import/Export defers to ImportParameters/ExportParameters (covered by *KeyFileTests)
|
||||
"ImportRSAPrivateKey",
|
||||
"ImportRSAPublicKey",
|
||||
|
|
|
@ -75,6 +75,9 @@
|
|||
<Compile Include="$(CommonTestPath)System\Security\Cryptography\AlgorithmImplementations\DSA\DSAKeyFileTests.cs">
|
||||
<Link>CommonTest\System\Security\Cryptography\AlgorithmImplementations\DSA\DSAKeyFileTests.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonTestPath)System\Security\Cryptography\AlgorithmImplementations\DSA\DSAKeyPemTests.cs">
|
||||
<Link>CommonTest\System\Security\Cryptography\AlgorithmImplementations\DSA\DSAKeyPemTests.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonTestPath)System\Security\Cryptography\AlgorithmImplementations\DSA\DSAKeyGeneration.cs">
|
||||
<Link>CommonTest\System\Security\Cryptography\AlgorithmImplementations\DSA\DSAKeyGeneration.cs</Link>
|
||||
</Compile>
|
||||
|
@ -117,6 +120,9 @@
|
|||
<Compile Include="$(CommonTestPath)System\Security\Cryptography\AlgorithmImplementations\RSA\RSAKeyFileTests.cs">
|
||||
<Link>CommonTest\System\Security\Cryptography\AlgorithmImplementations\RSA\RSAKeyFileTests.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonTestPath)System\Security\Cryptography\AlgorithmImplementations\RSA\RSAKeyPemTests.cs">
|
||||
<Link>CommonTest\System\Security\Cryptography\AlgorithmImplementations\RSA\RSAKeyPemTests.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonTestPath)System\Security\Cryptography\AlgorithmImplementations\RSA\SignVerify.netcoreapp.cs">
|
||||
<Link>CommonTest\System\Security\Cryptography\AlgorithmImplementations\RSA\SignVerify.netcoreapp.cs</Link>
|
||||
</Compile>
|
||||
|
|
|
@ -140,18 +140,30 @@
|
|||
<Compile Include="$(CommonTestPath)System\Security\Cryptography\AlgorithmImplementations\DSA\DSAKeyFileTests.cs">
|
||||
<Link>CommonTest\System\Security\Cryptography\AlgorithmImplementations\DSA\DSAKeyFileTests.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonTestPath)System\Security\Cryptography\AlgorithmImplementations\DSA\DSAKeyPemTests.cs">
|
||||
<Link>CommonTest\System\Security\Cryptography\AlgorithmImplementations\DSA\DSAKeyPemTests.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonTestPath)System\Security\Cryptography\AlgorithmImplementations\EC\ECKeyFileTests.cs">
|
||||
<Link>CommonTest\System\Security\Cryptography\AlgorithmImplementations\EC\ECKeyFileTests.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonTestPath)System\Security\Cryptography\AlgorithmImplementations\EC\ECKeyFileTests.LimitedPrivate.cs">
|
||||
<Link>CommonTest\System\Security\Cryptography\AlgorithmImplementations\EC\ECKeyFileTests.LimitedPrivate.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonTestPath)System\Security\Cryptography\AlgorithmImplementations\EC\ECKeyPemTests.cs">
|
||||
<Link>CommonTest\System\Security\Cryptography\AlgorithmImplementations\EC\ECKeyPemTests.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonTestPath)System\Security\Cryptography\AlgorithmImplementations\ECDiffieHellman\ECDhKeyFileTests.cs">
|
||||
<Link>CommonTest\System\Security\Cryptography\AlgorithmImplementations\ECDiffieHellman\ECDhKeyFileTests.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonTestPath)System\Security\Cryptography\AlgorithmImplementations\ECDiffieHellman\ECDiffieHellmanKeyPemTests.cs">
|
||||
<Link>CommonTest\System\Security\Cryptography\AlgorithmImplementations\ECDiffieHellman\ECDiffieHellmanKeyPemTests.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonTestPath)System\Security\Cryptography\AlgorithmImplementations\ECDsa\ECDsaKeyFileTests.cs">
|
||||
<Link>CommonTest\System\Security\Cryptography\AlgorithmImplementations\ECDsa\ECDsaKeyFileTests.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonTestPath)System\Security\Cryptography\AlgorithmImplementations\ECDsa\ECDsaKeyPemTests.cs">
|
||||
<Link>CommonTest\System\Security\Cryptography\AlgorithmImplementations\ECDsa\ECDsaKeyPemTests.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonTestPath)System\Security\Cryptography\AlgorithmImplementations\ECDsa\ECDsaTests.netcoreapp.cs">
|
||||
<Link>CommonTest\System\Security\Cryptography\AlgorithmImplementations\ECDsa\ECDsaTests.netcoreapp.cs</Link>
|
||||
</Compile>
|
||||
|
@ -161,9 +173,12 @@
|
|||
<Compile Include="$(CommonTestPath)System\Security\Cryptography\AlgorithmImplementations\RSA\RSAKeyFileTests.cs">
|
||||
<Link>CommonTest\System\Security\Cryptography\AlgorithmImplementations\RSA\RSAKeyFileTests.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonTestPath)System\Security\Cryptography\AlgorithmImplementations\RSA\RSAKeyPemTests.cs">
|
||||
<Link>CommonTest\System\Security\Cryptography\AlgorithmImplementations\RSA\RSAKeyPemTests.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonTestPath)System\Security\Cryptography\AlgorithmImplementations\RSA\SignVerify.netcoreapp.cs">
|
||||
<Link>CommonTest\System\Security\Cryptography\AlgorithmImplementations\RSA\SignVerify.netcoreapp.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="SafeEvpPKeyHandleTests.cs" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -28,6 +28,9 @@ namespace System.Security.Cryptography
|
|||
public virtual void FromXmlString(string xmlString) { }
|
||||
public virtual void ImportEncryptedPkcs8PrivateKey(System.ReadOnlySpan<byte> passwordBytes, System.ReadOnlySpan<byte> source, out int bytesRead) { throw null; }
|
||||
public virtual void ImportEncryptedPkcs8PrivateKey(System.ReadOnlySpan<char> password, System.ReadOnlySpan<byte> source, out int bytesRead) { throw null; }
|
||||
public virtual void ImportFromEncryptedPem(System.ReadOnlySpan<char> input, System.ReadOnlySpan<byte> passwordBytes) { }
|
||||
public virtual void ImportFromEncryptedPem(System.ReadOnlySpan<char> input, System.ReadOnlySpan<char> password) { }
|
||||
public virtual void ImportFromPem(System.ReadOnlySpan<char> input) { }
|
||||
public virtual void ImportPkcs8PrivateKey(System.ReadOnlySpan<byte> source, out int bytesRead) { throw null; }
|
||||
public virtual void ImportSubjectPublicKeyInfo(System.ReadOnlySpan<byte> source, out int bytesRead) { throw null; }
|
||||
public virtual string ToXmlString(bool includePrivateParameters) { throw null; }
|
||||
|
|
|
@ -164,6 +164,57 @@ namespace System.Security.Cryptography
|
|||
public virtual bool TryExportSubjectPublicKeyInfo(Span<byte> destination, out int bytesWritten) =>
|
||||
throw new NotImplementedException(SR.NotSupported_SubclassOverride);
|
||||
|
||||
/// <summary>
|
||||
/// When overridden in a derived class, imports an encrypted RFC 7468
|
||||
/// PEM-encoded key, replacing the keys for this object.
|
||||
/// </summary>
|
||||
/// <param name="input">The PEM text of the encrypted key to import.</param>
|
||||
/// <param name="password">
|
||||
/// The password to use for decrypting the key material.
|
||||
/// </param>
|
||||
/// <exception cref="NotImplementedException">
|
||||
/// A derived type has not overridden this member.
|
||||
/// </exception>
|
||||
/// <remarks>
|
||||
/// Because each algorithm may have algorithm-specific PEM labels, the
|
||||
/// default behavior will throw <see cref="NotImplementedException" />.
|
||||
/// </remarks>
|
||||
public virtual void ImportFromEncryptedPem(ReadOnlySpan<char> input, ReadOnlySpan<char> password) =>
|
||||
throw new NotImplementedException(SR.NotSupported_SubclassOverride);
|
||||
|
||||
/// <summary>
|
||||
/// When overridden in a derived class, imports an encrypted RFC 7468
|
||||
/// PEM-encoded key, replacing the keys for this object.
|
||||
/// </summary>
|
||||
/// <param name="input">The PEM text of the encrypted key to import.</param>
|
||||
/// <param name="passwordBytes">
|
||||
/// The bytes to use as a password when decrypting the key material.
|
||||
/// </param>
|
||||
/// <exception cref="NotImplementedException">
|
||||
/// A derived type has not overridden this member.
|
||||
/// </exception>
|
||||
/// <remarks>
|
||||
/// Because each algorithm may have algorithm-specific PEM labels, the
|
||||
/// default behavior will throw <see cref="NotImplementedException" />.
|
||||
/// </remarks>
|
||||
public virtual void ImportFromEncryptedPem(ReadOnlySpan<char> input, ReadOnlySpan<byte> passwordBytes) =>
|
||||
throw new NotImplementedException(SR.NotSupported_SubclassOverride);
|
||||
|
||||
/// <summary>
|
||||
/// When overridden in a derived class, imports an RFC 7468 textually
|
||||
/// encoded key, replacing the keys for this object.
|
||||
/// </summary>
|
||||
/// <param name="input">The text of the PEM key to import.</param>
|
||||
/// <exception cref="NotImplementedException">
|
||||
/// A derived type has not overridden this member.
|
||||
/// </exception>
|
||||
/// <remarks>
|
||||
/// Because each algorithm may have algorithm-specific PEM labels, the
|
||||
/// default behavior will throw <see cref="NotImplementedException" />.
|
||||
/// </remarks>
|
||||
public virtual void ImportFromPem(ReadOnlySpan<char> input) =>
|
||||
throw new NotImplementedException(SR.NotSupported_SubclassOverride);
|
||||
|
||||
private delegate bool TryExportPbe<T>(
|
||||
ReadOnlySpan<T> password,
|
||||
PbeParameters pbeParameters,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue