Imported Upstream version 5.8.0.22

Former-commit-id: df344e34b07851d296efb3e6604c8db42b6f7aa3
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2017-10-19 20:04:20 +00:00
parent 5f4a27cc8a
commit 7d05485754
5020 changed files with 114082 additions and 186061 deletions

View File

@@ -155,9 +155,6 @@ namespace Internal.Cryptography.Pal
internal sealed class AppleCertificatePal : ICertificatePal
{
private SafeSecIdentityHandle _identityHandle;
// Do not give out this reference, it's only needed in certain cases to prevent temporary keychains
// from being deleted.
private SafeSecKeyRefHandle _privateKeyHolder;
private SafeSecCertificateHandle _certHandle;
private CertificateData _certData;
private bool _readCertData;
@@ -181,11 +178,9 @@ namespace Internal.Cryptography.Pal
{
_certHandle?.Dispose();
_identityHandle?.Dispose();
_privateKeyHolder?.Dispose();
_certHandle = null;
_identityHandle = null;
_privateKeyHolder = null;
}
internal SafeSecCertificateHandle CertificateHandle => _certHandle;
@@ -401,12 +396,6 @@ namespace Internal.Cryptography.Pal
return new ECDsaImplementation.ECDsaSecurityTransforms(publicKey, privateKey);
}
private void HoldPrivateKey()
{
_privateKeyHolder = Interop.AppleCrypto.X509GetPrivateKeyFromIdentity(_identityHandle);
Debug.Assert(!_privateKeyHolder.IsInvalid);
}
public ICertificatePal CopyWithPrivateKey(DSA privateKey)
{
var typedKey = privateKey as DSAImplementation.DSASecurityTransforms;
@@ -480,20 +469,57 @@ namespace Internal.Cryptography.Pal
SafeKeychainHandle keychain = Interop.AppleCrypto.SecKeychainItemCopyKeychain(keyPair.PrivateKey);
// If we're using a key already in a keychain don't add the certificate to that keychain here,
// do it in the temporary add/remove in the shim.
SafeKeychainHandle cloneKeychain = SafeTemporaryKeychainHandle.InvalidHandle;
if (keychain.IsInvalid)
{
keychain = Interop.AppleCrypto.CreateTemporaryKeychain();
cloneKeychain = keychain;
}
// Because SecIdentityRef only has private constructors we need to have the cert and the key
// in the same keychain. That almost certainly means we're going to need to add this cert to a
// keychain, and when a cert that isn't part of a keychain gets added to a keychain then the
// interior pointer of "what keychain did I come from?" used by SecKeychainItemCopyKeychain gets
// set. That makes this function have side effects, which is not desired.
//
// It also makes reference tracking on temporary keychains broken, since the cert can
// DangerousRelease a handle it didn't DangerousAddRef on. And so CopyWithPrivateKey makes
// a temporary keychain, then deletes it before anyone has a chance to (e.g.) export the
// new identity as a PKCS#12 blob.
//
// Solution: Clone the cert, like we do in Windows.
SafeSecCertificateHandle tempHandle;
{
byte[] export = RawData;
const bool exportable = false;
SafeSecIdentityHandle identityHandle;
tempHandle = Interop.AppleCrypto.X509ImportCertificate(
export,
X509ContentType.Cert,
SafePasswordHandle.InvalidHandle,
cloneKeychain,
exportable,
out identityHandle);
Debug.Assert(identityHandle.IsInvalid, "identityHandle should be IsInvalid");
identityHandle.Dispose();
Debug.Assert(!tempHandle.IsInvalid, "tempHandle should not be IsInvalid");
}
using (keychain)
using (tempHandle)
{
SafeSecIdentityHandle identityHandle = Interop.AppleCrypto.X509CopyWithPrivateKey(
_certHandle,
tempHandle,
keyPair.PrivateKey,
keychain);
AppleCertificatePal newPal = new AppleCertificatePal(identityHandle);
newPal.HoldPrivateKey();
return newPal;
}
}

View File

@@ -302,6 +302,7 @@ namespace Internal.Cryptography.Pal
case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_CERT_REVOKED:
return X509ChainStatusFlags.Revoked;
case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_CERT_SIGNATURE_FAILURE:
return X509ChainStatusFlags.NotSignatureValid;

View File

@@ -234,9 +234,6 @@ namespace Internal.Cryptography.Pal
// For .NET Native (UWP) the API used to delete the private key (if it wasn't added to a store) is not
// allowed to be called if the key is stored in CAPI. So for UWP force the key to be stored in the
// CNG Key Storage Provider, then deleting the key with CngKey.Delete will clean up the file on disk, too.
#if uap
pfxCertStoreFlags |= PfxCertStoreFlags.PKCS12_ALWAYS_CNG_KSP;
#endif
return pfxCertStoreFlags;
}

View File

@@ -29,15 +29,7 @@ namespace Internal.Cryptography.Pal
return GetPrivateKey<RSA>(
delegate (CspParameters csp)
{
#if uap
// In .NET Native (UWP) we don't have access to CAPI, so it's CNG-or-nothing.
// But we don't expect to get here, so it shouldn't be a problem.
Debug.Fail("A CAPI provider type code was specified");
return null;
#else
return new RSACryptoServiceProvider(csp);
#endif
},
delegate (CngKey cngKey)
{
@@ -51,15 +43,7 @@ namespace Internal.Cryptography.Pal
return GetPrivateKey<DSA>(
delegate (CspParameters csp)
{
#if uap
// In .NET Native (UWP) we don't have access to CAPI, so it's CNG-or-nothing.
// But we don't expect to get here, so it shouldn't be a problem.
Debug.Fail("A CAPI provider type code was specified");
return null;
#else
return new DSACryptoServiceProvider(csp);
#endif
},
delegate (CngKey cngKey)
{
@@ -215,17 +199,9 @@ namespace Internal.Cryptography.Pal
else
{
// ProviderType being non-zero signifies that this is a CAPI key.
#if uap
// In .NET Native (UWP) we don't have access to CAPI, so it's CNG-or-nothing.
// But we don't expect to get here, so it shouldn't be a problem.
Debug.Fail("A CAPI provider type code was specified");
return null;
#else
// We never want to stomp over certificate private keys.
cspParameters.Flags |= CspProviderFlags.UseExistingKey;
return createCsp(cspParameters);
#endif
}
}

View File

@@ -417,9 +417,6 @@ namespace Internal.Cryptography.Pal
sb.AppendLine();
sb.AppendLine("[Private Key]");
#if uap
// Similar to the Unix implementation, in UWP merely acknowledge that there -is- a private key.
#else
CspKeyContainerInfo cspKeyContainerInfo = null;
try
{
@@ -482,7 +479,6 @@ namespace Internal.Cryptography.Pal
}
catch (CryptographicException) { }
catch (NotSupportedException) { }
#endif // #if uap / #else
}
public void Dispose()

View File

@@ -297,11 +297,9 @@ internal static partial class Interop
[DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool CryptMsgClose(IntPtr hCryptMsg);
#if !uap
[DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
public static extern unsafe bool CryptImportPublicKeyInfoEx2(CertEncodingType dwCertEncodingType, CERT_PUBLIC_KEY_INFO* pInfo, int dwFlags, void* pvAuxInfo, out SafeBCryptKeyHandle phKey);
#endif
[DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool CryptAcquireCertificatePrivateKey(SafeCertContextHandle pCert, CryptAcquireFlags dwFlags, IntPtr pvParameters, out SafeNCryptKeyHandle phCryptProvOrNCryptKey, out int pdwKeySpec, out bool pfCallerFreeProvOrNCryptKey);

View File

@@ -15,11 +15,9 @@ internal static partial class Interop
{
public static partial class cryptoapi
{
#if !uap
[DllImport(Libraries.Advapi32, SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "CryptAcquireContextW")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern unsafe bool CryptAcquireContext(out IntPtr psafeProvHandle, char* pszContainer, char* pszProvider, int dwProvType, CryptAcquireContextFlags dwFlags);
#endif
}
}

View File

@@ -183,7 +183,6 @@ namespace Internal.Cryptography.Pal.Native
}
else
{
#if !uap // For UWP, CryptAcquireContext() is a disallowed api, even when being used for cleanup. CAPI keys should not exist on that platform, however...
CryptAcquireContextFlags flags = (pProvInfo->dwFlags & CryptAcquireContextFlags.CRYPT_MACHINE_KEYSET) | CryptAcquireContextFlags.CRYPT_DELETEKEYSET;
IntPtr hProv;
bool success = Interop.cryptoapi.CryptAcquireContext(out hProv, pProvInfo->pwszContainerName, pProvInfo->pwszProvName, pProvInfo->dwProvType, flags);
@@ -191,7 +190,6 @@ namespace Internal.Cryptography.Pal.Native
// Called CryptAcquireContext solely for the side effect of deleting the key containers. When called with these flags, no actual
// hProv is returned (so there's nothing to clean up.)
Debug.Assert(hProv == IntPtr.Zero);
#endif
}
}
}

View File

@@ -42,8 +42,6 @@ namespace Internal.Cryptography.Pal
CngKey cngKey = CngKey.Import(keyBlob, CngKeyBlobFormat.GenericPublicBlob);
return new RSACng(cngKey);
}
#if !uap
case AlgId.CALG_DSS_SIGN:
{
byte[] keyBlob = ConstructDSSPublicKeyCspBlob(encodedKeyValue, encodedParameters);
@@ -51,8 +49,6 @@ namespace Internal.Cryptography.Pal
dsa.ImportCspBlob(keyBlob);
return dsa;
}
#endif
default:
throw new NotSupportedException(SR.NotSupported_KeyAlgorithm);
}
@@ -65,14 +61,6 @@ namespace Internal.Cryptography.Pal
{
CngKeyBlobFormat blobFormat;
byte[] keyBlob;
#if uap
blobFormat = CngKeyBlobFormat.EccPublicBlob;
keyBlob = ExportKeyBlob(bCryptKeyHandle, blobFormat);
using (CngKey cngKey = CngKey.Import(keyBlob, blobFormat))
{
ecdsa = new ECDsaCng(cngKey);
}
#else
string curveName = GetCurveName(bCryptKeyHandle);
if (curveName == null)
@@ -102,7 +90,6 @@ namespace Internal.Cryptography.Pal
ecdsa = new ECDsaCng();
ecdsa.ImportParameters(ecparams);
}
#endif
}
return ecdsa;
@@ -110,10 +97,6 @@ namespace Internal.Cryptography.Pal
private static SafeBCryptKeyHandle ImportPublicKeyInfo(SafeCertContextHandle certContext)
{
#if uap
// CryptImportPublicKeyInfoEx2() not in the UWP api list.
throw new PlatformNotSupportedException();
#else
unsafe
{
SafeBCryptKeyHandle bCryptKeyHandle;
@@ -135,15 +118,10 @@ namespace Internal.Cryptography.Pal
certContext.DangerousRelease();
}
}
#endif // uap
}
private static byte[] ExportKeyBlob(SafeBCryptKeyHandle bCryptKeyHandle, CngKeyBlobFormat blobFormat)
{
#if uap
// BCryptExportKey() not in the UWP api list.
throw new PlatformNotSupportedException();
#else
string blobFormatString = blobFormat.Format;
int numBytesNeeded = 0;
@@ -158,10 +136,8 @@ namespace Internal.Cryptography.Pal
Array.Resize(ref keyBlob, numBytesNeeded);
return keyBlob;
#endif // uap
}
#if !uap
private static void ExportNamedCurveParameters(ref ECParameters ecParams, byte[] ecBlob, bool includePrivateParameters)
{
// We now have a buffer laid out as follows:
@@ -194,7 +170,6 @@ namespace Internal.Cryptography.Pal
}
}
}
#endif
private static byte[] DecodeKeyBlob(CryptDecodeObjectStructType lpszStructType, byte[] encodedKeyValue)
{

View File

@@ -6,7 +6,6 @@
<OutputType>Library</OutputType>
<AssemblyName>System.Security.Cryptography.X509Certificates</AssemblyName>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DefineConstants Condition="'$(TargetGroup)' == 'uap'">$(DefineConstants);uap</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-OSX-Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-OSX-Release|AnyCPU'" />

View File

@@ -17,9 +17,7 @@ namespace System.Security.Cryptography.X509Certificates.Tests
// netcoreapp-OSX: DefaultKeySet
// netcoreapp-other: EphemeralKeySet
internal static readonly X509KeyStorageFlags EphemeralIfPossible =
#if netcoreapp
!RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? X509KeyStorageFlags.EphemeralKeySet :
#endif
X509KeyStorageFlags.DefaultKeySet;
//
// The Import() methods have an overload for each X509Certificate2Collection.Import() overload.

View File

@@ -114,15 +114,20 @@ namespace System.Security.Cryptography.X509Certificates.Tests
Assert.True(success, "MicrosoftDotComIssuerBytes");
}
using (var microsoftDotComRoot = new X509Certificate2(TestData.MicrosoftDotComRootBytes))
// High Sierra fails to build a chain for a self-signed certificate with revocation enabled.
// https://github.com/dotnet/corefx/issues/21875
if (!PlatformDetection.IsMacOsHighSierra)
{
// NotAfter=7/17/2036
success = microsoftDotComRoot.Verify();
if (!success)
using (var microsoftDotComRoot = new X509Certificate2(TestData.MicrosoftDotComRootBytes))
{
LogVerifyErrors(microsoftDotComRoot, "MicrosoftDotComRootBytes");
// NotAfter=7/17/2036
success = microsoftDotComRoot.Verify();
if (!success)
{
LogVerifyErrors(microsoftDotComRoot, "MicrosoftDotComRootBytes");
}
Assert.True(success, "MicrosoftDotComRootBytes");
}
Assert.True(success, "MicrosoftDotComRootBytes");
}
}

View File

@@ -31,7 +31,7 @@ namespace System.Security.Cryptography.X509Certificates.Tests.CertificateCreatio
{
CertificateRequest request = new CertificateRequest("", ecdsa, HashAlgorithmName.SHA256);
Assert.Throws<ArgumentNullException>("signatureGenerator", () => request.CreateSigningRequest(null));
AssertExtensions.Throws<ArgumentNullException>("signatureGenerator", () => request.CreateSigningRequest(null));
}
}
@@ -44,7 +44,7 @@ namespace System.Security.Cryptography.X509Certificates.Tests.CertificateCreatio
var request = new CertificateRequest("CN=Test", rsa, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
Assert.Throws<ArgumentException>(
AssertExtensions.Throws<ArgumentException>(
null,
() => request.CreateSelfSigned(DateTimeOffset.MaxValue, DateTimeOffset.MinValue));
}
@@ -62,22 +62,22 @@ namespace System.Security.Cryptography.X509Certificates.Tests.CertificateCreatio
HashAlgorithmName.SHA256,
RSASignaturePadding.Pkcs1);
Assert.Throws<ArgumentNullException>(
AssertExtensions.Throws<ArgumentNullException>(
"generator",
() => request.Create(testRoot.SubjectName, null, DateTimeOffset.MinValue, DateTimeOffset.MinValue, null));
DateTimeOffset notAfter = testRoot.NotAfter;
DateTimeOffset notBefore = testRoot.NotBefore;
Assert.Throws<ArgumentException>(
AssertExtensions.Throws<ArgumentException>(
null,
() => request.Create(testRoot, notAfter, notBefore, null));
Assert.Throws<ArgumentException>(
AssertExtensions.Throws<ArgumentException>(
"serialNumber",
() => request.Create(testRoot, notBefore, notAfter, null));
Assert.Throws<ArgumentException>(
AssertExtensions.Throws<ArgumentException>(
"serialNumber",
() => request.Create(testRoot, notBefore, notAfter, Array.Empty<byte>()));
}
@@ -90,13 +90,13 @@ namespace System.Security.Cryptography.X509Certificates.Tests.CertificateCreatio
ECDsa key = null;
HashAlgorithmName hashAlgorithm = default(HashAlgorithmName);
Assert.Throws<ArgumentNullException>(
AssertExtensions.Throws<ArgumentNullException>(
"subjectName",
() => new CertificateRequest(subjectName, key, hashAlgorithm));
subjectName = "";
Assert.Throws<ArgumentNullException>(
AssertExtensions.Throws<ArgumentNullException>(
"key",
() => new CertificateRequest(subjectName, key, hashAlgorithm));
@@ -104,7 +104,7 @@ namespace System.Security.Cryptography.X509Certificates.Tests.CertificateCreatio
using (key)
{
Assert.Throws<ArgumentException>(
AssertExtensions.Throws<ArgumentException>(
"hashAlgorithm",
() => new CertificateRequest(subjectName, key, hashAlgorithm));
}
@@ -117,13 +117,13 @@ namespace System.Security.Cryptography.X509Certificates.Tests.CertificateCreatio
ECDsa key = null;
HashAlgorithmName hashAlgorithm = default(HashAlgorithmName);
Assert.Throws<ArgumentNullException>(
AssertExtensions.Throws<ArgumentNullException>(
"subjectName",
() => new CertificateRequest(subjectName, key, hashAlgorithm));
subjectName = new X500DistinguishedName("");
Assert.Throws<ArgumentNullException>(
AssertExtensions.Throws<ArgumentNullException>(
"key",
() => new CertificateRequest(subjectName, key, hashAlgorithm));
@@ -131,7 +131,7 @@ namespace System.Security.Cryptography.X509Certificates.Tests.CertificateCreatio
using (key)
{
Assert.Throws<ArgumentException>(
AssertExtensions.Throws<ArgumentException>(
"hashAlgorithm",
() => new CertificateRequest(subjectName, key, hashAlgorithm));
}
@@ -145,13 +145,13 @@ namespace System.Security.Cryptography.X509Certificates.Tests.CertificateCreatio
HashAlgorithmName hashAlgorithm = default(HashAlgorithmName);
RSASignaturePadding padding = null;
Assert.Throws<ArgumentNullException>(
AssertExtensions.Throws<ArgumentNullException>(
"subjectName",
() => new CertificateRequest(subjectName, key, hashAlgorithm, padding));
subjectName = "";
Assert.Throws<ArgumentNullException>(
AssertExtensions.Throws<ArgumentNullException>(
"key",
() => new CertificateRequest(subjectName, key, hashAlgorithm, padding));
@@ -159,13 +159,13 @@ namespace System.Security.Cryptography.X509Certificates.Tests.CertificateCreatio
using (key)
{
Assert.Throws<ArgumentException>(
AssertExtensions.Throws<ArgumentException>(
"hashAlgorithm",
() => new CertificateRequest(subjectName, key, hashAlgorithm, padding));
hashAlgorithm = HashAlgorithmName.SHA256;
Assert.Throws<ArgumentNullException>(
AssertExtensions.Throws<ArgumentNullException>(
"padding",
() => new CertificateRequest(subjectName, key, hashAlgorithm, padding));
}
@@ -179,13 +179,13 @@ namespace System.Security.Cryptography.X509Certificates.Tests.CertificateCreatio
HashAlgorithmName hashAlgorithm = default(HashAlgorithmName);
RSASignaturePadding padding = null;
Assert.Throws<ArgumentNullException>(
AssertExtensions.Throws<ArgumentNullException>(
"subjectName",
() => new CertificateRequest(subjectName, key, hashAlgorithm, padding));
subjectName = new X500DistinguishedName("");
Assert.Throws<ArgumentNullException>(
AssertExtensions.Throws<ArgumentNullException>(
"key",
() => new CertificateRequest(subjectName, key, hashAlgorithm, padding));
@@ -193,13 +193,13 @@ namespace System.Security.Cryptography.X509Certificates.Tests.CertificateCreatio
using (key)
{
Assert.Throws<ArgumentException>(
AssertExtensions.Throws<ArgumentException>(
"hashAlgorithm",
() => new CertificateRequest(subjectName, key, hashAlgorithm, padding));
hashAlgorithm = HashAlgorithmName.SHA256;
Assert.Throws<ArgumentNullException>(
AssertExtensions.Throws<ArgumentNullException>(
"padding",
() => new CertificateRequest(subjectName, key, hashAlgorithm, padding));
}
@@ -212,13 +212,13 @@ namespace System.Security.Cryptography.X509Certificates.Tests.CertificateCreatio
PublicKey publicKey = null;
HashAlgorithmName hashAlgorithm = default(HashAlgorithmName);
Assert.Throws<ArgumentNullException>(
AssertExtensions.Throws<ArgumentNullException>(
"subjectName",
() => new CertificateRequest(subjectName, publicKey, hashAlgorithm));
subjectName = new X500DistinguishedName("");
Assert.Throws<ArgumentNullException>(
AssertExtensions.Throws<ArgumentNullException>(
"publicKey",
() => new CertificateRequest(subjectName, publicKey, hashAlgorithm));
@@ -228,7 +228,7 @@ namespace System.Security.Cryptography.X509Certificates.Tests.CertificateCreatio
publicKey = generator.PublicKey;
}
Assert.Throws<ArgumentException>(
AssertExtensions.Throws<ArgumentException>(
"hashAlgorithm",
() => new CertificateRequest(subjectName, publicKey, hashAlgorithm));
}

View File

@@ -162,7 +162,7 @@ namespace System.Security.Cryptography.X509Certificates.Tests.CertificateCreatio
if (!expectSuccess)
{
Assert.Throws<ArgumentException>(
AssertExtensions.Throws<ArgumentException>(
"issuerCertificate",
() =>
{
@@ -179,6 +179,7 @@ namespace System.Security.Cryptography.X509Certificates.Tests.CertificateCreatio
chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority;
chain.ChainPolicy.ExtraStore.Add(rootCert);
chain.ChainPolicy.VerificationTime = start.ToLocalTime().DateTime;
if (useIntermed)
{
@@ -426,6 +427,7 @@ namespace System.Security.Cryptography.X509Certificates.Tests.CertificateCreatio
chain.ChainPolicy.ExtraStore.Add(intermed1CertWithKey);
chain.ChainPolicy.ExtraStore.Add(intermed2CertWithKey);
chain.ChainPolicy.ExtraStore.Add(rootCertWithKey);
chain.ChainPolicy.VerificationTime = now.ToLocalTime().DateTime;
RunChain(chain, leafCert, true, "Initial chain build");
@@ -511,6 +513,7 @@ namespace System.Security.Cryptography.X509Certificates.Tests.CertificateCreatio
chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority;
chain.ChainPolicy.ExtraStore.Add(intermedCertWithKey);
chain.ChainPolicy.ExtraStore.Add(rootCertWithKey);
chain.ChainPolicy.VerificationTime = notBefore.ToLocalTime().DateTime;
RunChain(chain, leafCert, true, "Chain build");
}

View File

@@ -117,29 +117,35 @@ namespace System.Security.Cryptography.X509Certificates.Tests.CertificateCreatio
Assert.Equal(expectedHex, cert.RawData.ByteArrayToHex());
}
[Fact]
public static void SimpleSelfSign_RSA()
[Theory]
[InlineData(false)]
[InlineData(true)]
public static void SimpleSelfSign_RSA(bool exportPfx)
{
using (RSA rsa = RSA.Create())
{
SimpleSelfSign(
new CertificateRequest("CN=localhost", rsa, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1),
"1.2.840.113549.1.1.1");
"1.2.840.113549.1.1.1",
exportPfx);
}
}
[Fact]
public static void SimpleSelfSign_ECC()
[Theory]
[InlineData(false)]
[InlineData(true)]
public static void SimpleSelfSign_ECC(bool exportPfx)
{
using (ECDsa ecdsa = ECDsa.Create(ECCurve.NamedCurves.nistP521))
{
SimpleSelfSign(
new CertificateRequest("CN=localhost", ecdsa, HashAlgorithmName.SHA512),
"1.2.840.10045.2.1");
"1.2.840.10045.2.1",
exportPfx);
}
}
private static void SimpleSelfSign(CertificateRequest request, string expectedKeyOid)
private static void SimpleSelfSign(CertificateRequest request, string expectedKeyOid, bool exportPfx)
{
request.CertificateExtensions.Add(
new X509EnhancedKeyUsageExtension(new OidCollection { new Oid("1.3.6.1.5.5.7.3.1") }, false));
@@ -168,6 +174,12 @@ namespace System.Security.Cryptography.X509Certificates.Tests.CertificateCreatio
Assert.True(
serialNumber.Length >= 8 && serialNumber.Length <= 18,
$"Serial number ({serialNumber}) should be between 4 and 9 bytes, inclusive");
if (exportPfx)
{
byte[] pfx = newCert.Export(X509ContentType.Pkcs12, nameof(SimpleSelfSign));
Assert.InRange(pfx.Length, 100, int.MaxValue);
}
}
}
@@ -419,23 +431,23 @@ namespace System.Security.Cryptography.X509Certificates.Tests.CertificateCreatio
request.Create(issuer, notBefore, notAfter.AddMilliseconds(1), serial).Dispose();//);
// The notBefore value a whole second earlier:
Assert.Throws<ArgumentException>(
"notBefore",
() => request.Create(issuer, notBefore.AddSeconds(-1), notAfter, serial).Dispose());
AssertExtensions.Throws<ArgumentException>("notBefore", () =>
{
request.Create(issuer, notBefore.AddSeconds(-1), notAfter, serial).Dispose();
});
// The notAfter value bumped past the second mark:
DateTimeOffset tooLate = notAfter.AddMilliseconds(1000 - notAfter.Millisecond);
Assert.Throws<ArgumentException>(
"notAfter",
() =>
{
request.Create(issuer, notBefore, tooLate, serial).Dispose();
});
AssertExtensions.Throws<ArgumentException>( "notAfter", () =>
{
request.Create(issuer, notBefore, tooLate, serial).Dispose();
});
// And ensure that both out of range isn't magically valid again
Assert.Throws<ArgumentException>(
"notBefore",
() => request.Create(issuer, notBefore.AddDays(-1), notAfter.AddDays(1), serial).Dispose());
AssertExtensions.Throws<ArgumentException>("notBefore", () =>
{
request.Create(issuer, notBefore.AddDays(-1), notAfter.AddDays(1), serial).Dispose();
});
}
}
}
@@ -507,11 +519,12 @@ namespace System.Security.Cryptography.X509Certificates.Tests.CertificateCreatio
Exception exception = Assert.Throws<CryptographicException>(
() =>
request.Create(request.SubjectName, generator, now, now.AddDays(1), new byte[1]));
#if netcoreapp
if (CultureInfo.CurrentCulture.Name == "en-US")
{
Assert.Contains("ASN1", exception.Message);
}
#endif
}
[Fact]
@@ -543,8 +556,7 @@ namespace System.Security.Cryptography.X509Certificates.Tests.CertificateCreatio
byte[] serialNumber = { 1, 1, 2, 3, 5, 8, 13 };
Assert.Throws<ArgumentException>(
() => request.Create(cert, now, now.AddHours(3), serialNumber));
AssertExtensions.Throws<ArgumentException>("issuerCertificate", () => request.Create(cert, now, now.AddHours(3), serialNumber));
// Passes with the generator
@@ -583,8 +595,7 @@ namespace System.Security.Cryptography.X509Certificates.Tests.CertificateCreatio
byte[] serialNumber = { 1, 1, 2, 3, 5, 8, 13 };
Assert.Throws<ArgumentException>(
() => request.Create(cert, now, now.AddHours(3), serialNumber));
AssertExtensions.Throws<ArgumentException>("issuerCertificate", () => request.Create(cert, now, now.AddHours(3), serialNumber));
X509SignatureGenerator ecdsaGenerator =
X509SignatureGenerator.CreateForECDsa(ecdsa);
@@ -623,8 +634,7 @@ namespace System.Security.Cryptography.X509Certificates.Tests.CertificateCreatio
byte[] serialNumber = { 1, 1, 2, 3, 5, 8, 13 };
Assert.Throws<ArgumentException>(
() => request.Create(cert, now, now.AddHours(3), serialNumber));
AssertExtensions.Throws<ArgumentException>("issuerCertificate", () => request.Create(cert, now, now.AddHours(3), serialNumber));
X509SignatureGenerator generator =
X509SignatureGenerator.CreateForRSA(rsa, RSASignaturePadding.Pkcs1);

View File

@@ -14,7 +14,7 @@ namespace System.Security.Cryptography.X509Certificates.Tests.CertificateCreatio
[Fact]
public static void ECDsaX509SignatureGeneratorCtor_Exceptions()
{
Assert.Throws<ArgumentNullException>(
AssertExtensions.Throws<ArgumentNullException>(
"key",
() => X509SignatureGenerator.CreateForECDsa(null));
}

View File

@@ -240,9 +240,15 @@ namespace System.Security.Cryptography.X509Certificates.Tests.CertificateCreatio
DateTimeOffset now = DateTimeOffset.UtcNow;
using (X509Certificate2 cert = request.CreateSelfSigned(now, now.AddDays(1)))
using (RSA rsa = cert.GetRSAPrivateKey())
{
signature = rsa.SignData(data, hashAlgorithm, RSASignaturePadding.Pkcs1);
using (RSA rsa = cert.GetRSAPrivateKey())
{
signature = rsa.SignData(data, hashAlgorithm, RSASignaturePadding.Pkcs1);
}
// RSAOther is exportable, so ensure PFX export succeeds
byte[] pfxBytes = cert.Export(X509ContentType.Pkcs12, request.SubjectName.Name);
Assert.InRange(pfxBytes.Length, 100, int.MaxValue);
}
Assert.True(rsaOther.VerifyData(data, signature, hashAlgorithm, RSASignaturePadding.Pkcs1));
@@ -444,9 +450,15 @@ namespace System.Security.Cryptography.X509Certificates.Tests.CertificateCreatio
using (X509Certificate2 cert = request.Create(request.SubjectName, dsaGen, now, now.AddDays(1), new byte[1]))
using (X509Certificate2 certWithPrivateKey = cert.CopyWithPrivateKey(dsaOther))
using (DSA dsa = certWithPrivateKey.GetDSAPrivateKey())
{
signature = dsa.SignData(data, hashAlgorithm);
using (DSA dsa = certWithPrivateKey.GetDSAPrivateKey())
{
signature = dsa.SignData(data, hashAlgorithm);
}
// DSAOther is exportable, so ensure PFX export succeeds
byte[] pfxBytes = certWithPrivateKey.Export(X509ContentType.Pkcs12, request.SubjectName.Name);
Assert.InRange(pfxBytes.Length, 100, int.MaxValue);
}
Assert.True(dsaOther.VerifyData(data, signature, hashAlgorithm));
@@ -523,9 +535,15 @@ namespace System.Security.Cryptography.X509Certificates.Tests.CertificateCreatio
DateTimeOffset now = DateTimeOffset.UtcNow;
using (X509Certificate2 cert = request.CreateSelfSigned(now, now.AddDays(1)))
using (ECDsa ecdsa = cert.GetECDsaPrivateKey())
{
signature = ecdsa.SignData(data, hashAlgorithm);
using (ECDsa ecdsa = cert.GetECDsaPrivateKey())
{
signature = ecdsa.SignData(data, hashAlgorithm);
}
// ECDsaOther is exportable, so ensure PFX export succeeds
byte[] pfxBytes = cert.Export(X509ContentType.Pkcs12, request.SubjectName.Name);
Assert.InRange(pfxBytes.Length, 100, int.MaxValue);
}
Assert.True(ecdsaOther.VerifyData(data, signature, hashAlgorithm));

View File

@@ -12,7 +12,7 @@ namespace System.Security.Cryptography.X509Certificates.Tests.CertificateCreatio
[Fact]
public static void RsaPkcsSignatureGeneratorCtor_Exceptions()
{
Assert.Throws<ArgumentNullException>(
AssertExtensions.Throws<ArgumentNullException>(
"key",
() => X509SignatureGenerator.CreateForRSA(null, RSASignaturePadding.Pkcs1));
}

View File

@@ -12,7 +12,7 @@ namespace System.Security.Cryptography.X509Certificates.Tests.CertificateCreatio
[Fact]
public static void RsaPssSignatureGeneratorCtor_Exceptions()
{
Assert.Throws<ArgumentNullException>(
AssertExtensions.Throws<ArgumentNullException>(
"key",
() => X509SignatureGenerator.CreateForRSA(null, RSASignaturePadding.Pss));
}

View File

@@ -17,14 +17,14 @@ namespace System.Security.Cryptography.X509Certificates.Tests.CertificateCreatio
{
SubjectAlternativeNameBuilder builder = new SubjectAlternativeNameBuilder();
Assert.Throws<ArgumentOutOfRangeException>("dnsName", () => builder.AddDnsName(null));
Assert.Throws<ArgumentOutOfRangeException>("dnsName", () => builder.AddDnsName(string.Empty));
Assert.Throws<ArgumentOutOfRangeException>("emailAddress", () => builder.AddEmailAddress(null));
Assert.Throws<ArgumentOutOfRangeException>("emailAddress", () => builder.AddEmailAddress(string.Empty));
Assert.Throws<ArgumentNullException>("uri", () => builder.AddUri(null));
Assert.Throws<ArgumentNullException>("ipAddress", () => builder.AddIpAddress(null));
Assert.Throws<ArgumentOutOfRangeException>("upn", () => builder.AddUserPrincipalName(null));
Assert.Throws<ArgumentOutOfRangeException>("upn", () => builder.AddUserPrincipalName(string.Empty));
AssertExtensions.Throws<ArgumentOutOfRangeException>("dnsName", () => builder.AddDnsName(null));
AssertExtensions.Throws<ArgumentOutOfRangeException>("dnsName", () => builder.AddDnsName(string.Empty));
AssertExtensions.Throws<ArgumentOutOfRangeException>("emailAddress", () => builder.AddEmailAddress(null));
AssertExtensions.Throws<ArgumentOutOfRangeException>("emailAddress", () => builder.AddEmailAddress(string.Empty));
AssertExtensions.Throws<ArgumentNullException>("uri", () => builder.AddUri(null));
AssertExtensions.Throws<ArgumentNullException>("ipAddress", () => builder.AddIpAddress(null));
AssertExtensions.Throws<ArgumentOutOfRangeException>("upn", () => builder.AddUserPrincipalName(null));
AssertExtensions.Throws<ArgumentOutOfRangeException>("upn", () => builder.AddUserPrincipalName(string.Empty));
}
[Fact]

Some files were not shown because too many files have changed in this diff Show More