WCF client and ASMX webservice client all use the System.Net.HttpWebRequest object to create underlying SSL connection. If you experience any SSL related problem, you can take a System.Net trace first.
If System.Net trace shows the pattern of following SSL alert sequence 15 03 01 00 02, we can use RFC 2246, https://www.ietf.org/rfc/rfc2246.txt , section 7.2 to get the possible root cause of SSL failure.
Sample snippet in System.Net trace.
System.Ne.Sockets Verbose: 0 : [5136] 00000000 : 15 03 01 00 02 :
Step 1: Taking System.Net trace.
1.) Add the contents of the listed XML file to your application configuration file.
If you have a desktop application, the configuration file will be a file called YourApp.exe.config
If it is an asp.net application, the configuration file will be a file called web.config residing in your asp.net application directory.
2.) Please create a folder called c:\traces, and give full permissions to “Everyone”. This will ensure that the log will get created regardless of the process/thread identity.
3.) Restart your application process (YourApp.exe for desktop applications and w3wp.exe for asp.net applications)
4.) Reproduce the problem
5.) You should see a file called System.Net.trace.log in the c:\traces folder.
Note: If you want to change the ___location of where the log gets generated, you can do it by changing the following section:
initializeData="yourDrive:\YourFolder\YourSubFolder……\System.Net.trace.log"
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.diagnostics>
<trace autoflush="true" />
<sources>
<source name="System.Net">
<listeners>
<add name="System.Net"/>
</listeners>
</source>
<source name="System.Net.HttpListener">
<listeners>
<add name="System.Net"/>
</listeners>
</source>
<source name="System.Net.Sockets">
<listeners>
<add name="System.Net"/>
</listeners>
</source>
<source name="System.Net.Cache">
<listeners>
<add name="System.Net"/>
</listeners>
</source>
</sources>
<sharedListeners>
<add
name="System.Net"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="c:\traces\System.Net.trace.log"
traceOutputOptions="DateTime"
/>
</sharedListeners>
<switches>
<add name="System.Net" value="Verbose" />
<add name="System.Net.Sockets" value="Verbose" />
<add name="System.Net.Cache" value="Verbose" />
<add name="System.Net.HttpListener" value="Verbose" />
</switches>
</system.diagnostics>
</configuration>
Additional information on taking System.Net trace, please check https://msdn.microsoft.com/en-us/library/ty48b824.aspx and https://blogs.msdn.com/b/jpsanders/archive/2009/03/24/my-favorite-system-net-trace-configuration-file-dumps-process-id-and-date-time-information.aspx
Step 2: Review System.Net trace.
SSL connection always starts with a client hello payload. In the System.Net trace, you will see something like this:
System.Net.Sockets Verbose: 0 : [5712] Data from Socket#33420276::Send
System.Net.Sockets Verbose: 0 : [5712] 00000000 : 16 03 01 00 6B 01 00 00-67 03 01 4F 8A 0F 82 CB : ....k...g..O....
System.Net.Sockets Verbose: 0 : [5712] 00000010 : FD 08 6F 6C 6F DC AD 20-D2 02 13 4F D8 F0 AD D9 : ..olo.. ...O....
System.Net.Sockets Verbose: 0 : [5712] 00000020 : 5C 22 3C 63 C6 53 AE B2-3D 21 81 00 00 18 C0 14 : \"<c.S..=!......
System.Net.Sockets Verbose: 0 : [5712] 00000030 : C0 13 00 2F 00 35 00 05-00 0A C0 09 C0 0A 00 32 : .../.5.........2
System.Net.Sockets Verbose: 0 : [5712] 00000040 : 00 38 00 13 00 04 01 00-00 26 FF 01 00 01 00 00 : .8.......&......
System.Net.Sockets Verbose: 0 : [5712] 00000050 : 00 00 0B 00 09 00 00 06-68 7A 64 73 6B 38 00 0A : ........hzdsk8..
System.Net.Sockets Verbose: 0 : [5712] 00000060 : 00 08 00 06 00 19 00 18-00 17 00 0B 00 02 01 00 : ................
System.Net.Sockets Verbose: 0 : [5712] Exiting Socket#33420276::Send() -> 112#112
16 --- > decimal 22, means handshake(22),
03 01 --- > SSL version 3.1, so it is TLS 1.0
00 6B -- > payload size
To possibly detect some certain SSL connection failure from text based System.Net log, now we can leverage RFC 2246,
https://www.ietf.org/rfc/rfc2246.txt
7.2. Alert protocol
The Raw Bytes Pattern is 15 03 01 00 02
like this trace file sample:
System.Net.Sockets Verbose: 0 : [5792] 00000000 : 15 03 01 00 02
15: --- > Hex, means 21, it is a signature for alert in RFC 2246, alert(21),
enum {
change_cipher_spec(20), alert(21), handshake(22),
application_data(23), (255)
} ContentType;
03 0x --- > SSL version
03 01 means SSL V 3.1, which is TLS 1.0
03 00 means SSL V 3.0
00 02 --- > Content Size: which is 2 bytes:
The format is following RFC 2246 SSL struct
struct {
ContentType type; --- > 1 byte
ProtocolVersion version; --- > 2 bytes
uint16 length; --- > 2 bytes
opaque fragment[TLSPlaintext.length];
} TLSPlaintext;
Now we can look at the data for 2 bytes Content:
trace file:
System.Net.Sockets Verbose: 0 : [5792] 00000005 : 02 30
DateTime=2009-07-09T19:13:26.1341615Z
System.Net.Sockets Verbose: 0 : [5792] Exiting
Socket#37472519::Receive() -> 2#2
DateTime=2009-07-09T19:13:26.1341615Z
02 means:
enum { warning(1), fatal(2), (255) } AlertLevel;
30 means: 0x30 --- > 0n48, which is
unknow_ca (the issuer of certificate authority is not trusted).
Here is the entire enum list of error code from https://www.ietf.org/rfc/rfc2246.txt
enum {
close_notify(0),
unexpected_message(10),
bad_record_mac(20),
decryption_failed(21),
record_overflow(22),
decompression_failure(30),
handshake_failure(40),
bad_certificate(42),
unsupported_certificate(43),
certificate_revoked(44),
certificate_expired(45),
certificate_unknown(46),
illegal_parameter(47),
unknown_ca(48),
access_denied(49),
decode_error(50),
decrypt_error(51),
export_restriction(60),
protocol_version(70),
insufficient_security(71),
internal_error(80),
user_canceled(90),
no_renegotiation(100),
(255)
} AlertDescription;
Here is the sample snippet for raw trace file:
… ….
System.Net.Sockets Verbose: 0 : [5792] Socket#37472519::Receive()
DateTime=2009-07-09T19:13:26.1341615Z
System.Net.Sockets Verbose: 0 : [5792] Data from Socket#37472519::Receive
DateTime=2009-07-09T19:13:26.1341615Z
System.Net.Sockets Verbose: 0 : [5792] 00000000 : 15 03 01 00 02 : .....
DateTime=2009-07-09T19:13:26.1341615Z
System.Net.Sockets Verbose: 0 : [5792] Exiting Socket#37472519::Receive() -> 5#5
DateTime=2009-07-09T19:13:26.1341615Z
System.Net.Sockets Verbose: 0 : [5792] Socket#37472519::Receive()
DateTime=2009-07-09T19:13:26.1341615Z
System.Net.Sockets Verbose: 0 : [5792] Data from Socket#37472519::Receive
DateTime=2009-07-09T19:13:26.1341615Z
System.Net.Sockets Verbose: 0 : [5792] 00000005 : 02 30 : .0
DateTime=2009-07-09T19:13:26.1341615Z
System.Net.Sockets Verbose: 0 : [5792] Exiting Socket#37472519::Receive() -> 2#2
DateTime=2009-07-09T19:13:26.1341615Z
System.Net Information: 0 : [5792] InitializeSecurityContext(credential = System.Net.SafeFreeCredential_SECURITY, context = 225480:1107220, targetName = gmservices.pp.gm.com, inFlags = ReplayDetect, SequenceDetect, Confidentiality, AllocateMemory, InitManualCredValidation)
DateTime=2009-07-09T19:13:26.1341615Z
System.Net Information: 0 : [5792] InitializeSecurityContext(In-Buffers count=2, Out-Buffer length=0, returned code=UntrustedRoot).
DateTime=2009-07-09T19:13:26.1497868Z
System.Net.Sockets Verbose: 0 : [5792] Socket#37472519::Dispose()
DateTime=2009-07-09T19:13:26.1654121Z
System.Net Error: 0 : [5792] Exception in the HttpWebRequest#55855606:: - The request was aborted: Could not create SSL/TLS secure channel.
DateTime=2009-07-09T19:13:26.1654121Z