Использование MySqlConnection (.NET) для SSL-соединения с MySql-сервером не удается у некоторых клиентов

Это действительно вопрос SSL, а трассировки сокетов приведены ниже, так что не стесняйтесь продолжать чтение, даже если вы никогда раньше не использовали MySql. В любом случае мы пытаемся подключиться к MySql-серверу через SSL (с сертификатом Client .PFX), используя MySqlConnection (как .NET 2.0, так и 4.0, версия не имеет значения), вот так:

using (MySqlConnection con = new MySqlConnection(@"server=xxx.yyy.zzz.uuu;database=whopper;user=Username;password=Secret;Certificate Store Location=CurrentUser;Pooling=false;SSL Mode=Required;Certificate Thumbprint=NNNN;Keepalive=60")) {
    con.Open();
}

Сертификат установлен в личном хранилище, и все это работает на некоторых машинах; но не на других. StackTrace:

System.IO.IOException: Received an unexpected EOF or 0 bytes from the transport stream.
   at System.Net.FixedSizeReader.ReadPacket(Byte[] buffer, Int32 offset, Int32 count)
   at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
   at System.Net.Security.SslStream.AuthenticateAsClient(String targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, Boolean checkCertificateRevocation)
   at MySql.Data.MySqlClient.NativeDriver.StartSSL() in D:\Downloads\mysql-connector-net-6.4.4-src\Source\MySql.Data\NativeDriver.cs:line 353
   at MySql.Data.MySqlClient.NativeDriver.Open() in D:\Downloads\mysql-connector-net-6.4.4-src\Source\MySql.Data\NativeDriver.cs:line 267
   at MySql.Data.MySqlClient.Driver.Open() in D:\Downloads\mysql-connector-net-6.4.4-src\Source\MySql.Data\Driver.cs:line 211
   at MySql.Data.MySqlClient.Driver.Create(MySqlConnectionStringBuilder settings) in D:\Downloads\mysql-connector-net-6.4.4-src\Source\MySql.Data\Driver.cs:line 199
   at MySql.Data.MySqlClient.MySqlConnection.Open() in D:\Downloads\mysql-connector-net-6.4.4-src\Source\MySql.Data\Connection.cs:line 489
   at ConsoleApplication1.Program.Main(String[] args) in D:\Downloads\mysql-connector-net-6.4.4-src\Source\ConsoleApplication1\Program.cs:line 14

Теперь, чтобы отладить это, я загрузил последний src MySqlConnection, поэтому я могу следить за всем до вызова AuthenticateAsClient - где MySqlConnection вызывает платформу .NET для установки SSL-соединения. Затем я добавил следующее в свой app.config (чтобы получить трассировку сокета и продолжить расследование):

<?xml version="1.0"?>
<configuration>
    <system.diagnostics>
        <sources>
            <source name="System.Net.Sockets">
                <listeners>
                    <add name="Sockets"/>
                </listeners>
            </source>
        </sources>
        <switches>
            <add name="System.Net.Sockets" value="31"/>
        </switches>
        <sharedListeners>
            <add name="Sockets" type="System.Diagnostics.TextWriterTraceListener" initializeData="c:\socketdump.log"/>
        </sharedListeners>
        <trace autoflush="true"/>
    </system.diagnostics>
</configuration>

На клиентской машине, где соединение обычно завершается успешно, этот файл начинается с:

System.Net.Sockets Verbose: 0 : [5000] Socket#29190913::Socket(InterNetwork#2)
System.Net.Sockets Verbose: 0 : [5000] Exiting Socket#29190913::Socket() 
System.Net.Sockets Verbose: 0 : [5000] Socket#29190913::BeginConnect(142:3306#-1905378776)
System.Net.Sockets Verbose: 0 : [5000] Socket#29190913::BeginConnectEx()
System.Net.Sockets Verbose: 0 : [5000] Socket#29190913::InternalBind(0:0#0)
System.Net.Sockets Verbose: 0 : [5000] Exiting Socket#29190913::InternalBind() 
System.Net.Sockets Verbose: 0 : [5000] Exiting Socket#29190913::BeginConnectEx()    -> ConnectOverlappedAsyncResult#9029417
System.Net.Sockets Verbose: 0 : [5000] Socket#29190913::EndConnect(ConnectOverlappedAsyncResult#9029417)
System.Net.Sockets Verbose: 0 : [5000] Exiting Socket#29190913::EndConnect() 
System.Net.Sockets Verbose: 0 : [5000] Socket#29190913::Receive()
System.Net.Sockets Verbose: 0 : [5000] Data from Socket#29190913::Receive
System.Net.Sockets Verbose: 0 : [5000] 00000000 : 3D 00 00 00 0A 35 2E 31-2E 35 34 2D 31 75 62 75 : =....5.1.54-1ubu
System.Net.Sockets Verbose: 0 : [5000] 00000010 : 6E 74 75 34 00 5E 04 00-00 2F 32 4C 69 4D 26 73 : ntu4.^.../2LiM&s
System.Net.Sockets Verbose: 0 : [5000] 00000020 : 32 00 FF FF 08 02 00 00-00 00 00 00 00 00 00 00 : 2...............
System.Net.Sockets Verbose: 0 : [5000] 00000030 : 00 00 00 00 3E 23 31 6B-4B 75 2B 72 7D 3F 60 48 : ....>#1kKu+r}?`H
System.Net.Sockets Verbose: 0 : [5000] 00000040 : 00                                              : .
System.Net.Sockets Verbose: 0 : [5000] Exiting Socket#29190913::Receive()   -> 65#65
System.Net.Sockets Verbose: 0 : [5000] Socket#29190913::Send()
System.Net.Sockets Verbose: 0 : [5000] Data from Socket#29190913::Send
System.Net.Sockets Verbose: 0 : [5000] 00000000 : 04 00 00 01 8F AA 03 00-                        : ........
System.Net.Sockets Verbose: 0 : [5000] Exiting Socket#29190913::Send()  -> 8#8
System.Net.Sockets Verbose: 0 : [5000] Socket#29190913::Send()
System.Net.Sockets Verbose: 0 : [5000] Data from Socket#29190913::Send
System.Net.Sockets Verbose: 0 : [5000] 00000000 : 16 03 01 00 5A 01 00 00-56 03 01 4E 89 D2 2C 88 : ....Z...V..N..,.
System.Net.Sockets Verbose: 0 : [5000] 00000010 : 6E E9 57 C7 A0 A2 83 59-DC B1 1D 11 01 F6 32 F0 : n.W....Y......2.
System.Net.Sockets Verbose: 0 : [5000] 00000020 : E0 50 63 37 BD EE AD A2-07 3B CC 00 00 18 00 2F : .Pc7.....;...../
System.Net.Sockets Verbose: 0 : [5000] 00000030 : 00 35 00 05 00 0A C0 13-C0 14 C0 09 C0 0A 00 32 : .5.............2
System.Net.Sockets Verbose: 0 : [5000] 00000040 : 00 38 00 13 00 04 01 00-00 15 FF 01 00 01 00 00 : .8..............
System.Net.Sockets Verbose: 0 : [5000] 00000050 : 0A 00 06 00 04 00 17 00-18 00 0B 00 02 01 00    : ...............
System.Net.Sockets Verbose: 0 : [5000] Exiting Socket#29190913::Send()  -> 95#95
System.Net.Sockets Verbose: 0 : [5000] Socket#29190913::Receive()
System.Net.Sockets Verbose: 0 : [5000] Data from Socket#29190913::Receive
System.Net.Sockets Verbose: 0 : [5000] 00000000 : 16 03 01 00 4A                                  : ....J
System.Net.Sockets Verbose: 0 : [5000] Exiting Socket#29190913::Receive()   -> 5#5
System.Net.Sockets Verbose: 0 : [5000] Socket#29190913::Receive()
System.Net.Sockets Verbose: 0 : [5000] Data from Socket#29190913::Receive
System.Net.Sockets Verbose: 0 : [5000] 00000005 : 02 00 00 46 03 01 D3 49-C4 02 A3 F4 60 21 C1 F0 : ...F...I....`!..
System.Net.Sockets Verbose: 0 : [5000] 00000015 : 19 06 33 F1 F2 9B D1 8D-65 C6 A6 EF C8 C8 21 BC : ..3.....e.....!.
System.Net.Sockets Verbose: 0 : [5000] 00000025 : C4 80 AC 9D 0D 0C 20 D9-5D A0 92 8A F5 70 D8 B0 : ...... .]....p..
System.Net.Sockets Verbose: 0 : [5000] 00000035 : 9A EB 86 26 2E AD 0B EC-EF FB EE AB B7 4F 74 BC : ...&.........Ot.
System.Net.Sockets Verbose: 0 : [5000] 00000045 : F3 31 E0 2A 0F 9F EB 00-35 00                   : .1.*....5.
System.Net.Sockets Verbose: 0 : [5000] Exiting Socket#29190913::Receive()   -> 74#74
System.Net.Sockets Verbose: 0 : [5000] Socket#29190913::Receive()
System.Net.Sockets Verbose: 0 : [5000] Data from Socket#29190913::Receive
System.Net.Sockets Verbose: 0 : [5000] 00000000 : 16 03 01 03 AC                                  : .....
System.Net.Sockets Verbose: 0 : [5000] Exiting Socket#29190913::Receive()   -> 5#5
System.Net.Sockets Verbose: 0 : [5000] Socket#29190913::Receive()
System.Net.Sockets Verbose: 0 : [5000] Data from Socket#29190913::Receive
[server certificate received here. identical in both dumps]
System.Net.Sockets Verbose: 0 : [5000] Exiting Socket#29190913::Receive()   -> 940#940
System.Net.Sockets Verbose: 0 : [5000] Socket#29190913::Receive()
System.Net.Sockets Verbose: 0 : [5000] Data from Socket#29190913::Receive
System.Net.Sockets Verbose: 0 : [5000] 00000000 : 16 03 01 00 09                                  : .....
System.Net.Sockets Verbose: 0 : [5000] Exiting Socket#29190913::Receive()   -> 5#5
System.Net.Sockets Verbose: 0 : [5000] Socket#29190913::Receive()
System.Net.Sockets Verbose: 0 : [5000] Data from Socket#29190913::Receive
System.Net.Sockets Verbose: 0 : [5000] 00000005 : 0D 00 00 05 02 01 02 00-00                      : .........
System.Net.Sockets Verbose: 0 : [5000] Exiting Socket#29190913::Receive()   -> 9#9
System.Net.Sockets Verbose: 0 : [5000] Socket#29190913::Receive()
System.Net.Sockets Verbose: 0 : [5000] Data from Socket#29190913::Receive
System.Net.Sockets Verbose: 0 : [5000] 00000000 : 16 03 01 00 04                                  : .....
System.Net.Sockets Verbose: 0 : [5000] Exiting Socket#29190913::Receive()   -> 5#5
System.Net.Sockets Verbose: 0 : [5000] Socket#29190913::Receive()
System.Net.Sockets Verbose: 0 : [5000] Data from Socket#29190913::Receive
System.Net.Sockets Verbose: 0 : [5000] 00000005 : 0E 00 00 00                                     : ....
System.Net.Sockets Verbose: 0 : [5000] Exiting Socket#29190913::Receive()   -> 4#4
System.Net.Sockets Verbose: 0 : [5000] Socket#29190913::Send()
System.Net.Sockets Verbose: 0 : [5000] Data from Socket#29190913::Send
[everything seems encrypted here]

и на машине, где установлен установка SSL не выполняется, этот файл начинается с (не обращайте внимания на BeginConnectEx (), поскольку кажется, что это делается платформой .NET при вызове из потока в ThreadPool):

System.Net.Sockets Verbose: 0 : [3880] Socket#39785641::Socket(InterNetwork#2)
System.Net.Sockets Verbose: 0 : [3880] Exiting Socket#39785641::Socket() 
System.Net.Sockets Verbose: 0 : [3880] Socket#39785641::BeginConnect(142:3306#-1905378776)



System.Net.Sockets Verbose: 0 : [3880] Exiting Socket#39785641::BeginConnect()  -> ConnectAsyncResult#45523402
System.Net.Sockets Verbose: 0 : [3880] Socket#39785641::EndConnect(ConnectAsyncResult#45523402)
System.Net.Sockets Verbose: 0 : [3880] Exiting Socket#39785641::EndConnect() 
System.Net.Sockets Verbose: 0 : [3880] Socket#39785641::Receive()
System.Net.Sockets Verbose: 0 : [3880] Data from Socket#39785641::Receive
System.Net.Sockets Verbose: 0 : [3880] 00000000 : 3D 00 00 00 0A 35 2E 31-2E 35 34 2D 31 75 62 75 : =....5.1.54-1ubu
System.Net.Sockets Verbose: 0 : [3880] 00000010 : 6E 74 75 34 00 62 04 00-00 7A 27 51 43 3C 43 7B : ntu4.b...z'QC<C{
System.Net.Sockets Verbose: 0 : [3880] 00000020 : 64 00 FF FF 08 02 00 00-00 00 00 00 00 00 00 00 : d...............
System.Net.Sockets Verbose: 0 : [3880] 00000030 : 00 00 00 00 63 44 68 61-2E 5C 69 79 46 32 65 29 : ....cDha.\iyF2e)
System.Net.Sockets Verbose: 0 : [3880] 00000040 : 00                                              : .
System.Net.Sockets Verbose: 0 : [3880] Exiting Socket#39785641::Receive()   -> 65#65
System.Net.Sockets Verbose: 0 : [3880] Socket#39785641::Send()
System.Net.Sockets Verbose: 0 : [3880] Data from Socket#39785641::Send
System.Net.Sockets Verbose: 0 : [3880] 00000000 : 04 00 00 01 8F AA 03 00-                        : ........
System.Net.Sockets Verbose: 0 : [3880] Exiting Socket#39785641::Send()  -> 8#8
System.Net.Sockets Verbose: 0 : [3880] Socket#39785641::Send()
System.Net.Sockets Verbose: 0 : [3880] Data from Socket#39785641::Send
System.Net.Sockets Verbose: 0 : [3880] 00000000 : 16 03 01 00 5A 01 00 00-56 03 01 4E 89 D1 92 4C : ....Z...V..N...L
System.Net.Sockets Verbose: 0 : [3880] 00000010 : 61 0C 93 9D 9F 7C 45 39-71 8C 0A 6E 29 7C D9 32 : a....|E9q..n)|.2
System.Net.Sockets Verbose: 0 : [3880] 00000020 : 89 CF 7B D8 1E 33 4F 90-A1 2C 27 00 00 18 00 2F : ..{..3O..,'..../
System.Net.Sockets Verbose: 0 : [3880] 00000030 : 00 35 00 05 00 0A C0 13-C0 14 C0 09 C0 0A 00 32 : .5.............2
System.Net.Sockets Verbose: 0 : [3880] 00000040 : 00 38 00 13 00 04 01 00-00 15 FF 01 00 01 00 00 : .8..............
System.Net.Sockets Verbose: 0 : [3880] 00000050 : 0A 00 06 00 04 00 17 00-18 00 0B 00 02 01 00    : ...............
System.Net.Sockets Verbose: 0 : [3880] Exiting Socket#39785641::Send()  -> 95#95
System.Net.Sockets Verbose: 0 : [3880] Socket#39785641::Receive()
System.Net.Sockets Verbose: 0 : [3880] Data from Socket#39785641::Receive
System.Net.Sockets Verbose: 0 : [3880] 00000000 : 16 03 01 00 4A                                  : ....J
System.Net.Sockets Verbose: 0 : [3880] Exiting Socket#39785641::Receive()   -> 5#5
System.Net.Sockets Verbose: 0 : [3880] Socket#39785641::Receive()
System.Net.Sockets Verbose: 0 : [3880] Data from Socket#39785641::Receive
System.Net.Sockets Verbose: 0 : [3880] 00000005 : 02 00 00 46 03 01 81 9E-F1 4F F4 7A C6 21 B7 94 : ...F.....O.z.!..
System.Net.Sockets Verbose: 0 : [3880] 00000015 : 03 9B 37 C4 E0 EF 0D 1D-86 95 04 2B FE 31 6A A0 : ..7........+.1j.
System.Net.Sockets Verbose: 0 : [3880] 00000025 : DF 1A D8 32 82 9B 20 18-1A 7B C6 FC BB 89 0B DE : ...2.. ..{......
System.Net.Sockets Verbose: 0 : [3880] 00000035 : 97 71 EC 38 9E 14 29 4B-65 BF 23 17 6C 17 1C 3C : .q.8..)Ke.#.l..<
System.Net.Sockets Verbose: 0 : [3880] 00000045 : 6A 5E D9 13 BE CC F9 00-35 00                   : j^......5.
System.Net.Sockets Verbose: 0 : [3880] Exiting Socket#39785641::Receive()   -> 74#74
System.Net.Sockets Verbose: 0 : [3880] Socket#39785641::Receive()
System.Net.Sockets Verbose: 0 : [3880] Data from Socket#39785641::Receive
System.Net.Sockets Verbose: 0 : [3880] 00000000 : 16 03 01 03 AC                                  : .....
System.Net.Sockets Verbose: 0 : [3880] Exiting Socket#39785641::Receive()   -> 5#5
System.Net.Sockets Verbose: 0 : [3880] Socket#39785641::Receive()
System.Net.Sockets Verbose: 0 : [3880] Data from Socket#39785641::Receive
[server certificate received here. identical in both dumps]
System.Net.Sockets Verbose: 0 : [3880] Exiting Socket#39785641::Receive()   -> 940#940
System.Net.Sockets Verbose: 0 : [3880] Socket#39785641::Receive()
System.Net.Sockets Verbose: 0 : [3880] Data from Socket#39785641::Receive
System.Net.Sockets Verbose: 0 : [3880] 00000000 : 16 03 01 00 09                                  : .....
System.Net.Sockets Verbose: 0 : [3880] Exiting Socket#39785641::Receive()   -> 5#5
System.Net.Sockets Verbose: 0 : [3880] Socket#39785641::Receive()
System.Net.Sockets Verbose: 0 : [3880] Data from Socket#39785641::Receive
System.Net.Sockets Verbose: 0 : [3880] 00000005 : 0D 00 00 05 02 01 02 00-00                      : .........
System.Net.Sockets Verbose: 0 : [3880] Exiting Socket#39785641::Receive()   -> 9#9
System.Net.Sockets Verbose: 0 : [3880] Socket#39785641::Receive()
System.Net.Sockets Verbose: 0 : [3880] Data from Socket#39785641::Receive
System.Net.Sockets Verbose: 0 : [3880] 00000000 : 16 03 01 00 04                                  : .....
System.Net.Sockets Verbose: 0 : [3880] Exiting Socket#39785641::Receive()   -> 5#5
System.Net.Sockets Verbose: 0 : [3880] Socket#39785641::Receive()
System.Net.Sockets Verbose: 0 : [3880] Data from Socket#39785641::Receive
System.Net.Sockets Verbose: 0 : [3880] 00000005 : 0E 00 00 00                                     : ....
System.Net.Sockets Verbose: 0 : [3880] Exiting Socket#39785641::Receive()   -> 4#4
System.Net.Sockets Verbose: 0 : [3880] Socket#39785641::Send()
System.Net.Sockets Verbose: 0 : [3880] Data from Socket#39785641::Send
System.Net.Sockets Verbose: 0 : [3880] (printing 1024 out of 1540)
[my client certificate seems to be sent here]

(Я вырезал части сертификата из файлы выше). В любом случае я предполагаю, что ошибка, которую я получаю на некоторых машинах, связана с тем, какой алгоритм шифрования выбран в подтверждении SSL. Но это действительно удар в темноте (?), И я рву волосы именно в этот момент. На некоторых машинах квитирование SSL просто не работает.

Если кто-нибудь знает хороший способ проанализировать / декодировать / проанализировать трафик, указанный выше (я был в WireShark и бился головой в течение нескольких часов, но все еще не могу понять, как передать указанное выше шестнадцатеричное значение диссектору SSL ). Или, если кто-то может напрямую определить разницу / что не удается в № 2, это очень поможет !!

5
задан Fredrik Johansson 4 October 2011 в 14:06
поделиться