in MySQL.Data/src/Authentication/MySqlPemReader.cs [54:147]
static RSACryptoServiceProvider DecodeX509Key(byte[] key)
{
if (key == null) return null;
byte[] oidSequence = { 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00 };
using (var memoryStream = new MemoryStream(key))
{
using (var reader = new BinaryReader(memoryStream))
{
try
{
var bytes = reader.ReadUInt16();
switch (bytes)
{
case 0x8130:
reader.ReadByte();
break;
case 0x8230:
reader.ReadInt16();
break;
default:
return null;
}
var sequence = reader.ReadBytes(15);
// Compare arrays.
bool arraysAreEqual = true;
if (sequence.Length == oidSequence.Length)
{
for (int i = 0; i < oidSequence.Length; i++)
if (sequence[i] != oidSequence[i])
{
arraysAreEqual = false;
}
}
if (!arraysAreEqual) return null;
bytes = reader.ReadUInt16();
if (bytes == 0x8103) reader.ReadByte();
else if (bytes == 0x8203) reader.ReadInt16();
else return null;
if (reader.ReadByte() != 0x00) return null;
bytes = reader.ReadUInt16();
if (bytes == 0x8130) reader.ReadByte();
else if (bytes == 0x8230) reader.ReadInt16();
else return null;
bytes = reader.ReadUInt16();
byte lowByte = 0x00;
byte highByte = 0x00;
if (bytes == 0x8102) lowByte = reader.ReadByte();
else if (bytes == 0x8202)
{
highByte = reader.ReadByte();
lowByte = reader.ReadByte();
}
else return null;
int modulusSize = highByte << 8 | lowByte;
byte firstByte = reader.ReadByte();
reader.BaseStream.Seek(-1, SeekOrigin.Current);
if (firstByte == 0x00)
{
reader.ReadByte();
modulusSize -= 1;
}
// Read modulus.
byte[] modulus = reader.ReadBytes(modulusSize);
if (reader.ReadByte() != 0x02) return null;
// Read exponent.
byte[] exponent = reader.ReadBytes(reader.ReadByte());
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
RSAParameters rsaKeyInfo = new RSAParameters
{
Modulus = modulus,
Exponent = exponent
};
rsa.ImportParameters(rsaKeyInfo);
return rsa;
}
catch (Exception)
{
return null;
}
}
}
}