/// <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); }
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()); }
public override ECParameters ExportParameters() => ECAndroid.ExportParameters(GetKey(), includePrivateParameters: false);
internal ECDiffieHellmanAndroidPublicKey(ECParameters parameters) { _key = new ECAndroid(parameters); }
public override ECParameters ExportParameters(bool includePrivateParameters) { ThrowIfDisposed(); return(ECAndroid.ExportParameters(_key.Value, includePrivateParameters)); }
internal ECDsaAndroid(SafeEcKeyHandle ecKeyHandle) { _key = new ECAndroid(ecKeyHandle.DuplicateHandle()); ForceSetKeySize(_key.KeySize); }
/// <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); }
public override ECParameters ExportParameters(bool includePrivateParameters) => ECAndroid.ExportParameters(GetKey(), includePrivateParameters);
public ECDiffieHellmanAndroid(int keySize) { base.KeySize = keySize; _key = new ECAndroid(this); }
public ECDiffieHellmanAndroid(ECCurve curve) { _key = new ECAndroid(curve); KeySizeValue = _key.KeySize; }
/// <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); } } }
internal ECDiffieHellmanAndroid(SafeEcKeyHandle ecKeyHandle) { _key = new ECAndroid(ecKeyHandle.DuplicateHandle()); KeySizeValue = _key.KeySize; }