예제 #1
0
 /// <summary>
 ///     Creates a new ECDsaAndroid 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 ECDsaAndroid(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 ECAndroid(this);
 }
예제 #2
0
            protected override void Dispose(bool disposing)
            {
                if (disposing)
                {
                    _key?.Dispose();
                    _key = null !;
                }

                base.Dispose(disposing);
            }
            internal ECDiffieHellmanAndroidPublicKey(SafeEcKeyHandle ecKeyHandle)
            {
                ArgumentNullException.ThrowIfNull(ecKeyHandle);

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

                _key = new ECAndroid(ecKeyHandle.DuplicateHandle());
            }
예제 #4
0
 public override ECParameters ExportParameters() =>
 ECAndroid.ExportParameters(GetKey(), includePrivateParameters: false);
예제 #5
0
 internal ECDiffieHellmanAndroidPublicKey(ECParameters parameters)
 {
     _key = new ECAndroid(parameters);
 }
예제 #6
0
 public override ECParameters ExportParameters(bool includePrivateParameters)
 {
     ThrowIfDisposed();
     return(ECAndroid.ExportParameters(_key.Value, includePrivateParameters));
 }
예제 #7
0
 internal ECDsaAndroid(SafeEcKeyHandle ecKeyHandle)
 {
     _key = new ECAndroid(ecKeyHandle.DuplicateHandle());
     ForceSetKeySize(_key.KeySize);
 }
예제 #8
0
 /// <summary>
 /// Create an ECDsaAndroid 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 ECDsaAndroid(ECCurve curve)
 {
     _key = new ECAndroid(curve);
     ForceSetKeySize(_key.KeySize);
 }
예제 #9
0
 public override ECParameters ExportParameters(bool includePrivateParameters) =>
 ECAndroid.ExportParameters(GetKey(), includePrivateParameters);
예제 #10
0
 public ECDiffieHellmanAndroid(int keySize)
 {
     base.KeySize = keySize;
     _key         = new ECAndroid(this);
 }
예제 #11
0
 public ECDiffieHellmanAndroid(ECCurve curve)
 {
     _key         = new ECAndroid(curve);
     KeySizeValue = _key.KeySize;
 }
예제 #12
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.AndroidCrypto.EcKeyHasCurveName(_key.Value);
                ECDiffieHellmanAndroidPublicKey?otherKey = otherPartyPublicKey as ECDiffieHellmanAndroidPublicKey;
                bool disposeOtherKey = false;

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

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

                    otherKey = new ECDiffieHellmanAndroidPublicKey(otherParameters);
                }

                bool otherIsNamed = otherKey.HasCurveName;

                SafeEcKeyHandle?ourKey   = null;
                SafeEcKeyHandle?theirKey = null;

                byte[]? rented = null;
                // Calculate secretLength in bytes.
                int secretLength = AsymmetricAlgorithmHelpers.BitsToBytes(KeySize);

                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 (ECAndroid tmp = new ECAndroid(otherKey.ExportExplicitParameters()))
                        {
                            theirKey = tmp.UpRefKeyHandle();
                        }
                    }
                    else
                    {
                        using (ECAndroid tmp = new ECAndroid(thisKeyExplicit))
                        {
                            ourKey = tmp.UpRefKeyHandle();
                        }

                        theirKey = otherKey.DuplicateKeyHandle();
                    }

                    // 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];
                    }

                    if (!Interop.AndroidCrypto.EcdhDeriveKey(ourKey, theirKey, secret, out int usedBufferLength))
                    {
                        throw new CryptographicException();
                    }

                    Debug.Assert(secretLength == usedBufferLength, $"Expected secret length {secretLength} does not match actual secret length {usedBufferLength}.");

                    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);
                    }
                }
            }
예제 #13
0
 internal ECDiffieHellmanAndroid(SafeEcKeyHandle ecKeyHandle)
 {
     _key         = new ECAndroid(ecKeyHandle.DuplicateHandle());
     KeySizeValue = _key.KeySize;
 }