Пример #1
0
 /// <summary>
 ///     Creates a new ECDsaOpenSsl object that will use a randomly generated key of the specified size.
 /// </summary>
 /// <param name="keySize">Size of the key to generate, in bits.</param>
 public ECDsaOpenSsl(int keySize)
 {
     // Use the base setter to get the validation and field assignment without the
     // side effect of dereferencing _key.
     base.KeySize = keySize;
     _key         = new ECOpenSsl(this);
 }
Пример #2
0
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                _key?.Dispose();
                _key = null !;
            }

            base.Dispose(disposing);
        }
Пример #3
0
        /// <summary>
        /// Create an ECDsaOpenSsl from an existing <see cref="IntPtr"/> whose value is an
        /// existing OpenSSL <c>EC_KEY*</c>.
        /// </summary>
        /// <remarks>
        /// This method will increase the reference count of the <c>EC_KEY*</c>, the caller should
        /// continue to manage the lifetime of their reference.
        /// </remarks>
        /// <param name="handle">A pointer to an OpenSSL <c>EC_KEY*</c></param>
        /// <exception cref="ArgumentException"><paramref name="handle" /> is invalid</exception>
        public ECDsaOpenSsl(IntPtr handle)
        {
            if (handle == IntPtr.Zero)
            {
                throw new ArgumentException(SR.Cryptography_OpenInvalidHandle, nameof(handle));
            }

            SafeEcKeyHandle ecKeyHandle = SafeEcKeyHandle.DuplicateHandle(handle);

            _key         = new ECOpenSsl(ecKeyHandle);
            KeySizeValue = _key.KeySize;
        }
        internal ECDiffieHellmanOpenSslPublicKey(SafeEvpPKeyHandle pkeyHandle)
        {
            ArgumentNullException.ThrowIfNull(pkeyHandle);

            if (pkeyHandle.IsInvalid)
            {
                throw new ArgumentException(SR.Cryptography_OpenInvalidHandle, nameof(pkeyHandle));
            }

            // If ecKey is valid it has already been up-ref'd, so we can just use this handle as-is.
            SafeEcKeyHandle key = Interop.Crypto.EvpPkeyGetEcKey(pkeyHandle);

            if (key.IsInvalid)
            {
                key.Dispose();
                throw Interop.Crypto.CreateOpenSslCryptographicException();
            }

            _key = new ECOpenSsl(key);
        }
Пример #5
0
        public ECDsaOpenSsl(SafeEvpPKeyHandle pkeyHandle)
        {
            ArgumentNullException.ThrowIfNull(pkeyHandle);

            if (pkeyHandle.IsInvalid)
            {
                throw new ArgumentException(SR.Cryptography_OpenInvalidHandle, nameof(pkeyHandle));
            }

            ThrowIfNotSupported();
            // If ecKey is valid it has already been up-ref'd, so we can just use this handle as-is.
            SafeEcKeyHandle key = Interop.Crypto.EvpPkeyGetEcKey(pkeyHandle);

            if (key.IsInvalid)
            {
                key.Dispose();
                throw Interop.Crypto.CreateOpenSslCryptographicException();
            }

            _key         = new ECOpenSsl(key);
            KeySizeValue = _key.KeySize;
        }
Пример #6
0
 public override ECParameters ExportParameters(bool includePrivateParameters)
 {
     ThrowIfDisposed();
     return(ECOpenSsl.ExportParameters(_key.Value, includePrivateParameters));
 }
Пример #7
0
 /// <summary>
 /// Create an ECDsaOpenSsl algorithm with a named curve.
 /// </summary>
 /// <param name="curve">The <see cref="ECCurve"/> representing the curve.</param>
 /// <exception cref="ArgumentNullException">if <paramref name="curve" /> is null.</exception>
 public ECDsaOpenSsl(ECCurve curve)
 {
     ThrowIfNotSupported();
     _key = new ECOpenSsl(curve);
     ForceSetKeySize(_key.KeySize);
 }
 public override ECParameters ExportParameters() =>
 ECOpenSsl.ExportParameters(GetKey(), includePrivateParameters: false);
 internal ECDiffieHellmanOpenSslPublicKey(ECParameters parameters)
 {
     _key = new ECOpenSsl(parameters);
 }
Пример #10
0
 public ECDiffieHellmanOpenSsl(int keySize)
 {
     ThrowIfNotSupported();
     base.KeySize = keySize;
     _key         = new ECOpenSsl(this);
 }
Пример #11
0
 /// <summary>
 /// Create an ECDsaOpenSsl algorithm with a named curve.
 /// </summary>
 /// <param name="curve">The <see cref="ECCurve"/> representing the curve.</param>
 /// <exception cref="ArgumentNullException">if <paramref name="curve" /> is null.</exception>
 public ECDsaOpenSsl(ECCurve curve)
 {
     _key = new ECOpenSsl(curve);
     ForceSetKeySize(_key.KeySize);
 }
Пример #12
0
 public override ECParameters ExportParameters() =>
 ECOpenSsl.ExportParameters(_key.Value, includePrivateParameters: false);
Пример #13
0
 public ECDiffieHellmanOpenSsl(int keySize)
 {
     base.KeySize = keySize;
     _key         = new ECOpenSsl(this);
 }
Пример #14
0
 public ECDiffieHellmanOpenSsl(ECCurve curve)
 {
     _key         = new ECOpenSsl(curve);
     KeySizeValue = _key.KeySize;
 }
Пример #15
0
 public override ECParameters ExportParameters(bool includePrivateParameters) =>
 ECOpenSsl.ExportParameters(_key.Value, includePrivateParameters);
Пример #16
0
        /// <summary>
        /// Get the secret agreement generated between two parties
        /// </summary>
        private byte[]? DeriveSecretAgreement(ECDiffieHellmanPublicKey otherPartyPublicKey, IncrementalHash?hasher)
        {
            Debug.Assert(otherPartyPublicKey != null);

            // Ensure that this ECDH object contains a private key by attempting a parameter export
            // which will throw an OpenSslCryptoException if no private key is available
            ECParameters thisKeyExplicit             = ExportExplicitParameters(true);
            bool         thisIsNamed                 = Interop.Crypto.EcKeyHasCurveName(_key.Value);
            ECDiffieHellmanOpenSslPublicKey?otherKey = otherPartyPublicKey as ECDiffieHellmanOpenSslPublicKey;
            bool disposeOtherKey = false;

            if (otherKey == null)
            {
                disposeOtherKey = true;

                ECParameters otherParameters =
                    thisIsNamed
                        ? otherPartyPublicKey.ExportParameters()
                        : otherPartyPublicKey.ExportExplicitParameters();

                otherKey = new ECDiffieHellmanOpenSslPublicKey(otherParameters);
            }

            bool otherIsNamed = otherKey.HasCurveName;

            SafeEvpPKeyHandle?ourKey   = null;
            SafeEvpPKeyHandle?theirKey = null;

            byte[]? rented = null;
            int secretLength = 0;

            try
            {
                if (otherKey.KeySize != KeySize)
                {
                    throw new ArgumentException(SR.Cryptography_ArgECDHKeySizeMismatch, nameof(otherPartyPublicKey));
                }

                if (otherIsNamed == thisIsNamed)
                {
                    ourKey   = _key.UpRefKeyHandle();
                    theirKey = otherKey.DuplicateKeyHandle();
                }
                else if (otherIsNamed)
                {
                    ourKey = _key.UpRefKeyHandle();

                    using (ECOpenSsl tmp = new ECOpenSsl(otherKey.ExportExplicitParameters()))
                    {
                        theirKey = tmp.UpRefKeyHandle();
                    }
                }
                else
                {
                    using (ECOpenSsl tmp = new ECOpenSsl(thisKeyExplicit))
                    {
                        ourKey = tmp.UpRefKeyHandle();
                    }

                    theirKey = otherKey.DuplicateKeyHandle();
                }

                using (SafeEvpPKeyCtxHandle ctx = Interop.Crypto.EvpPKeyCtxCreate(ourKey, theirKey, out uint secretLengthU))
                {
                    if (ctx == null || ctx.IsInvalid || secretLengthU == 0 || secretLengthU > int.MaxValue)
                    {
                        throw Interop.Crypto.CreateOpenSslCryptographicException();
                    }

                    secretLength = (int)secretLengthU;

                    // Indicate that secret can hold stackallocs from nested scopes
                    Span <byte> secret = stackalloc byte[0];

                    // Arbitrary limit. But it covers secp521r1, which is the biggest common case.
                    const int StackAllocMax = 66;

                    if (secretLength > StackAllocMax)
                    {
                        rented = CryptoPool.Rent(secretLength);
                        secret = new Span <byte>(rented, 0, secretLength);
                    }
                    else
                    {
                        secret = stackalloc byte[secretLength];
                    }

                    Interop.Crypto.EvpPKeyDeriveSecretAgreement(ctx, secret);

                    if (hasher == null)
                    {
                        return(secret.ToArray());
                    }
                    else
                    {
                        hasher.AppendData(secret);
                        return(null);
                    }
                }
            }
            finally
            {
                theirKey?.Dispose();
                ourKey?.Dispose();

                if (disposeOtherKey)
                {
                    otherKey.Dispose();
                }

                if (rented != null)
                {
                    CryptoPool.Return(rented, secretLength);
                }
            }
        }
Пример #17
0
 public override ECParameters ExportParameters(bool includePrivateParameters) =>
 ECOpenSsl.ExportParameters(GetKey(), includePrivateParameters);
Пример #18
0
 public ECDiffieHellmanOpenSsl(ECCurve curve)
 {
     ThrowIfNotSupported();
     _key         = new ECOpenSsl(curve);
     KeySizeValue = _key.KeySize;
 }