private SafeRsaHandle GenerateKey() { SafeRsaHandle key = Interop.libcrypto.RSA_new(); bool generated = false; CheckInvalidNewKey(key); try { using (SafeBignumHandle exponent = Interop.libcrypto.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 void FreeKey() { if (_key != null && _key.IsValueCreated) { SafeRsaHandle handle = _key.Value; if (handle != null) { handle.Dispose(); } } }
public override unsafe void ImportParameters(RSAParameters parameters) { ValidateParameters(ref parameters); SafeRsaHandle key = Interop.libcrypto.RSA_new(); bool imported = false; CheckInvalidNewKey(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.libcrypto.CreateBignumPtr(parameters.Modulus); rsaStructure->e = Interop.libcrypto.CreateBignumPtr(parameters.Exponent); rsaStructure->d = Interop.libcrypto.CreateBignumPtr(parameters.D); rsaStructure->p = Interop.libcrypto.CreateBignumPtr(parameters.P); rsaStructure->dmp1 = Interop.libcrypto.CreateBignumPtr(parameters.DP); rsaStructure->q = Interop.libcrypto.CreateBignumPtr(parameters.Q); rsaStructure->dmq1 = Interop.libcrypto.CreateBignumPtr(parameters.DQ); rsaStructure->iqmp = Interop.libcrypto.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 = 8 * Interop.libcrypto.RSA_size(key); }