public override void ImportParameters(RSAParameters parameters) { ValidateParameters(ref parameters); ThrowIfDisposed(); SafeRsaHandle key = Interop.Crypto.RsaCreate(); SafeEvpPKeyHandle pkey = Interop.Crypto.EvpPkeyCreate(); bool imported = false; Interop.Crypto.CheckValidOpenSslHandle(key); try { if (!Interop.Crypto.SetRsaParameters( key, parameters.Modulus, parameters.Modulus != null ? parameters.Modulus.Length : 0, parameters.Exponent, parameters.Exponent != null ? parameters.Exponent.Length : 0, parameters.D, parameters.D != null ? parameters.D.Length : 0, parameters.P, parameters.P != null ? parameters.P.Length : 0, parameters.DP, parameters.DP != null ? parameters.DP.Length : 0, parameters.Q, parameters.Q != null ? parameters.Q.Length : 0, parameters.DQ, parameters.DQ != null ? parameters.DQ.Length : 0, parameters.InverseQ, parameters.InverseQ != null ? parameters.InverseQ.Length : 0)) { throw Interop.Crypto.CreateOpenSslCryptographicException(); } imported = true; } finally { if (!imported) { key.Dispose(); } } if (!Interop.Crypto.EvpPkeySetRsa(pkey, key)) { pkey.Dispose(); key.Dispose(); throw Interop.Crypto.CreateOpenSslCryptographicException(); } key.Dispose(); FreeKey(); _key = new Lazy <SafeEvpPKeyHandle>(pkey); // Use ForceSet instead of the property setter to ensure that LegalKeySizes doesn't interfere // with the already loaded key. ForceSetKeySize(BitsPerByte * Interop.Crypto.EvpPKeySize(pkey)); }
private SafeRsaHandle GenerateKey() { SafeRsaHandle key = Interop.libcrypto.RSA_new(); bool generated = false; Interop.Crypto.CheckValidOpenSslHandle(key); try { using (SafeBignumHandle exponent = Interop.Crypto.CreateBignum(s_defaultExponent)) { // The documentation for RSA_generate_key_ex does not say that it returns only // 0 or 1, so the call marshalls it back as a full Int32 and checks for a value // of 1 explicitly. int response = Interop.libcrypto.RSA_generate_key_ex( key, KeySize, exponent, IntPtr.Zero); CheckBoolReturn(response); generated = true; } } finally { if (!generated) { key.Dispose(); } } return(key); }
private SafeRsaHandle GenerateKey() { SafeRsaHandle key = Interop.AndroidCrypto.RsaCreate(); bool generated = false; if (key is null || key.IsInvalid) { throw new CryptographicException(); } try { // The documentation for RSA_generate_key_ex does not say that it returns only // 0 or 1, so the call marshals it back as a full Int32 and checks for a value // of 1 explicitly. int response = Interop.AndroidCrypto.RsaGenerateKeyEx( key, KeySize); CheckBoolReturn(response); generated = true; } finally { if (!generated) { key.Dispose(); } } return(key); }
/// <summary> /// Create an RSAOpenSsl from an <see cref="SafeEvpPKeyHandle"/> whose value is an existing /// OpenSSL <c>EVP_PKEY*</c> wrapping an <c>RSA*</c> /// </summary> /// <param name="pkeyHandle">A SafeHandle for an OpenSSL <c>EVP_PKEY*</c></param> /// <exception cref="ArgumentNullException"><paramref name="pkeyHandle"/> is <c>null</c></exception> /// <exception cref="ArgumentException"> /// <paramref name="pkeyHandle"/> <see cref="Runtime.InteropServices.SafeHandle.IsInvalid" /> /// </exception> /// <exception cref="CryptographicException"><paramref name="pkeyHandle"/> is not a valid enveloped <c>RSA*</c></exception> public RSAOpenSsl(SafeEvpPKeyHandle pkeyHandle) { if (pkeyHandle == null) { throw new ArgumentNullException(nameof(pkeyHandle)); } if (pkeyHandle.IsInvalid) { throw new ArgumentException(SR.Cryptography_OpenInvalidHandle, nameof(pkeyHandle)); } // If rsa is valid it has already been up-ref'd, so we can just use this handle as-is. SafeRsaHandle rsa = Interop.Crypto.EvpPkeyGetRsa(pkeyHandle); if (rsa.IsInvalid) { rsa.Dispose(); throw Interop.Crypto.CreateOpenSslCryptographicException(); } // Use ForceSet instead of the property setter to ensure that LegalKeySizes doesn't interfere // with the already loaded key. ForceSetKeySize(BitsPerByte * Interop.Crypto.RsaSize(rsa)); _key = new Lazy <SafeRsaHandle>(() => rsa, isThreadSafe: true); }
private void FreeKey() { if (_key != null && _key.IsValueCreated) { SafeRsaHandle handle = _key.Value; handle?.Dispose(); } }
public override void ImportRSAPublicKey(ReadOnlySpan <byte> source, out int bytesRead) { ThrowIfDisposed(); int read; try { AsnDecoder.ReadEncodedValue( source, AsnEncodingRules.BER, out _, out _, out read); } catch (AsnContentException e) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); } SafeEvpPKeyHandle pkey = Interop.Crypto.EvpPkeyCreate(); SafeRsaHandle key = Interop.Crypto.DecodeRsaPublicKey(source.Slice(0, read)); Interop.Crypto.CheckValidOpenSslHandle(key); if (!Interop.Crypto.EvpPkeySetRsa(pkey, key)) { key.Dispose(); pkey.Dispose(); throw Interop.Crypto.CreateOpenSslCryptographicException(); } key.Dispose(); FreeKey(); _key = new Lazy <SafeEvpPKeyHandle>(pkey); // Use ForceSet instead of the property setter to ensure that LegalKeySizes doesn't interfere // with the already loaded key. ForceSetKeySize(BitsPerByte * Interop.Crypto.EvpPKeySize(pkey)); bytesRead = read; }
public override void ImportParameters(RSAParameters parameters) { ValidateParameters(ref parameters); ThrowIfDisposed(); SafeRsaHandle key = Interop.AndroidCrypto.RsaCreate(); bool imported = false; if (key is null || key.IsInvalid) { throw new CryptographicException(); } try { if (!Interop.AndroidCrypto.SetRsaParameters( key, parameters.Modulus, parameters.Modulus != null ? parameters.Modulus.Length : 0, parameters.Exponent, parameters.Exponent != null ? parameters.Exponent.Length : 0, parameters.D, parameters.D != null ? parameters.D.Length : 0, parameters.P, parameters.P != null ? parameters.P.Length : 0, parameters.DP, parameters.DP != null ? parameters.DP.Length : 0, parameters.Q, parameters.Q != null ? parameters.Q.Length : 0, parameters.DQ, parameters.DQ != null ? parameters.DQ.Length : 0, parameters.InverseQ, parameters.InverseQ != null ? parameters.InverseQ.Length : 0)) { throw new CryptographicException(); } imported = true; } finally { if (!imported) { key.Dispose(); } } FreeKey(); _key = new Lazy <SafeRsaHandle>(key); SetKeySizeFromHandle(key); }
public override unsafe void ImportRSAPublicKey(ReadOnlySpan <byte> source, out int bytesRead) { ThrowIfDisposed(); fixed(byte *ptr = &MemoryMarshal.GetReference(source)) { using (MemoryManager <byte> manager = new PointerMemoryManager <byte>(ptr, source.Length)) { ReadOnlyMemory <byte> subjectPublicKey; try { AsnReader reader = new AsnReader(manager.Memory, AsnEncodingRules.BER); subjectPublicKey = reader.PeekEncodedValue(); } catch (AsnContentException e) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); } // Decoding the key on Android requires the encoded SubjectPublicKeyInfo, // not just the SubjectPublicKey, so we construct one. SubjectPublicKeyInfoAsn spki = new SubjectPublicKeyInfoAsn { Algorithm = new AlgorithmIdentifierAsn { Algorithm = Oids.Rsa, Parameters = AlgorithmIdentifierAsn.ExplicitDerNull, }, SubjectPublicKey = subjectPublicKey, }; AsnWriter writer = new AsnWriter(AsnEncodingRules.DER); spki.Encode(writer); SafeRsaHandle key = Interop.AndroidCrypto.DecodeRsaSubjectPublicKeyInfo(writer.Encode()); if (key is null || key.IsInvalid) { key?.Dispose(); throw new CryptographicException(); } FreeKey(); _key = new Lazy <SafeRsaHandle>(key); SetKeySizeFromHandle(key); bytesRead = subjectPublicKey.Length; } } }
private SafeRsaHandle GenerateKey() { using (SafeEvpPKeyHandle pkey = Interop.Crypto.RsaGenerateKey(KeySize)) { SafeRsaHandle rsa = Interop.Crypto.EvpPkeyGetRsa(pkey); if (rsa.IsInvalid) { rsa.Dispose(); throw Interop.Crypto.CreateOpenSslCryptographicException(); } return(rsa); } }
public override void ImportParameters(RSAParameters parameters) { ValidateParameters(ref parameters); SafeRsaHandle key = Interop.Crypto.RsaCreate(); bool imported = false; Interop.Crypto.CheckValidOpenSslHandle(key); try { Interop.Crypto.SetRsaParameters( key, parameters.Modulus, parameters.Modulus != null ? parameters.Modulus.Length : 0, parameters.Exponent, parameters.Exponent != null ? parameters.Exponent.Length : 0, parameters.D, parameters.D != null ? parameters.D.Length : 0, parameters.P, parameters.P != null ? parameters.P.Length : 0, parameters.DP, parameters.DP != null ? parameters.DP.Length : 0, parameters.Q, parameters.Q != null ? parameters.Q.Length : 0, parameters.DQ, parameters.DQ != null ? parameters.DQ.Length : 0, parameters.InverseQ, parameters.InverseQ != null ? parameters.InverseQ.Length : 0); imported = true; } finally { if (!imported) { key.Dispose(); } } FreeKey(); _key = new Lazy <SafeRsaHandle>(() => key, LazyThreadSafetyMode.None); // Set base.KeySize directly, since we don't want to free the key // (which we would do if the keysize changed on import) base.KeySize = BitsPerByte * Interop.Crypto.RsaSize(key); }
public override void ImportParameters(RSAParameters parameters) { ValidateParameters(ref parameters); SafeRsaHandle key = Interop.Crypto.RsaCreate(); bool imported = false; Interop.Crypto.CheckValidOpenSslHandle(key); try { Interop.Crypto.SetRsaParameters( key, parameters.Modulus, parameters.Modulus != null ? parameters.Modulus.Length : 0, parameters.Exponent, parameters.Exponent != null ? parameters.Exponent.Length : 0, parameters.D, parameters.D != null ? parameters.D.Length : 0, parameters.P, parameters.P != null ? parameters.P.Length : 0, parameters.DP, parameters.DP != null ? parameters.DP.Length : 0, parameters.Q, parameters.Q != null ? parameters.Q.Length : 0, parameters.DQ, parameters.DQ != null ? parameters.DQ.Length : 0, parameters.InverseQ, parameters.InverseQ != null ? parameters.InverseQ.Length : 0); imported = true; } finally { if (!imported) { key.Dispose(); } } FreeKey(); _key = new Lazy <SafeRsaHandle>(() => key, isThreadSafe: true); // Use ForceSet instead of the property setter to ensure that LegalKeySizes doesn't interfere // with the already loaded key. ForceSetKeySize(BitsPerByte * Interop.Crypto.RsaSize(key)); }
internal static SafeRsaHandle DuplicateHandle(IntPtr handle) { Debug.Assert(handle != IntPtr.Zero); // Reliability: Allocate the SafeHandle before calling RSA_up_ref so // that we don't lose a tracked reference in low-memory situations. SafeRsaHandle safeHandle = new SafeRsaHandle(); if (!Interop.AndroidCrypto.RsaUpRef(handle)) { safeHandle.Dispose(); throw new CryptographicException(); } safeHandle.SetHandle(handle); return(safeHandle); }
public override unsafe void ImportParameters(RSAParameters parameters) { ValidateParameters(ref parameters); SafeRsaHandle key = Interop.libcrypto.RSA_new(); bool imported = false; Interop.Crypto.CheckValidOpenSslHandle(key); try { Interop.libcrypto.RSA_ST *rsaStructure = (Interop.libcrypto.RSA_ST *)key.DangerousGetHandle(); // RSA_free is going to take care of freeing any of these as long as they successfully // get assigned. // CreateBignumPtr returns IntPtr.Zero for null input, so this just does the right thing // on a public-key-only set of RSAParameters. rsaStructure->n = Interop.Crypto.CreateBignumPtr(parameters.Modulus); rsaStructure->e = Interop.Crypto.CreateBignumPtr(parameters.Exponent); rsaStructure->d = Interop.Crypto.CreateBignumPtr(parameters.D); rsaStructure->p = Interop.Crypto.CreateBignumPtr(parameters.P); rsaStructure->dmp1 = Interop.Crypto.CreateBignumPtr(parameters.DP); rsaStructure->q = Interop.Crypto.CreateBignumPtr(parameters.Q); rsaStructure->dmq1 = Interop.Crypto.CreateBignumPtr(parameters.DQ); rsaStructure->iqmp = Interop.Crypto.CreateBignumPtr(parameters.InverseQ); imported = true; } finally { if (!imported) { key.Dispose(); } } FreeKey(); _key = new Lazy <SafeRsaHandle>(() => key, LazyThreadSafetyMode.None); // Set base.KeySize directly, since we don't want to free the key // (which we would do if the keysize changed on import) base.KeySize = BitsPerByte * Interop.libcrypto.RSA_size(key); }
public override void ImportParameters(RSAParameters parameters) { ValidateParameters(ref parameters); ThrowIfDisposed(); if (parameters.Exponent == null || parameters.Modulus == null) { throw new CryptographicException(SR.Cryptography_InvalidRsaParameters); } // Check that either all parameters are not null or all are null, if a subset were set, then the parameters are invalid. // If the parameters are all not null, verify the integrity of their lengths. if (parameters.D == null) { if (parameters.P != null || parameters.DP != null || parameters.Q != null || parameters.DQ != null || parameters.InverseQ != null) { throw new CryptographicException(SR.Cryptography_InvalidRsaParameters); } } else { if (parameters.P == null || parameters.DP == null || parameters.Q == null || parameters.DQ == null || parameters.InverseQ == null) { throw new CryptographicException(SR.Cryptography_InvalidRsaParameters); } // Half, rounded up. int halfModulusLength = (parameters.Modulus.Length + 1) / 2; // Matching the .NET Framework RSACryptoServiceProvider behavior, as that's the .NET de facto standard if (parameters.D.Length != parameters.Modulus.Length || parameters.P.Length != halfModulusLength || parameters.Q.Length != halfModulusLength || parameters.DP.Length != halfModulusLength || parameters.DQ.Length != halfModulusLength || parameters.InverseQ.Length != halfModulusLength) { throw new CryptographicException(SR.Cryptography_InvalidRsaParameters); } } SafeRsaHandle key = Interop.AndroidCrypto.RsaCreate(); bool imported = false; if (key is null || key.IsInvalid) { throw new CryptographicException(); } try { if (!Interop.AndroidCrypto.SetRsaParameters( key, parameters.Modulus, parameters.Modulus != null ? parameters.Modulus.Length : 0, parameters.Exponent, parameters.Exponent != null ? parameters.Exponent.Length : 0, parameters.D, parameters.D != null ? parameters.D.Length : 0, parameters.P, parameters.P != null ? parameters.P.Length : 0, parameters.DP, parameters.DP != null ? parameters.DP.Length : 0, parameters.Q, parameters.Q != null ? parameters.Q.Length : 0, parameters.DQ, parameters.DQ != null ? parameters.DQ.Length : 0, parameters.InverseQ, parameters.InverseQ != null ? parameters.InverseQ.Length : 0)) { throw new CryptographicException(); } imported = true; } finally { if (!imported) { key.Dispose(); } } FreeKey(); _key = new Lazy <SafeRsaHandle>(key); SetKeySizeFromHandle(key); }