static RSACryptoServiceProvider DecodeX509Key()

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;
          }
        }
      }
    }