public ECDsa ToECDsa()
            {
                if (s_importParametersMethod is null)
                {
                    Type ecParametersType = typeof(ECDsa).Assembly.GetType("System.Security.Cryptography.ECParameters")
                                            ?? throw new PlatformNotSupportedException("The current platform does not support reading an ECDsa private key from a PEM file");

                    s_importParametersMethod = typeof(ECDsa).GetMethod("ImportParameters", BindingFlags.Instance | BindingFlags.Public, null, new[] { ecParametersType }, null);
                }

                ECDsa ecdsa = null;

                try
                {
                    ecdsa = ECDsa.Create();
                    s_importParametersMethod.Invoke(ecdsa, new[] { ToObject() });

                    // Make sure ecdsa is disposed if ImportParameters above fails.
                    ECDsa ret = ecdsa;
                    ecdsa = null;

                    return(ret);
                }
                finally
                {
                    ecdsa?.Dispose();
                }
            }
        private void UseAfterDispose(ECDsa ecdsa)
        {
            byte[] data = { 1 };
            byte[] sig;

            // Ensure the key is populated, then dispose it.
            using (ecdsa)
            {
                sig = SignData(ecdsa, data, HashAlgorithmName.SHA256);
            }

            ecdsa.Dispose();

            UseAfterDispose(ecdsa, data, sig);

            if (!(PlatformDetection.IsNetFramework && ecdsa.GetType().Name.EndsWith("Cng")))
            {
                Assert.Throws <ObjectDisposedException>(() => ecdsa.GenerateKey(ECCurve.NamedCurves.nistP256));

                Assert.Throws <ObjectDisposedException>(
                    () => ecdsa.ImportParameters(EccTestData.GetNistP256ReferenceKey()));
            }

            // Either set_KeySize or SignData should throw.
            Assert.Throws <ObjectDisposedException>(
                () =>
            {
                ecdsa.KeySize = 384;
                SignData(ecdsa, data, HashAlgorithmName.SHA256);
            });
        }
        protected virtual void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                _disposed = true;
                if (disposing)
                {
                    if (_disposeCryptoOperators)
                    {
                        if (ECDsa != null)
                        {
                            ECDsa.Dispose();
                        }
#if DESKTOP
                        if (RsaCryptoServiceProviderProxy != null)
                        {
                            RsaCryptoServiceProviderProxy.Dispose();
                        }
#endif
                        if (RSA != null)
                        {
                            RSA.Dispose();
                        }
                    }
                }
            }
        }
Пример #4
0
        /// <summary>
        /// Calls <see cref="HashAlgorithm.Dispose()"/> to release this managed resources.
        /// </summary>
        /// <param name="disposing">true, if called from Dispose(), false, if invoked inside a finalizer.</param>
        protected override void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                _disposed = true;

                if (disposing)
                {
#if NETSTANDARD1_4
                    if (_rsa != null && _disposeRsa)
                    {
                        _rsa.Dispose();
                    }
#else
                    if (_rsaCryptoServiceProvider != null && _disposeRsa)
                    {
                        _rsaCryptoServiceProvider.Dispose();
                    }

                    if (_rsaCryptoServiceProviderProxy != null)
                    {
                        _rsaCryptoServiceProviderProxy.Dispose();
                    }
#endif
                    if (_ecdsa != null && _disposeEcdsa)
                    {
                        _ecdsa.Dispose();
                    }
                }
            }
        }
Пример #5
0
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                _impl.Dispose();
            }

            base.Dispose(disposing);
        }
 /// <inheritdoc />
 public void Dispose()
 {
     _ecdsa?.Dispose();
     // ReSharper disable once SuspiciousTypeConversion.Global
     if (_hasherPool is IDisposable disposable)
     {
         disposable.Dispose();
     }
 }
Пример #7
0
        private ECDsa Convert(bool includePrivateParameters, bool throwIfNotSupported)
        {
            if (!CurveName.HasValue)
            {
                if (throwIfNotSupported)
                {
                    throw new InvalidOperationException("missing required curve name");
                }

                return(null);
            }

            KeyCurveName curveName = CurveName.Value;

            int requiredParameterSize = curveName.KeyParameterSize;

            if (requiredParameterSize <= 0)
            {
                if (throwIfNotSupported)
                {
                    throw new InvalidOperationException($"invalid curve name: {CurveName.ToString()}");
                }

                return(null);
            }

            ECParameters ecParameters = new ECParameters
            {
                Curve = ECCurve.CreateFromOid(curveName.Oid),
                Q     = new ECPoint
                {
                    X = ForceBufferLength(nameof(X), X, requiredParameterSize),
                    Y = ForceBufferLength(nameof(Y), Y, requiredParameterSize),
                },
            };

            if (includePrivateParameters && HasPrivateKey)
            {
                ecParameters.D = ForceBufferLength(nameof(D), D, requiredParameterSize);
            }

            ECDsa ecdsa = ECDsa.Create();

            try
            {
                ecdsa.ImportParameters(ecParameters);
            }
            catch when(!throwIfNotSupported)
            {
                ecdsa.Dispose();

                return(null);
            }

            return(ecdsa);
        }
Пример #8
0
        /// <inheritdoc/>
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                publicKey?.Dispose();
                publicKey = null;
            }

            base.Dispose(disposing);
        }
Пример #9
0
 /// <summary>
 /// Releases the unmanaged resources used by this instance and optionally releases the managed resources.
 /// </summary>
 /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
 protected virtual void Dispose(bool disposing)
 {
     if (!disposing)
     {
         return;
     }
     if (needDispose && ecdsa != null)
     {
         ecdsa.Dispose();
     }
 }
Пример #10
0
        static partial void CreateECDsaCertificate(byte[] cer, byte[] key, X509KeyStorageFlags keyStorageFlags, ref X509Certificate2 certificate)
        {
            if (!s_ecInitializedImportPkcs8PrivateKeyMethod)
            {
                // ImportPkcs8PrivateKey was added in .NET Core 3.0 and is only present on Core. We will fall back to a lightweight decoder if this method is missing from the current runtime.
                s_ecImportPkcs8PrivateKeyMethod            = typeof(ECDsa).GetMethod("ImportPkcs8PrivateKey", BindingFlags.Instance | BindingFlags.Public, null, new[] { typeof(ReadOnlySpan <byte>), typeof(int).MakeByRefType() }, null);
                s_ecInitializedImportPkcs8PrivateKeyMethod = true;
            }

            if (s_ecCopyWithPrivateKeyMethod is null)
            {
                s_ecCopyWithPrivateKeyMethod = typeof(ECDsaCertificateExtensions).GetMethod("CopyWithPrivateKey", BindingFlags.Static | BindingFlags.Public, null, new[] { typeof(X509Certificate2), typeof(ECDsa) }, null)
                                               ?? throw new PlatformNotSupportedException("The current platform does not support reading an ECDsa private key from a PEM file");
            }

            // Create the certificate without the private key to pass to our PKCS8 decoder if needed to copy the prime curve.
            using X509Certificate2 certificateWithoutPrivateKey = new X509Certificate2(cer, (string)null, keyStorageFlags);

            ECDsa privateKey = null;

            try
            {
                if (s_ecImportPkcs8PrivateKeyMethod != null)
                {
                    privateKey = ECDsa.Create();

                    // Because ImportECPrivateKeyMethod declares an out parameter we cannot call it directly using MethodInfo.Invoke since all arguments are passed as an object array.
                    // Instead we create a delegate with the correct signature and invoke it.
                    ImportPrivateKeyDelegate importECPrivateKey = (ImportPrivateKeyDelegate)s_ecImportPkcs8PrivateKeyMethod.CreateDelegate(typeof(ImportPrivateKeyDelegate), privateKey);
                    importECPrivateKey.Invoke(key, out int bytesRead);

                    if (key.Length != bytesRead)
                    {
                        throw new InvalidDataException("Invalid PKCS#8 Data");
                    }
                }
                else
                {
                    // Copy the prime curve from the public key to mitigate risk parsing the ASN.1 structure ourselves.
                    using ECDsa publicKey = certificateWithoutPrivateKey.GetECDsaPublicKey();
                    privateKey            = LightweightPkcs8Decoder.DecodeECDsaPkcs8(key, publicKey);
                }

                certificate = (X509Certificate2)s_ecCopyWithPrivateKeyMethod.Invoke(null, new object[] { certificateWithoutPrivateKey, privateKey });

                // Make sure the private key doesn't get disposed now that it's used.
                privateKey = null;
            }
            finally
            {
                // If we created and did not use the RSA private key, make sure it's disposed.
                privateKey?.Dispose();
            }
        }
Пример #11
0
 protected virtual void Dispose(bool disposing)
 {
     // Clean up managed resources if Dispose was called
     if (disposing)
     {
         if (_ecdsa != null)
         {
             _ecdsa.Dispose();
             _ecdsa = null;
         }
     }
 }
Пример #12
0
        protected virtual void Dispose(bool disposing)
        {
            if (!_disposedValue)
            {
                if (disposing)
                {
                    _dsa.Dispose();
                }

                // TODO: free unmanaged resources (unmanaged objects) and override finalizer
                _dsa           = null;
                _disposedValue = true;
            }
        }
        /// <summary>
        /// Creates an instance of the platform specific implementation of the cref="ECDsa" algorithm.
        /// </summary>
        /// <param name="parameters">
        /// The <see cref="ECParameters"/> representing the elliptic curve parameters.
        /// </param>
        public static partial ECDsa Create(ECParameters parameters)
        {
            ECDsa ecdsa = Create();

            try
            {
                ecdsa.ImportParameters(parameters);
            }
            catch
            {
                ecdsa.Dispose();
                throw;
            }

            return(ecdsa);
        }
        /// <summary>
        /// Creates an instance of the platform specific implementation of the cref="ECDsa" algorithm.
        /// </summary>
        /// <param name="curve">
        /// The <see cref="ECCurve"/> representing the elliptic curve.
        /// </param>
        public static partial ECDsa Create(ECCurve curve)
        {
            ECDsa ecdsa = Create();

            try
            {
                ecdsa.GenerateKey(curve);
            }
            catch
            {
                ecdsa.Dispose();
                throw;
            }

            return(ecdsa);
        }
Пример #15
0
        public ECDsa?GetECDsaPublicKey()
        {
            if (_oid.Value != Oids.EcPublicKey)
            {
                return(null);
            }

            ECDsa ecdsa = ECDsa.Create();

            try
            {
                ecdsa.ImportSubjectPublicKeyInfo(ExportSubjectPublicKeyInfo(), out _);
                return(ecdsa);
            }
            catch
            {
                ecdsa.Dispose();
                throw;
            }
        }
        // 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();
            }
        }
Пример #17
0
 public void Dispose()
 {
     _algorithm.Dispose();
 }
        public static void ChainCertRequirements(bool useIntermed, bool?isCA, X509KeyUsageFlags keyUsage, bool expectSuccess)
        {
            HashAlgorithmName hashAlgorithm = HashAlgorithmName.SHA384;

            ECDsa rootKey     = null;
            ECDsa intermedKey = null;
            ECDsa leafKey     = null;

            X509Certificate2 rootCert     = null;
            X509Certificate2 intermedCert = null;
            X509Certificate2 leafCert     = null;

            try
            {
                rootKey = ECDsa.Create(ECCurve.NamedCurves.nistP384);

                var request = new CertificateRequest("CN=Root", rootKey, hashAlgorithm);

                if (useIntermed || isCA.HasValue)
                {
                    request.CertificateExtensions.Add(
                        new X509BasicConstraintsExtension(useIntermed || isCA.Value, false, 0, true));
                }

                X509KeyUsageFlags rootFlags = useIntermed ? X509KeyUsageFlags.KeyCertSign : keyUsage;

                if (rootFlags != X509KeyUsageFlags.None)
                {
                    request.CertificateExtensions.Add(new X509KeyUsageExtension(rootFlags, true));
                }

                DateTimeOffset start = DateTimeOffset.UtcNow.AddHours(-1);
                DateTimeOffset end   = start.AddHours(2);

                rootCert = request.CreateSelfSigned(start, end);

                X509Certificate2 signerCert = rootCert;

                if (useIntermed)
                {
                    intermedKey = ECDsa.Create(ECCurve.NamedCurves.nistP384);
                    request     = new CertificateRequest("CN=Intermediate", intermedKey, hashAlgorithm);

                    if (isCA.HasValue)
                    {
                        request.CertificateExtensions.Add(
                            new X509BasicConstraintsExtension(isCA.Value, false, 0, true));
                    }

                    if (keyUsage != X509KeyUsageFlags.None)
                    {
                        request.CertificateExtensions.Add(new X509KeyUsageExtension(keyUsage, true));
                    }

                    using (X509Certificate2 tmp = request.Create(rootCert, start, end, new byte[] { 6, 0, 2, 2, 10, 23 }))
                    {
                        intermedCert = tmp.CopyWithPrivateKey(intermedKey);
                    }

                    signerCert = intermedCert;
                }

                leafKey = ECDsa.Create(ECCurve.NamedCurves.nistP256);
                request = new CertificateRequest("CN=Leaf", leafKey, hashAlgorithm);

                byte[] leafSerialNumber = { 2, 4, 6, 0, 1 };

                if (!expectSuccess)
                {
                    AssertExtensions.Throws <ArgumentException>(
                        "issuerCertificate",
                        () =>
                    {
                        request.Create(signerCert, start, end, leafSerialNumber)?.Dispose();
                    });

                    return;
                }

                leafCert = request.Create(signerCert, start, end, leafSerialNumber);

                using (X509Chain chain = new X509Chain())
                {
                    chain.ChainPolicy.RevocationMode    = X509RevocationMode.NoCheck;
                    chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority;
                    chain.ChainPolicy.ExtraStore.Add(rootCert);
                    chain.ChainPolicy.VerificationTime = start.ToLocalTime().DateTime;

                    if (useIntermed)
                    {
                        chain.ChainPolicy.ExtraStore.Add(intermedCert);
                    }

                    RunChain(chain, leafCert, true, "Chain verification");
                    DisposeChainCerts(chain);
                }
            }
            finally
            {
                leafCert?.Dispose();
                leafKey?.Dispose();
                intermedCert?.Dispose();
                intermedKey?.Dispose();
                rootCert?.Dispose();
                rootKey?.Dispose();
            }
        }
Пример #19
0
 public void Dispose() => _signAlgorithm.Dispose();
Пример #20
0
 protected override void Dispose(bool disposing)
 {
     _ecdsa.Dispose();
 }
Пример #21
0
 public void Dispose()
 {
     _ecdsa?.Dispose();
 }
Пример #22
0
 public void Dispose()
 {
     _signer.Dispose();
 }
Пример #23
0
        private static bool VerifyX509Signature(
            ReadOnlySpan <byte> toBeSigned,
            ReadOnlySpan <byte> signature,
            PublicKey publicKey,
            AlgorithmIdentifierAsn algorithmIdentifier)
        {
            RSA?  rsa   = publicKey.GetRSAPublicKey();
            ECDsa?ecdsa = publicKey.GetECDsaPublicKey();

            try
            {
                HashAlgorithmName hashAlg;

                if (algorithmIdentifier.Algorithm == Oids.RsaPss)
                {
                    if (rsa is null || !algorithmIdentifier.Parameters.HasValue)
                    {
                        return(false);
                    }

                    PssParamsAsn pssParams = PssParamsAsn.Decode(
                        algorithmIdentifier.Parameters.GetValueOrDefault(),
                        AsnEncodingRules.DER);

                    RSASignaturePadding padding = pssParams.GetSignaturePadding();
                    hashAlg = HashAlgorithmName.FromOid(pssParams.HashAlgorithm.Algorithm);

                    return(rsa.VerifyData(
                               toBeSigned,
                               signature,
                               hashAlg,
                               padding));
                }

                switch (algorithmIdentifier.Algorithm)
                {
                case Oids.RsaPkcs1Sha256:
                case Oids.ECDsaWithSha256:
                    hashAlg = HashAlgorithmName.SHA256;
                    break;

                case Oids.RsaPkcs1Sha384:
                case Oids.ECDsaWithSha384:
                    hashAlg = HashAlgorithmName.SHA384;
                    break;

                case Oids.RsaPkcs1Sha512:
                case Oids.ECDsaWithSha512:
                    hashAlg = HashAlgorithmName.SHA512;
                    break;

                case Oids.RsaPkcs1Sha1:
                case Oids.ECDsaWithSha1:
                    hashAlg = HashAlgorithmName.SHA1;
                    break;

                default:
                    throw new NotSupportedException(
                              SR.Format(SR.Cryptography_UnknownKeyAlgorithm, algorithmIdentifier.Algorithm));
                }

                // All remaining supported algorithms have no defined parameters
                if (!algorithmIdentifier.HasNullEquivalentParameters())
                {
                    return(false);
                }

                switch (algorithmIdentifier.Algorithm)
                {
                case Oids.RsaPkcs1Sha256:
                case Oids.RsaPkcs1Sha384:
                case Oids.RsaPkcs1Sha512:
                case Oids.RsaPkcs1Sha1:
                    if (rsa is null)
                    {
                        return(false);
                    }

                    return(rsa.VerifyData(toBeSigned, signature, hashAlg, RSASignaturePadding.Pkcs1));

                case Oids.ECDsaWithSha256:
                case Oids.ECDsaWithSha384:
                case Oids.ECDsaWithSha512:
                case Oids.ECDsaWithSha1:
                    if (ecdsa is null)
                    {
                        return(false);
                    }

                    return(ecdsa.VerifyData(toBeSigned, signature, hashAlg, DSASignatureFormat.Rfc3279DerSequence));

                default:
                    Debug.Fail(
                        $"Algorithm ID {algorithmIdentifier.Algorithm} was in the first switch, but not the second");
                    return(false);
                }
            }
            catch (AsnContentException)
            {
                return(false);
            }
            catch (CryptographicException)
            {
                return(false);
            }
            finally
            {
                rsa?.Dispose();
                ecdsa?.Dispose();
            }
        }