Skip to content

Commit b221a8c

Browse files
committed
Use new .NET 5.0 API to load RSA parameters.
1 parent 1270a92 commit b221a8c

File tree

3 files changed

+35
-7
lines changed

3 files changed

+35
-7
lines changed

src/MySqlConnector/Core/ServerSession.cs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,8 @@ private async Task<PayloadData> SendEncryptedPasswordAsync(
664664
IOBehavior ioBehavior,
665665
CancellationToken cancellationToken)
666666
{
667+
using var rsa = RSA.Create();
668+
#if NET461 || NET471 || NETSTANDARD1_3 || NETSTANDARD2_0 || NETSTANDARD2_1 || NETCOREAPP2_1 || NETCOREAPP3_1
667669
// load the RSA public key
668670
RSAParameters rsaParameters;
669671
try
@@ -676,13 +678,23 @@ private async Task<PayloadData> SendEncryptedPasswordAsync(
676678
throw new MySqlException(MySqlErrorCode.UnableToConnectToHost, "Couldn't load server's RSA public key; try using a secure connection instead.", ex);
677679
}
678680

681+
rsa.ImportParameters(rsaParameters);
682+
#else
683+
try
684+
{
685+
Utility.LoadRsaParameters(rsaPublicKey, rsa);
686+
}
687+
catch (Exception ex)
688+
{
689+
Log.Error(ex, "Session{0} couldn't load server's RSA public key", m_logArguments);
690+
throw new MySqlException(MySqlErrorCode.UnableToConnectToHost, "Couldn't load server's RSA public key; try using a secure connection instead.", ex);
691+
}
692+
#endif
693+
679694
// add NUL terminator to password
680695
var passwordBytes = Encoding.UTF8.GetBytes(cs.Password);
681696
Array.Resize(ref passwordBytes, passwordBytes.Length + 1);
682697

683-
using var rsa = RSA.Create();
684-
rsa.ImportParameters(rsaParameters);
685-
686698
// XOR the password bytes with the challenge
687699
AuthPluginData = Utility.TrimZeroByte(switchRequest.Data);
688700
for (var i = 0; i < passwordBytes.Length; i++)

src/MySqlConnector/Utilities/Utility.cs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,11 @@ public static unsafe void Convert(this Encoder encoder, ReadOnlySpan<char> chars
8282
/// <summary>
8383
/// Loads a RSA key from a PEM string.
8484
/// </summary>
85-
/// <param name="key">The key, in PEM format.</param>
86-
/// <returns>An RSA key.</returns>
85+
#if NET45 || NET461 || NET471 || NETSTANDARD1_3 || NETSTANDARD2_0 || NETSTANDARD2_1 || NETCOREAPP2_1 || NETCOREAPP3_1
8786
public static RSAParameters GetRsaParameters(string key)
87+
#else
88+
public static void LoadRsaParameters(string key, RSA rsa)
89+
#endif
8890
{
8991
const string beginRsaPrivateKey = "-----BEGIN RSA PRIVATE KEY-----";
9092
const string endRsaPrivateKey = "-----END RSA PRIVATE KEY-----";
@@ -134,7 +136,14 @@ public static RSAParameters GetRsaParameters(string key)
134136
{
135137
if (!System.Convert.TryFromBase64Chars(keyChars, bufferBytes, out var bytesWritten))
136138
throw new FormatException("The input is not a valid Base-64 string.");
139+
#if NETSTANDARD2_1 || NETCOREAPP2_1 || NETCOREAPP3_1
137140
return GetRsaParameters(bufferBytes.Slice(0, bytesWritten), isPrivate);
141+
#else
142+
if (isPrivate)
143+
rsa.ImportRSAPrivateKey(bufferBytes.Slice(0, bytesWritten), out var _);
144+
else
145+
rsa.ImportSubjectPublicKeyInfo(bufferBytes.Slice(0, bytesWritten), out var _);
146+
#endif
138147
}
139148
finally
140149
{
@@ -144,6 +153,7 @@ public static RSAParameters GetRsaParameters(string key)
144153
#endif
145154
}
146155

156+
#if NET45 || NET461 || NET471 || NETSTANDARD1_3 || NETSTANDARD2_0 || NETSTANDARD2_1 || NETCOREAPP2_1 || NETCOREAPP3_1
147157
// Derived from: https://stackoverflow.com/a/32243171/, https://stackoverflow.com/a/26978561/, http://luca.ntop.org/Teaching/Appunti/asn1.html
148158
private static RSAParameters GetRsaParameters(ReadOnlySpan<byte> data, bool isPrivate)
149159
{
@@ -247,6 +257,7 @@ private static RSAParameters GetRsaParameters(ReadOnlySpan<byte> data, bool isPr
247257
InverseQ = iq.ToArray(),
248258
};
249259
}
260+
#endif
250261

251262
/// <summary>
252263
/// Returns a new <see cref="ArraySegment{T}"/> that starts at index <paramref name="index"/> into <paramref name="arraySegment"/>.

tests/MySqlConnector.Tests/UtilityTests.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Globalization;
3+
using System.Security.Cryptography;
34
using System.Text;
45
using MySqlConnector.Utilities;
56
using Xunit;
@@ -90,7 +91,9 @@ public void ParseTimeSpanFails(string input)
9091
[InlineData("pre", "post")]
9192
public void DecodePublicKey(string pre, string post)
9293
{
93-
var parameters = Utility.GetRsaParameters(pre + c_publicKey + post);
94+
using var rsa = RSA.Create();
95+
Utility.LoadRsaParameters(pre + c_publicKey + post, rsa);
96+
var parameters = rsa.ExportParameters(false);
9497
Assert.Equal(s_modulus, parameters.Modulus);
9598
Assert.Equal(s_exponent, parameters.Exponent);
9699
}
@@ -102,7 +105,9 @@ public void DecodePublicKey(string pre, string post)
102105
[InlineData("pre", "post")]
103106
public void DecodePrivateKey(string pre, string post)
104107
{
105-
var parameters = Utility.GetRsaParameters(pre + c_privateKey + post);
108+
using var rsa = RSA.Create();
109+
Utility.LoadRsaParameters(pre + c_privateKey + post, rsa);
110+
var parameters = rsa.ExportParameters(true);
106111
Assert.Equal(s_modulus, parameters.Modulus);
107112
Assert.Equal(s_exponent, parameters.Exponent);
108113
Assert.Equal(s_d, parameters.D);

0 commit comments

Comments
 (0)