You've already forked linux-packaging-mono
Imported Upstream version 5.8.0.22
Former-commit-id: df344e34b07851d296efb3e6604c8db42b6f7aa3
This commit is contained in:
parent
5f4a27cc8a
commit
7d05485754
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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'" />
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user