title: OpenSSL connection: alert internal error
body: <p>I have 100 HTTPS services running on a single server using SNI. (Actually, I don't have access to them. It's an assignment. All I know are their domain names <code>N.xxx.yy</code> where N is in range from 00 to 99.) The goal of the assignment is to evaluate security of every single connection to each of these servers. So some of the servers contain expired certificates, certificates with wrong CN, etc.</p>
  
  <p>My problem is that I cannot get past the handshake on some of the servers. I have written my own application in C++ using OpenSSL, but I've also tried it with <code>openssl s_client</code>. This is how I connect to the server:</p>
  
  <pre><code>openssl s_client -host N.xxx.yy -port 443 -verify 1 -servername N.xxx.yy -CAfile assignment-ca.pem
  </code></pre>
  
  <p>And this is what I get:</p>
  
  <pre><code>139625941858168:error:14094438:SSL routines:ssl3_read_bytes:tlsv1 alert internal error:s3_pkt.c:1493:SSL alert number 80
  139625941858168:error:140790E5:SSL routines:ssl23_write:ssl handshake failure:s23_lib.c:177:
  </code></pre>
  
  <p>In Wireshark, I see that client sent <code>ClientHello</code>, server responded with <code>ServerHello</code> (choosing TLSv1.2 and <code>ECDHE-RSA-AES256-GCM-SHA384</code>) followed by <code>Certificate</code> and then it sent me <code>Alert</code> message containing <code>Internal Error (80)</code>.</p>
  
  <p>After trying different thing I have found out that if I run <code>s_client</code> with <code>-tls1</code> or <code>-tls1_1</code> I can successfully get past the handshake. <code>-tls1_2</code> does not work. What is even stranger is that connection through Chrome/Firefox/any other browser succeeds even if TLSv1.2 is negotiated. From what I see, Chrome is sending a different cipher list than me or <code>s_client</code> but even after modifying the cipher list to match the one in Chrome (and making sure that server chooses <code>ECDHE-RSA-AES128-GCM-SHA256</code>), it does not work either. Chrome is sending these TLS extensions, which I don't but most of them seem empty:</p>
  
  <pre><code>Unknown 47802
  renegotiation_info
  Extended Master Secret
  signed_certificate_timestamp
  status_request
  Application Layer Protocol Negotiation
  channel_id
  Unknown 6682
  </code></pre>
  
  <p>Can anybody explain me what is happening here? Unfortunately, I have no way to debug it on the server side so this is all I know.</p>
  
  <p>UPDATE:</p>
  
  <p>After playing around with forged <code>ClientHello</code> messages I managed to track it down to <code>signature_algorithms</code> extension. My app and <code>s_client</code> provide <code>SHA384 + {RSA,DSA,ECDSA}</code> but if I remove these and keep just <code>SHA256 + {RSA,DSA,ECDSA}</code>, as Chrome does, it works and I receive <code>Server Key Exchange</code> message successfully. Could it be that server somehow does not support it, but instead of providing meaningful error message, it just ends unexpectedly and gives me this internal error?</p>
  
  <p>UPDATE 2:</p>
  
  <p>I found answer to why it works with TLS versions prior to 1.2 in RFC5246. Question from the previous UPDATE still holds.</p>
  
  <pre><code>Note: this extension is not meaningful for TLS versions prior to 1.2.
     Clients MUST NOT offer it if they are offering prior versions.
     However, even if clients do offer it, the rules specified in [TLSEXT]
     require servers to ignore extensions they do not understand.
  </code></pre>