I trying to understand why when I create TcpListener server in c# I'm failed to retrive certificate chain from the client ssl connection.
I bought certificate from COMODO with folowing files:
- Root CA Certificate - AddTrustExternalCARoot.crt
- Intermediate CA Certificate - COMODORSAAddTrustCA.crt
- Intermediate CA Certificate - COMODORSADomainValidationSecureServerCA.crt
Then I combined those files into one CAfile:
cat COMODORSADomainValidationSecureServerCA.crt COMODORSAAddTrustCA.crt AddTrustExternalCARoot.crt > cafile.cer
Next I create pfx certificate:
openssl pkcs12 -export -in new_api_coinpip_com.crt -inkey new_api.coinpip.com.key -chain -CAfile api.coinpip.com.bundle -out my-csharp-cert.pfx
And finally I writed simple test server application (SslServer.exe):
using System;
using System.Security.Cryptography.X509Certificates;
using System.Net.Sockets;
using System.Net;
using System.Net.Security;
using System.Security.Authentication;
using System.Text;
namespace SslServer
{
public class Program
{
static int Port = 9097;
static X509Certificate2 serverCertificate = null;
// The certificate parameter specifies the name of the file
// containing the machine certificate.
public static void RunServer(string certificate, string password)
{
serverCertificate = new X509Certificate2 (certificate, password);
// Create a TCP/IP (IPv4) socket and listen for incoming connections11.
TcpListener listener = new TcpListener(IPAddress.Any, Port);
listener.Start();
while (true)
{
Console.WriteLine("Waiting for a client to connect...");
// Application blocks while waiting for an incoming connection.
// Type CNTL-C to terminate the server.
TcpClient client = listener.AcceptTcpClient();
ProcessClient(client);
}
}
static void ProcessClient (TcpClient client)
{
// A client has connected. Create the
// SslStream using the client's network stream.
SslStream sslStream = new SslStream(
client.GetStream(), false);
// Authenticate the server but don't require the client to authenticate.
try
{
sslStream.AuthenticateAsServer(serverCertificate,
false, SslProtocols.Default, true);
// Set timeouts for the read and write to 5 seconds.
sslStream.ReadTimeout = 5000;
sslStream.WriteTimeout = 5000;
// Read a message from the client.
Console.WriteLine("Waiting for client message...");
string messageData = ReadMessage(sslStream);
Console.WriteLine("Received: {0}", messageData);
// Write a message to the client.
byte[] message = Encoding.UTF8.GetBytes("Hello from the server.<EOF>");
Console.WriteLine("Sending hello message.");
sslStream.Write(message);
}
catch (AuthenticationException e)
{
Console.WriteLine("Exception: {0}", e.Message);
if (e.InnerException != null)
{
Console.WriteLine("Inner exception: {0}", e.InnerException.Message);
}
Console.WriteLine ("Authentication failed - closing the connection.");
sslStream.Close();
client.Close();
return;
}
catch(Exception e) {
Console.WriteLine("Exception: {0}", e.Message);
if (e.InnerException != null)
{
Console.WriteLine("Inner exception: {0}", e.InnerException.Message);
}
sslStream.Close();
client.Close();
return;
}
finally
{
// The client stream will be closed with the sslStream
// because we specified this behavior when creating
// the sslStream.
sslStream.Close();
client.Close();
}
}
static string ReadMessage(SslStream sslStream)
{
// Read the message sent by the client.
// The client signals the end of the message using the
// "<EOF>" marker.
byte [] buffer = new byte[2048*2];
StringBuilder messageData = new StringBuilder();
int bytes = -1;
do
{
// Read the client's test message.
bytes = sslStream.Read(buffer, 0, buffer.Length);
// Use Decoder class to convert from bytes to UTF8
// in case a character spans two buffers.
Decoder decoder = Encoding.UTF8.GetDecoder();
char[] chars = new char[decoder.GetCharCount(buffer,0,bytes)];
decoder.GetChars(buffer, 0, bytes, chars,0);
messageData.Append (chars);
// Check for EOF or an empty message.
if (messageData.ToString().IndexOf("<EOF>") != -1)
{
break;
}
} while (bytes !=0);
return messageData.ToString();
}
public static int Main(string[] args)
{
RunServer (args [0], args[1]);
return 0;
}
}
}
And when I trying to launch server by
SslServer.exe /path/to/certificate/my-csharp-cert.pfx SomePassword
I'm unable to see certificate chain (which is include in my-csharp-cert.pfx)
openssl s_client -showcerts -connect api.coinpip.com:9097
CONNECTED(00000003)
depth=0 OU = Domain Control Validated, OU = PositiveSSL, CN = api.coinpip.com verify error:num=20:unable to get local issuer certificate verify return:1 depth=0 OU = Domain Control Validated, OU = PositiveSSL, CN = api.coinpip.com verify error:num=27:certificate not trusted verify return:1 depth=0 OU = Domain Control Validated, OU = PositiveSSL, CN = api.coinpip.com verify error:num=21:unable to verify the first certificate verify return:1 --- Certificate chain 0 s:/OU=Domain Control Validated/OU=PositiveSSL/CN=api.coinpip.com i:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA -----BEGIN CERTIFICATE----- MIIFUjCCBDqgAwIBAgIRAI5OrBia65sFYOEOPAE+YcYwDQYJKoZIhvcNAQELBQAw gZAxCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO BgNVBAcTB1NhbGZvcmQxGjAYBgNVBAoTEUNPTU9ETyBDQSBMaW1pdGVkMTYwNAYD VQQDEy1DT01PRE8gUlNBIERvbWFpbiBWYWxpZGF0aW9uIFNlY3VyZSBTZXJ2ZXIg Q0EwHhcNMTUwNTAzMDAwMDAwWhcNMTYwNTMxMjM1OTU5WjBTMSEwHwYDVQQLExhE b21haW4gQ29udHJvbCBWYWxpZGF0ZWQxFDASBgNVBAsTC1Bvc2l0aXZlU1NMMRgw FgYDVQQDEw9hcGkuY29pbnBpcC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw ggEKAoIBAQCtTznUdDXEmB2WMjWZNVL/4nfdqvWvRP8zQFx5rhsCFO+N4fsi+FY7 AAC1Mn4/jb0EDjZkxukyz8xbLmMcskDhgFTXlZlhb/5R5mscn2lwlBXwQpTuvjtX yIwl8a1Ey6cZHVWcjf5vveCa1crwOd7653EsxY9gXf5UEKzST0qRhMMlF2Be120t nKyqJSvNi6lNYcIrTg3zWLdHRpitZn8uIyVO0i7aq/cujz0O620K4rYR1QJZ7Cij 5hmdGoWIYMsAL0A0qODw5yEGiUqEEGdtHsYHJTopGoQCP1rOyEhlyhoILnyBUDDT DgUMwYSFLv4JnfXbR52+LBKd5dDImT0LAgMBAAGjggHhMIIB3TAfBgNVHSMEGDAW gBSQr2o6lFoL2JDqElZz30O0Oija5zAdBgNVHQ4EFgQUAHGRnlng9W4U9qVPYBdS nfQAW8owDgYDVR0PAQH/BAQDAgWgMAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYwFAYI KwYBBQUHAwEGCCsGAQUFBwMCME8GA1UdIARIMEYwOgYLKwYBBAGyMQECAgcwKzAp BggrBgEFBQcCARYdaHR0cHM6Ly9zZWN1cmUuY29tb2RvLmNvbS9DUFMwCAYGZ4EM AQIBMFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly9jcmwuY29tb2RvY2EuY29tL0NP TU9ET1JTQURvbWFpblZhbGlkYXRpb25TZWN1cmVTZXJ2ZXJDQS5jcmwwgYUGCCsG AQUFBwEBBHkwdzBPBggrBgEFBQcwAoZDaHR0cDovL2NydC5jb21vZG9jYS5jb20v Q09NT0RPUlNBRG9tYWluVmFsaWRhdGlvblNlY3VyZVNlcnZlckNBLmNydDAkBggr BgEFBQcwAYYYaHR0cDovL29jc3AuY29tb2RvY2EuY29tMC8GA1UdEQQoMCaCD2Fw aS5jb2lucGlwLmNvbYITd3d3LmFwaS5jb2lucGlwLmNvbTANBgkqhkiG9w0BAQsF AAOCAQEAe3C8VWbVoXiKj406XOZ7FUwQkiLX9wzlF9jgvXDuKSj/U65d6v2uwTma VjufWUN6yVFWS+M16qZwcH7e3z1tUeYZ6g6+lIv6h0/hNmiSt+ruqlqXX8qZYGEI PK39C1udd8tcwhxq0ob/JOWUhU8QRjKiQ/WZEVL0Ps55qMap4rYgWviqiDLkhRVA kneXMmKBXQrmxa+AvQ4S1pTDmOr/BMmnAkDSUkPvd4J4KnAL4m2rM2yTG3FsGzgk 06pWGqOOcALYe1qxz3pQCFsTpltDKIRXXSlsJCW06UHezRgA9umkt/Mst0E6g7Kb yM6fV9XhEyrnPGWstjultuD6BQuO2w== -----END CERTIFICATE----- --- Server certificate subject=/OU=Domain Control Validated/OU=PositiveSSL/CN=api.coinpip.com issuer=/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA --- No client certificate CA names sent --- SSL handshake has read 1496 bytes and written 621 bytes --- New, TLSv1/SSLv3, Cipher is AES256-SHA Server public key is 2048 bit Secure Renegotiation IS NOT supported Compression: NONE Expansion: NONE SSL-Session: Protocol : TLSv1 Cipher : AES256-SHA Session-ID: Session-ID-ctx: Master-Key: CE5BF190BCE388CC09ACD846357ECFFED77992C2059A489C8406EAE1CF7A8274B04FF6838DA8182539205331F0F680BE Key-Arg : None PSK identity: None PSK identity hint: None SRP username: None Start Time: 1435488120 Timeout : 300 (sec) Verify return code: 21 (unable to verify the first certificate) ---
Why it's not working? What I missed?
If use same chain cafile.cer for apache there no any problem:
openssl s_client -showcerts -connect api.coinpip.com:443
CONNECTED(00000003)
depth=0 C = SG, ST = Some-State, L = Singapore, O = Internet Widgits Pty Ltd, OU = eztopay.me, CN = eztopay.me, emailAddress = admin@eztopay.me verify error:num=18:self signed certificate verify return:1 depth=0 C = SG, ST = Some-State, L = Singapore, O = Internet Widgits Pty Ltd, OU = eztopay.me, CN = eztopay.me, emailAddress = admin@eztopay.me verify return:1 --- Certificate chain 0 s:/C=SG/ST=Some-State/L=Singapore/O=Internet Widgits Pty Ltd/OU=http://ift.tt/1GTOtaz
i:/C=SG/ST=Some-State/L=Singapore/O=Internet Widgits Pty Ltd/OU=http://ift.tt/1GTOtaz -----BEGIN CERTIFICATE----- MIIEHTCCAwWgAwIBAgIJAPwmQDQj40WhMA0GCSqGSIb3DQEBBQUAMIGkMQswCQYD VQQGEwJTRzETMBEGA1UECAwKU29tZS1TdGF0ZTESMBAGA1UEBwwJU2luZ2Fwb3Jl MSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxEzARBgNVBAsMCmV6 dG9wYXkubWUxEzARBgNVBAMMCmV6dG9wYXkubWUxHzAdBgkqhkiG9w0BCQEWEGFk bWluQGV6dG9wYXkubWUwHhcNMTQwNzE1MDQyMjI2WhcNMTUwNzE1MDQyMjI2WjCB pDELMAkGA1UEBhMCU0cxEzARBgNVBAgMClNvbWUtU3RhdGUxEjAQBgNVBAcMCVNp bmdhcG9yZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMRMwEQYD VQQLDAplenRvcGF5Lm1lMRMwEQYDVQQDDAplenRvcGF5Lm1lMR8wHQYJKoZIhvcN AQkBFhBhZG1pbkBlenRvcGF5Lm1lMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB CgKCAQEAuDk+s91Be9I4QuUnAAriSltbgD8VGkQ5D4F0M3KsGgTlTpUTo4LT49eQ Yg7TaialFK9HtCUZcPOo4wTDrFCsP+GJUURxCTkt6LUOnJu4R/VwScx2Rknh18+0 clq5d8UxkMRcEWJ1vdWdn71jjSSBNuVsDJAljKMh1pib26/LoCyskDTBuUE5VOjC Fc8HlHLy4VGAROCarogNgWIhJVeBOZA9f96IutKLinj8Kh6ANh6HXazShatyB7XG AMLbuFFegPcYp/GbKOd/c3k/KWq+PmN+CmIDHqanlv29YGyXVJSnOT4IjEPbNJs3 CE2qK9h/03+fZJfJfasgMWcHSndoBQIDAQABo1AwTjAdBgNVHQ4EFgQU9B3fsjib bsR7VtYr0l7URsdplmswHwYDVR0jBBgwFoAU9B3fsjibbsR7VtYr0l7URsdplmsw DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEABNOdBR+GX1YZDRenTOqN EybA9urdytLjl9jzxqh3jcPQWXNF1v8rg9jTWhIGxnsxXj6igqKHOV6L3MeGt0Vm tlJgdKhTnJPbYVsXVyo12m0DGfd7y2mrqlrAu4/JkMhAgJRdoOC5ShwZm7JQcU8f EvcgyozEmfZwOd3Oj8gZJu8QXF0i5iGfjC34g9tBLvQYu++fbSaRnLYOpHY7rtDZ 3eC+zN3zE2ENtC5leKVOUOM41NNPvHiEYbhXMSqF0TD9+GktW2dU3Np6HvOEif+F /xSCz3PgVtPB97kcGobWQiv1nome5QzkSz814jzKxEYc6qBOrA4GmmnRrOxYe5AA vg== -----END CERTIFICATE----- --- Server certificate subject=/C=SG/ST=Some-State/L=Singapore/O=Internet Widgits Pty Ltd/OU=http://ift.tt/1GTOtaz issuer=/C=SG/ST=Some-State/L=Singapore/O=Internet Widgits Pty Ltd/OU=http://ift.tt/1GTOtaz --- No client certificate CA names sent --- SSL handshake has read 1748 bytes and written 421 bytes --- New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384 Server public key is 2048 bit Secure Renegotiation IS supported Compression: NONE Expansion: NONE SSL-Session: Protocol : TLSv1.2 Cipher : ECDHE-RSA-AES256-GCM-SHA384 Session-ID: CE13742D4BA8B45D899819FF011B9033ACAFD0DCF65CC53E8F35ADDF60D3DDF6 Session-ID-ctx: Master-Key: 5656D423DED4A8D65EFF63080A514A2C3B9D27A8BBB1D39FFB3367484842D8B0300591C7E837B3894A7172AE3458AE21 Key-Arg : None PSK identity: None PSK identity hint: None SRP username: None TLS session ticket lifetime hint: 300 (seconds) TLS session ticket: 0000 - 49 42 9d c0 a1 c6 13 3d-1e 58 3e 08 8a 7e aa 60 IB.....=.X>..~.` 0010 - 66 1f 2f fc b0 3f 9b 0e-97 91 d8 de fc fd 56 33 f./..?........V3 0020 - 94 43 a0 8b 84 a7 b3 67-10 b1 d0 c6 62 af 5d 0f .C.....g....b.]. 0030 - dc 5f 78 e1 9b 68 ed a5-7a 48 98 11 d9 ae ba 71 .x..h..zH.....q 0040 - 2b 84 3a 82 97 ca 1b 44-52 67 09 31 27 4b 36 5b +.:....DRg.1'K6[ 0050 - 91 7b cd b6 78 05 cf e5-ab b4 4c 83 18 46 dc b0 .{..x.....L..F.. 0060 - 9d 09 41 57 ea 4c 05 a2-44 59 89 d9 42 98 97 89 ..AW.L..DY..B... 0070 - 93 9c cc ce db 8d 64 54-30 08 b7 3c 1e 2c b4 94 ......dT0..<.,.. 0080 - 71 90 d3 0e 7f d1 f7 9c-d2 4d 1f 97 65 4f 4a 9e q........M..eOJ. 0090 - 4a c3 f7 67 20 04 41 ca-b7 15 4f 5e 1a ba fd 3c J..g .A...O^...< 00a0 - 1d 34 1f 5f cf 37 93 79-10 1b d5 b0 ab 46 0c 32 .4..7.y.....F.2 00b0 - bd bf 2f 1c 17 b1 52 43-20 e0 2e 0e f9 89 18 29 ../...RC ......)Start Time: 1435488467 Timeout : 300 (sec)
Verify return code: 18 (self signed certificate)
Any suggestion how to fix this and make certificate chain works in c#?
Aucun commentaire:
Enregistrer un commentaire