// Not using TestCaseSource because params too long for friendly test case rendering. private static void VerifyECDecoder(string key, CertificateKeyCurveName keyCurveName, string signature, string cer = null) { #if NET461 Assert.Ignore("ECC is not supported before .NET Framework 4.7"); #endif byte[] data = Convert.FromBase64String(key); byte[] signatureBytes = Convert.FromBase64String(signature); ECDsa publicKey = null; try { if (cer != null) { byte[] publicKeyData = Convert.FromBase64String(cer); using X509Certificate2 certificate = new X509Certificate2(publicKeyData); publicKey = certificate.GetECDsaPublicKey(); } using ECDsa keyPair = LightweightPkcs8Decoder.DecodeECDsaPkcs8(data, publicKey); Assert.AreEqual(keyCurveName.GetKeySize(), keyPair.KeySize); Assert.IsTrue(keyPair.VerifyData(Encoding.UTF8.GetBytes("test"), signatureBytes, HashAlgorithmName.SHA256)); } catch (Exception ex) when( (ex is CryptographicException || (ex is TargetInvocationException && ex.InnerException is CryptographicException)) && RuntimeInformation.IsOSPlatform(OSPlatform.OSX) && keyCurveName == CertificateKeyCurveName.P256 || keyCurveName == CertificateKeyCurveName.P256K) { Assert.Ignore("The curve is not supported by the current platform"); } finally { publicKey?.Dispose(); } }
public static SignatureAlgorithm GetSignatureAlgorithm(this CertificateKeyCurveName keyCurveName) => keyCurveName.ToString() switch { "P-256" => SignatureAlgorithm.ES256,
private static bool IsExpectedP256KException(Exception ex, CertificateKeyCurveName keyCurveName) => // OpenSSL-based implementations do not support P256K. // TODO: Remove this entire check when https://github.com/Azure/azure-sdk-for-net/issues/20244 is resolved. (ex is CryptographicException || ex is TargetInvocationException tiex && tiex.InnerException is ArgumentException {
public async Task DownloadECDsaCertificateSignLocalVerifyRemote([EnumValues] CertificateContentType contentType, [EnumValues] CertificateKeyCurveName keyCurveName) { #if NET461 Assert.Ignore("ECC is not supported before .NET Framework 4.7"); #endif string name = Recording.GenerateId(); CertificatePolicy policy = new CertificatePolicy { IssuerName = WellKnownIssuerNames.Self, Subject = "CN=default", KeyType = CertificateKeyType.Ec, KeyCurveName = keyCurveName, Exportable = true, KeyUsage = { CertificateKeyUsage.DigitalSignature, }, ContentType = contentType, }; CertificateOperation operation = await Client.StartCreateCertificateAsync(name, policy); RegisterForCleanup(name); await operation.WaitForCompletionAsync(DefaultCertificateOperationPollingInterval, default); // Download the certificate and sign data locally. byte[] plaintext = Encoding.UTF8.GetBytes(nameof(DownloadECDsaCertificateSignRemoteVerifyLocal)); X509Certificate2 certificate = null; try { certificate = await Client.DownloadCertificateAsync(name, operation.Value.Properties.Version); using ECDsa privateKey = certificate.GetECDsaPrivateKey(); byte[] signature = privateKey.SignData(plaintext, keyCurveName.GetHashAlgorithmName()); // Verify data remotely. CryptographyClient cryptoClient = GetCryptographyClient(operation.Value.KeyId); VerifyResult result = await cryptoClient.VerifyDataAsync(keyCurveName.GetSignatureAlgorithm(), plaintext, signature); Assert.IsTrue(result.IsValid); } catch (Exception ex) when(IsExpectedP256KException(ex, keyCurveName)) { Assert.Ignore("The curve is not supported by the current platform"); } finally { certificate?.Dispose(); } }
private static bool IsExpectedP256KException(X509Certificate2 certificate, CertificateKeyCurveName keyCurveName) => certificate is null && RuntimeInformation.IsOSPlatform(OSPlatform.OSX) && keyCurveName == CertificateKeyCurveName.P256K;