BoringSSL certificate verification failure when connecting to secure websocket on iOS

I'm unable to connect to a secure websocket connection due to the error below on an iOS device (iOS 12 & 13).


It seems there is a failure validating the certificate for the end-point but I can't find a way to determine the reason. I can connect to the websocket end-point from a browser client. I also verified the certificate using https://www.ssllabs.com/ssltest/ and don't see any issues. The SSL certificate is issued from Let's Encrypt.


Below is the console output I could capture from the device and console app on my mac laptop.


XCODE DEBUG CONSOLE


2020-04-29 16:18:03.501170-0700 [BoringSSL] boringssl_context_handle_fatal_alert(1873) [C12.1:1][0x1151122e0] write alert, level: fatal, description: certificate unknown
2020-04-29 16:18:03.501366-0700 [BoringSSL] boringssl_context_error_print(1863) boringssl ctx 0x282eb41b0: 4450062232:error:1000007d:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED:/AppleInternal/BuildRoot/Library/Caches/com.apple.xbs/Sources/boringssl/boringssl-283.102.1/ssl/handshake.cc:369:
2020-04-29 16:18:03.510648-0700 [BoringSSL] boringssl_session_handshake_incomplete(164) [C12.1:1][0x1151122e0] SSL library error
2020-04-29 16:18:03.510740-0700 [BoringSSL] boringssl_session_handshake_error_print(111) [C12.1:1][0x1151122e0] 4450062232:error:1000007d:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED:/AppleInternal/BuildRoot/Library/Caches/com.apple.xbs/Sources/boringssl/boringssl-283.102.1/ssl/handshake.cc:369:
2020-04-29 16:18:03.510837-0700 [BoringSSL] nw_protocol_boringssl_handshake_negotiate_proceed(726) [C12.1:1][0x1151122e0] handshake failed at state 12288
2020-04-29 16:18:03.532541-0700 [strings] ERROR: Network.NWError not found in table Error of bundle CFBundle 0x109308b40  (framework, loaded)
   error: Optional("The operation couldn’t be completed. (NETWORK.NWERROR error 2.)")


MAC CONSOLE APP


default    16:18:03.712414-0700    boringssl_session_handshake_incomplete(170) [C12.1:1][0x1151122e0] Handshake incomplete: waiting for data to read [2]
default    16:18:03.712477-0700    boringssl_session_handshake_incomplete(170) [C12.1:1][0x1151122e0] Handshake incomplete: waiting for data to read [2]
default    16:18:03.712583-0700    boringssl_session_handshake_incomplete(170) [C12.1:1][0x1151122e0] Handshake incomplete: waiting for data to read [2]
default    16:18:03.712646-0700    boringssl_session_handshake_incomplete(170) [C12.1:1][0x1151122e0] Handshake incomplete: waiting for data to read [2]
default    16:18:03.712707-0700    boringssl_context_message_handler(2258) [C12.1:1][0x1151122e0] Reading SSL3_RT_HANDSHAKE 122 bytes
default    16:18:03.713628-0700    boringssl_context_info_handler(1983) [C12.1:1][0x1151122e0] Client handshake state: TLS 1.3 client read_hello_retry_request
default    16:18:03.713687-0700    boringssl_context_add_handshake_message_pending(578) [C12.1:1][0x1151122e0] Adding message(2)
default    16:18:03.713747-0700    boringssl_context_message_handler(2258) [C12.1:1][0x1151122e0] Writing SSL3_RT_CHANGE_CIPHER_SPEC 1 bytes
default    16:18:03.713807-0700    boringssl_context_info_handler(1983) [C12.1:1][0x1151122e0] Client handshake state: TLS 1.3 client read_server_hello
default    16:18:03.713865-0700    boringssl_context_info_handler(1983) [C12.1:1][0x1151122e0] Client handshake state: TLS 1.3 client read_encrypted_extensions
default    16:18:03.714153-0700    boringssl_context_message_handler(2258) [C12.1:1][0x1151122e0] Reading SSL3_RT_HANDSHAKE 10 bytes
default    16:18:03.714219-0700    boringssl_context_info_handler(1983) [C12.1:1][0x1151122e0] Client handshake state: TLS 1.3 client read_certificate_request
default    16:18:03.714277-0700    boringssl_context_message_handler(2258) [C12.1:1][0x1151122e0] Reading SSL3_RT_HANDSHAKE 3105 bytes
default    16:18:03.714335-0700    boringssl_context_info_handler(1983) [C12.1:1][0x1151122e0] Client handshake state: TLS 1.3 client read_server_certificate
default    16:18:03.714395-0700    boringssl_context_info_handler(1983) [C12.1:1][0x1151122e0] Client handshake state: TLS 1.3 client read_server_certificate_verify
default    16:18:03.714452-0700    boringssl_context_message_handler(2258) [C12.1:1][0x1151122e0] Reading SSL3_RT_HANDSHAKE 264 bytes
default    16:18:03.714628-0700    boringssl_context_copy_peer_sct_list(1003) [C12.1:1][0x1151122e0] SSL_get0_signed_cert_timestamp_list returned no SCT extension data
default    16:18:03.714914-0700    boringssl_helper_create_sec_trust_with_certificates(607) [C12.1:1][0x1151122e0] SecTrustCreateWithCertificates result: 0
default    16:18:03.714973-0700    boringssl_helper_create_sec_trust_with_certificates(612) [C12.1:1][0x1151122e0] SecTrustSetOCSPResponse result: 0
default    16:18:03.715033-0700    boringssl_helper_create_sec_trust_with_certificates(621) [C12.1:1][0x1151122e0] No TLS-provided SCTs
default    16:18:03.715167-0700    boringssl_context_certificate_verify_callback(2071) [C12.1:1][0x1151122e0] Asyncing for verify block
default    16:18:03.715225-0700    boringssl_session_handshake_incomplete(170) [C12.1:1][0x1151122e0] Handshake incomplete: certificate evaluation result pending [16]
default    16:18:03.715418-0700    boringssl_context_certificate_verify_callback(2040) [C12.1:1][0x1151122e0] Verification already in progress.
default    16:18:03.715481-0700    boringssl_session_handshake_incomplete(170) [C12.1:1][0x1151122e0] Handshake incomplete: certificate evaluation result pending [16]
default    16:18:03.716084-0700    boringssl_context_certificate_verify_callback(2040) [C12.1:1][0x1151122e0] Verification already in progress.
default    16:18:03.716145-0700    boringssl_session_handshake_incomplete(170) [C12.1:1][0x1151122e0] Handshake incomplete: certificate evaluation result pending [16]
default    16:19:16.180121-0700    boringssl_context_message_handler(2258) [C6.1:2][0x11321ccb0] Writing SSL3_RT_ALERT 2 bytes
default    16:19:16.180202-0700    boringssl_context_handle_warning_alert(1893) [C6.1:2][0x11321ccb0] write alert, level: warning, description: close notify
default    16:19:16.180285-0700    boringssl_session_disconnect(504) [C6.1:2][0x11321ccb0] SSL_shutdown 0
default    16:19:16.181104-0700    nw_protocol_boringssl_remove_input_handler(1012) [C6.1:2][0x11321ccb0] nw_protocol_boringssl_remove_input_handler forced true
default    16:19:16.181169-0700    nw_protocol_boringssl_remove_input_handler(1030) [C6.1:2][0x11321ccb0] Transferring nw_protocol_boringssl_t handle back into ARC for autorelease
default    16:19:33.510159-0700    boringssl_context_message_handler(2258) [C8.1:2][0x11328fd50] Writing SSL3_RT_ALERT 2 bytes
default    16:19:33.510247-0700    boringssl_context_handle_warning_alert(1893) [C8.1:2][0x11328fd50] write alert, level: warning, description: close notify
default    16:19:33.510309-0700    boringssl_session_disconnect(504) [C8.1:2][0x11328fd50] SSL_shutdown 0
default    16:19:33.510922-0700    nw_protocol_boringssl_remove_input_handler(1012) [C8.1:2][0x11328fd50] nw_protocol_boringssl_remove_input_handler forced true
default    16:19:33.511105-0700    nw_protocol_boringssl_remove_input_handler(1030) [C8.1:2][0x11328fd50] Transferring nw_protocol_boringssl_t handle back into ARC for autorelease


The NGINX server block for the end-point is:


server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name me.example.com;

    ssl_certificate /etc/letsencrypt/live/me.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/me.example.com/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/me.example.com/chain.pem;

    location /ws {
        proxy_pass http://upstreamserver;

        proxy_http_version  1.1;
        proxy_set_header    Upgrade $http_upgrade;
        proxy_set_header    Connection $connection_upgrade;
        proxy_set_header    Host $host;
        proxy_set_header     X-Real-IP $remote_addr;
        proxy_set_header     X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header     X-Forwarded-Protocol $scheme;
    }
}


Any thoughts on why this is an issue on iOS?


I've also asked this question on SO:

https://stackoverflow.com/questions/61513555/secure-websocket-connection-fails-on-ios-due-to-boringssl-certificate-verificati


Thanks in advance for any help/hints.

Answered by Systems Engineer in 417851022

There are a few things going on here; first you are correct that the handshake is failing due to the client not being unable to verify the server's certificate. The reason the client cannot verify the certificate on the server is because there is are no SCT (Signed Certificate Timestamps) values provided to the client for verification. Also the OSCP response is 0. Notice the lines:


boringssl_context_info_handler(1983) [C12.1:1][0x1151122e0] Client handshake state: TLS 1.3 client read_server_certificate_verify  
boringssl_context_message_handler(2258) [C12.1:1][0x1151122e0] Reading SSL3_RT_HANDSHAKE 264 bytes  
boringssl_context_copy_peer_sct_list(1003) [C12.1:1][0x1151122e0] SSL_get0_signed_cert_timestamp_list returned no SCT extension data  
boringssl_helper_create_sec_trust_with_certificates(607) [C12.1:1][0x1151122e0] SecTrustCreateWithCertificates result: 0  
boringssl_helper_create_sec_trust_with_certificates(612) [C12.1:1][0x1151122e0] SecTrustSetOCSPResponse result: 0  
boringssl_helper_create_sec_trust_with_certificates(621) [C12.1:1][0x1151122e0] No TLS-provided SCTs  
boringssl_context_certificate_verify_callback(2071) [C12.1:1][0x1151122e0] Asyncing for verify block  
boringssl_session_handshake_incomplete(170) [C12.1:1][0x1151122e0] Handshake incomplete: certificate evaluation result pending [16]  
boringssl_context_certificate_verify_callback(2040) [C12.1:1][0x1151122e0] Verification already in progress.  
boringssl_session_handshake_incomplete(170) [C12.1:1][0x1151122e0] Handshake incomplete: certificate evaluation result pending [16]  
boringssl_context_certificate_verify_callback(2040) [C12.1:1][0x1151122e0] Verification already in progress.  
boringssl_session_handshake_incomplete(170) [C12.1:1][0x1151122e0] Handshake incomplete: certificate evaluation result pending [16]  
boringssl_context_message_handler(2258) [C6.1:2][0x11321ccb0] Writing SSL3_RT_ALERT 2 bytes 


Second, the reason this works in the browser is because your browser may not be setting up the TLS connection with TLS 1.3. This means that certificate verification on both sides is not as strict as an iOS client trying to setup the connection as TLS 1.3. If the connection on browser side does work with TLS 1.3, the browser may not be failing on the lack of SCT data like iOS does.


My recommendation would be to try this again with embedded SCT values on the certificate, or, you could manually evaluate the trust yourself and decide if this should be a failure. I highly encourage you to take a look at my first recommendation as this will get you what you actually need over the long term.

<https://support.apple.com/en-us/HT205280>


Matt Eaton

DTS Engineering, CoreOS

meaton3 at apple.com

Accepted Answer

There are a few things going on here; first you are correct that the handshake is failing due to the client not being unable to verify the server's certificate. The reason the client cannot verify the certificate on the server is because there is are no SCT (Signed Certificate Timestamps) values provided to the client for verification. Also the OSCP response is 0. Notice the lines:


boringssl_context_info_handler(1983) [C12.1:1][0x1151122e0] Client handshake state: TLS 1.3 client read_server_certificate_verify  
boringssl_context_message_handler(2258) [C12.1:1][0x1151122e0] Reading SSL3_RT_HANDSHAKE 264 bytes  
boringssl_context_copy_peer_sct_list(1003) [C12.1:1][0x1151122e0] SSL_get0_signed_cert_timestamp_list returned no SCT extension data  
boringssl_helper_create_sec_trust_with_certificates(607) [C12.1:1][0x1151122e0] SecTrustCreateWithCertificates result: 0  
boringssl_helper_create_sec_trust_with_certificates(612) [C12.1:1][0x1151122e0] SecTrustSetOCSPResponse result: 0  
boringssl_helper_create_sec_trust_with_certificates(621) [C12.1:1][0x1151122e0] No TLS-provided SCTs  
boringssl_context_certificate_verify_callback(2071) [C12.1:1][0x1151122e0] Asyncing for verify block  
boringssl_session_handshake_incomplete(170) [C12.1:1][0x1151122e0] Handshake incomplete: certificate evaluation result pending [16]  
boringssl_context_certificate_verify_callback(2040) [C12.1:1][0x1151122e0] Verification already in progress.  
boringssl_session_handshake_incomplete(170) [C12.1:1][0x1151122e0] Handshake incomplete: certificate evaluation result pending [16]  
boringssl_context_certificate_verify_callback(2040) [C12.1:1][0x1151122e0] Verification already in progress.  
boringssl_session_handshake_incomplete(170) [C12.1:1][0x1151122e0] Handshake incomplete: certificate evaluation result pending [16]  
boringssl_context_message_handler(2258) [C6.1:2][0x11321ccb0] Writing SSL3_RT_ALERT 2 bytes 


Second, the reason this works in the browser is because your browser may not be setting up the TLS connection with TLS 1.3. This means that certificate verification on both sides is not as strict as an iOS client trying to setup the connection as TLS 1.3. If the connection on browser side does work with TLS 1.3, the browser may not be failing on the lack of SCT data like iOS does.


My recommendation would be to try this again with embedded SCT values on the certificate, or, you could manually evaluate the trust yourself and decide if this should be a failure. I highly encourage you to take a look at my first recommendation as this will get you what you actually need over the long term.

<https://support.apple.com/en-us/HT205280>


Matt Eaton

DTS Engineering, CoreOS

meaton3 at apple.com

Thanks for that insight @meaton, very helpful!


I tried a few things but still no luck and same output from Xcode and Console 😟


  1. Re-created the letsencrypt certificate and enaled "OCSP Must Staple" support. Verified with Qualys Server Test tool.
  2. Correctly configured NGINX with OCSP support (the previous certificate did not have the "CT Precertificate SCTs" extension)
  3. Checked the generated certificate with openssl and I now see the embedded SCT.
  4. Tried connecting to the end-point from the device and got the same errors as before. (No TLS-provided SCTs, etc)


I'm wondering if the old certificate is cached on the device. If it is, how would I clear it? I had HSTS enabled with 20 day max age on the domain so not sure if that affects anything on iOS.


Below is the output from running "openssl x509 -in cert.pem -text" (only showing relevant data)


Certificate:
    Data:
        X509v3 extensions:
            Authority Information Access:
                OCSP - URI:http://ocsp.int-x3.letsencrypt.org
                CA Issuers - URI:http://cert.int-x3.letsencrypt.org/

            TLS Feature:
                status_request
            X509v3 Certificate Policies:
                Policy: 2.23.140.1.2.1
                Policy: 1.3.6.1.4.1.44947.1.1.1
                  CPS: http://cps.letsencrypt.org

            CT Precertificate SCTs:
                Signed Certificate Timestamp:
                    Version   : v1 (0x0)
                    Log ID    : 5E:A7:73:F9:DF:56:C0:E7:B5:36:48:7D:D0:49:E0:32:
                                7A:91:9A:0C:84:A1:12:12:84:18:75:96:81:71:45:58
                    Timestamp : May  1 21:02:14.817 2020 GMT
                    Extensions: none
                    Signature : ecdsa-with-SHA256
                                30:45:02:20:2F:2C:22:85:50:DD:FD:DA:62:E9:60:BA:
                                95:6C:49:03:1E:9E:F9:6C:9F:AA:A0:17:65:7F:D7:D3:
                                A4:E7:CC:02:02:21:00:D4:2F:55:CF:F6:57:AC:BF:3E:
                                E5:8B:F5:A2:00:47:2D:C4:5E:A4:10:EE:D7:D6:B4:FF:
                                9E:21:1D:CC:6A:89:53
                Signed Certificate Timestamp:
                    Version   : v1 (0x0)
                    Log ID    : 07:B7:5C:1B:E5:7D:68:FF:F1:B0:C6:1D:23:15:C7:BA:
                                E6:57:7C:57:94:B7:6A:EE:BC:61:3A:1A:69:D3:A2:1C
                    Timestamp : May  1 21:02:14.843 2020 GMT
                    Extensions: none
                    Signature : ecdsa-with-SHA256
                                30:44:02:20:17:63:1D:8E:76:CA:E0:A2:5C:42:92:7C:
                                BC:06:60:C7:9B:46:BB:59:63:8F:E1:8A:BE:52:CB:15:
                                FD:C4:DE:09:02:20:28:EF:48:E1:4B:BD:9D:05:29:52:
                                FC:D9:5A:8B:82:08:9D:1A:A0:58:F0:33:FB:05:5E:E7:
                                56:A0:AE:64:84:C7


Viewing the certificate from Firefox or Safari indicates the embedded SCT log provider is Cloudfare and Google and the OSCP url seems valid.


For reference I found these 2 articles about how LetsEncrypt approaches embedding SCTs:


Signed Certificate Timestamps embedded in certificates

Engineering deep dive: Encoding of SCTs in certificates

Excellent. It looks like you now have 2 SCTs on the certificate. You could try restarting the device to see if that is the case, but I'm thinking something else is going on here.


What do your BoringSSL logs say now?


Also, what Apple API are you using here in your WebSocket connection?


One last thing, a packet trace with tell you also tell you where the break-down is if you still come up empty.


Matt Eaton

DTS Engineering, CoreOS

meaton3 at apple.com

I created a package to help with web sockets and the new apple TLS restrictions, has some good info about creating certificates, I found a method that works really well. The code package is all you need to get started with a socket connection and send and receive data.


https://github.com/eamonwhiter73/IOSObjCWebSockets/tree/master

Success! Connecting the secure websocket end-point now works. The changes I made (substituted my real domain with domain.example.com):


  1. Re-create letsencrypt certificate with "OCSP Must Staple" support
    certbot --nginx --hsts --staple-ocsp --must-staple -d domain.example.com
  2. Update NGINX config:
    * Properly support OCSP
    * Removed HTTP/2 from server block
    * ssl_trusted_certificate has to specify a certificate with embedded SCT (Signed Certificate Timestamps)
  3. Update iOS websocket library (Starscream) to latest version (v4.0.3)
    * This latest version uses URLSessionWebSocketTask for iOS 13+ and for iOS 12 seems to be overriding the verification to return true if certificate pinning is disabled. Still need to try with cert pinning enabled to see what happens

NGINX Update

     map $http_upgrade $connection_upgrade {
         default upgrade;
         '' close;
     }

     upstream ws-signal {
         server localhost:8080;
     }

    server {
        listen 443 ssl;
        listen [::]:443 ssl;
        server_name domain.example.com;
     
        ssl_certificate /etc/letsencrypt/live/domain.example.com/fullchain.pem; # managed by Certbot
        ssl_certificate_key /etc/letsencrypt/live/domain.example.com/privkey.pem; # managed by Certbot

        # OCSP Stapling
        ssl_stapling on;
        ssl_stapling_verify on;
        ssl_trusted_certificate /etc/letsencrypt/live/domain.example.com/fullchain.pem;
        resolver 8.8.8.8 8.8.4.4;

        location /ws {
            proxy_pass http://ws-signal;

            proxy_http_version      1.1;
            proxy_set_header        Upgrade $http_upgrade;
            proxy_set_header        Connection $connection_upgrade;
            proxy_set_header        Host $host;
        }
    }


Xcode and Console logs are below:


XCode (iOS 12.4.6 device)

2020-05-04 15:16:49.015893-0700 ViewLive[234:4296] [Common] _BSMachError: port 13d13; (os/kern) invalid capability (0x14) "Unable to insert COPY_SEND"
websocket is connected: ["Strict-Transport-Security": "max-age=15552000; includeSubDomains", "Connection": "upgrade", "Upgrade": "websocket", "Date": "Mon, 04 May 2020 22:16:49 GMT", "Server": "nginx", "Sec-WebSocket-Accept": "/eit0Y/X5rQ5VC5+1V6s3gJTd7I="]


Console (iOS 12.4.6 device -- no boring ssl warnings/failures)

default    15:16:48.972613-0700    [C11 domain.example.com:443 tcp, tls, indefinite] start
default    15:16:48.973726-0700    nw_connection_report_state_with_handler_locked [C11] reporting state preparing
default    15:16:49.602958-0700    nw_endpoint_flow_protocol_connected [C11.1 76.90.112.55:443 in_progress channel-flow (satisfied)] Transport protocol connected
default    15:16:50.021828-0700    nw_endpoint_flow_protocol_connected [C11.1 76.90.112.55:443 in_progress channel-flow (satisfied)] Output protocol connected
default    15:16:50.185451-0700    nw_connection_report_state_with_handler_locked [C11] reporting state ready
default    15:17:48.618618-0700    success removing entry for host firebaseremoteconfig.googleapis.com config 0x280160f80
default    15:17:48.619211-0700    TIC TCP Conn Cancel [6:0x28347c000]


XCode (iOS 13.4.1 device)

websocket is connected: ["Server": "nginx", "Upgrade": "websocket", "Strict-Transport-Security": "max-age=15552000; includeSubDomains", "Date": "Mon, 04 May 2020 22:27:32 GMT", "Sec-WebSocket-Accept": "KaMepQ15ll91KPt6r2BxmQqoW+I=", "Connection": "upgrade"]


Console (iOS 13.4.1 device)

default    15:27:31.983995-0700    [C11 1FF387F7-5917-466E-AAD1-40CF48D84A09 domain.example.com:443 tcp, tls, indefinite] start
default    15:27:31.987035-0700    nw_connection_report_state_with_handler_on_nw_queue [C11] reporting state preparing
default    15:27:32.388881-0700    tcp_output [C11.1:2] flags=[S] seq=3061544366, ack=0, win=65535 state=SYN_SENT rcv_nxt=0, snd_una=3061544366
default    15:27:32.393637-0700    tcp_input [C11.1:2] flags=[S.] seq=385384344, ack=3061544367, win=65160 state=SYN_SENT rcv_nxt=0, snd_una=3061544366
default    15:27:32.393783-0700    nw_flow_connected [C11.1 76.90.112.55:443 in_progress channel-flow (satisfied (Path is satisfied), interface: en0, ipv4, ipv6, dns)] Transport protocol connected
default    15:27:32.393929-0700    boringssl_context_set_handshake_config(1471) [0x13dfd6bd0] set tls_handshake_config_standard
default    15:27:32.394277-0700    boringssl_context_set_min_version(324) [0x13dfd6bd0] set 0x0301
default    15:27:32.394325-0700    boringssl_context_set_max_version(308) [0x13dfd6bd0] set 0x0304
default    15:27:32.394372-0700    boringssl_context_set_cipher_suites(843) [0x13dfd6bd0] Ciphersuite string: TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-CHACHA20-POLY1305:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:AES256-SHA:AES128-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:DES-CBC3-SHA
default    15:27:32.394421-0700    boringssl_context_set_remote_address(2555) [0x13dfd6bd0] Saving remote IPv4 address
default    15:27:32.394471-0700    boringssl_session_install_association_state(1262) [0x13dfd6bd0] Client session cache miss
default    15:27:32.394517-0700    boringssl_session_set_peer_hostname(1154) [0x13dfd6bd0] SNI domain.example.com
default    15:27:32.394623-0700    boringssl_context_set_fallback(374) [C11.1:1][0x13dfd6bd0] set false
default    15:27:32.394668-0700    boringssl_context_set_session_ticket_enabled(440) [C11.1:1][0x13dfd6bd0] set false
default    15:27:32.394718-0700    boringssl_context_set_false_start(410) [C11.1:1][0x13dfd6bd0] set false
default    15:27:32.394767-0700    boringssl_context_set_enforce_ev(400) [C11.1:1][0x13dfd6bd0] set false
default    15:27:32.394813-0700    boringssl_context_set_ats_enforced(1285) [C11.1:1][0x13dfd6bd0] set false
default    15:27:32.394857-0700    boringssl_context_set_ats_minimum_rsa_key_size(1294) [C11.1:1][0x13dfd6bd0] set 0
default    15:27:32.394902-0700    boringssl_context_set_ats_minimum_ecdsa_key_size(1303) [C11.1:1][0x13dfd6bd0] set 0
default    15:27:32.395034-0700    boringssl_context_set_ats_minimum_signature_algorithm(1313) [C11.1:1][0x13dfd6bd0] set 0
default    15:27:32.395085-0700    nw_protocol_boringssl_begin_connection(497) [C11.1:1][0x13dfd6bd0] early data disabled
default    15:27:32.395129-0700    boringssl_context_info_handler(1970) [C11.1:1][0x13dfd6bd0] Client handshake started
default    15:27:32.395260-0700    boringssl_context_message_handler(2258) [C11.1:1][0x13dfd6bd0] Writing SSL3_RT_HANDSHAKE 512 bytes
default    15:27:32.395322-0700    boringssl_context_info_handler(1983) [C11.1:1][0x13dfd6bd0] Client handshake state: TLS client enter_early_data
default    15:27:32.395369-0700    boringssl_context_add_handshake_message_pending(578) [C11.1:1][0x13dfd6bd0] Adding message(1)
default    15:27:32.395556-0700    boringssl_context_info_handler(1983) [C11.1:1][0x13dfd6bd0] Client handshake state: TLS client read_server_hello
default    15:27:32.395602-0700    boringssl_context_add_handshake_message_pending(578) [C11.1:1][0x13dfd6bd0] Adding message(2)
default    15:27:32.395648-0700    boringssl_session_handshake_incomplete(170) [C11.1:1][0x13dfd6bd0] Handshake incomplete: waiting for data to read [2]
default    15:27:32.395694-0700    boringssl_session_handshake_incomplete(170) [C11.1:1][0x13dfd6bd0] Handshake incomplete: waiting for data to read [2]
default    15:27:32.395776-0700    boringssl_session_handshake_incomplete(170) [C11.1:1][0x13dfd6bd0] Handshake incomplete: waiting for data to read [2]
default    15:27:32.395824-0700    boringssl_session_handshake_incomplete(170) [C11.1:1][0x13dfd6bd0] Handshake incomplete: waiting for data to read [2]
default    15:27:32.396337-0700    boringssl_session_handshake_incomplete(170) [C11.1:1][0x13dfd6bd0] Handshake incomplete: waiting for data to read [2]
default    15:27:32.396384-0700    boringssl_session_handshake_incomplete(170) [C11.1:1][0x13dfd6bd0] Handshake incomplete: waiting for data to read [2]
default    15:27:32.396848-0700    boringssl_context_message_handler(2258) [C11.1:1][0x13dfd6bd0] Reading SSL3_RT_HANDSHAKE 122 bytes
default    15:27:32.396898-0700    boringssl_context_info_handler(1983) [C11.1:1][0x13dfd6bd0] Client handshake state: TLS 1.3 client read_hello_retry_request
default    15:27:32.396944-0700    boringssl_context_add_handshake_message_pending(578) [C11.1:1][0x13dfd6bd0] Adding message(2)
default    15:27:32.396994-0700    boringssl_context_message_handler(2258) [C11.1:1][0x13dfd6bd0] Writing SSL3_RT_CHANGE_CIPHER_SPEC 1 bytes
default    15:27:32.397039-0700    boringssl_context_info_handler(1983) [C11.1:1][0x13dfd6bd0] Client handshake state: TLS 1.3 client read_server_hello
default    15:27:32.397083-0700    boringssl_context_info_handler(1983) [C11.1:1][0x13dfd6bd0] Client handshake state: TLS 1.3 client read_encrypted_extensions
default    15:27:32.397134-0700    boringssl_context_message_handler(2258) [C11.1:1][0x13dfd6bd0] Reading SSL3_RT_HANDSHAKE 10 bytes
default    15:27:32.397178-0700    boringssl_context_info_handler(1983) [C11.1:1][0x13dfd6bd0] Client handshake state: TLS 1.3 client read_certificate_request
default    15:27:32.397227-0700    boringssl_session_handshake_incomplete(170) [C11.1:1][0x13dfd6bd0] Handshake incomplete: waiting for data to read [2]
default    15:27:32.397275-0700    boringssl_context_message_handler(2258) [C11.1:1][0x13dfd6bd0] Reading SSL3_RT_HANDSHAKE 3123 bytes
default    15:27:32.399467-0700    boringssl_context_info_handler(1983) [C11.1:1][0x13dfd6bd0] Client handshake state: TLS 1.3 client read_server_certificate
default    15:27:32.399707-0700    boringssl_context_info_handler(1983) [C11.1:1][0x13dfd6bd0] Client handshake state: TLS 1.3 client read_server_certificate_verify
default    15:27:32.399780-0700    boringssl_context_message_handler(2258) [C11.1:1][0x13dfd6bd0] Reading SSL3_RT_HANDSHAKE 264 bytes
default    15:27:32.399876-0700    boringssl_context_copy_peer_sct_list(1003) [C11.1:1][0x13dfd6bd0] SSL_get0_signed_cert_timestamp_list returned no SCT extension data
default    15:27:32.400002-0700    boringssl_helper_create_sec_trust_with_certificates(607) [C11.1:1][0x13dfd6bd0] SecTrustCreateWithCertificates result: 0
default    15:27:32.400289-0700    boringssl_helper_create_sec_trust_with_certificates(612) [C11.1:1][0x13dfd6bd0] SecTrustSetOCSPResponse result: 0
default    15:27:32.400340-0700    boringssl_helper_create_sec_trust_with_certificates(621) [C11.1:1][0x13dfd6bd0] No TLS-provided SCTs
default    15:27:32.400415-0700    boringssl_context_certificate_verify_callback(2071) [C11.1:1][0x13dfd6bd0] Asyncing for verify block
default    15:27:32.400499-0700    boringssl_session_handshake_incomplete(170) [C11.1:1][0x13dfd6bd0] Handshake incomplete: certificate evaluation result pending [16]
default    15:27:32.407354-0700    boringssl_context_certificate_verify_callback_block_invoke_3(2080) [C11.1:1][0x13dfd6bd0] Returning from verify block
default    15:27:32.407439-0700    boringssl_context_certificate_verify_callback(2047) [C11.1:1][0x13dfd6bd0] Setting trust result to ssl_verify_ok
default    15:27:32.407522-0700    boringssl_context_info_handler(1983) [C11.1:1][0x13dfd6bd0] Client handshake state: TLS 1.3 client read_server_finished
default    15:27:32.407588-0700    boringssl_context_message_handler(2258) [C11.1:1][0x13dfd6bd0] Reading SSL3_RT_HANDSHAKE 52 bytes
default    15:27:32.407636-0700    boringssl_context_info_handler(1983) [C11.1:1][0x13dfd6bd0] Client handshake state: TLS 1.3 client send_end_of_early_data
default    15:27:32.407685-0700    boringssl_context_info_handler(1983) [C11.1:1][0x13dfd6bd0] Client handshake state: TLS 1.3 client send_client_certificate
default    15:27:32.407834-0700    boringssl_context_info_handler(1983) [C11.1:1][0x13dfd6bd0] Client handshake state: TLS 1.3 client complete_second_flight
default    15:27:32.407952-0700    boringssl_context_message_handler(2258) [C11.1:1][0x13dfd6bd0] Writing SSL3_RT_HANDSHAKE 52 bytes
default    15:27:32.408000-0700    boringssl_context_info_handler(1983) [C11.1:1][0x13dfd6bd0] Client handshake state: TLS 1.3 client done
default    15:27:32.408046-0700    boringssl_context_info_handler(1983) [C11.1:1][0x13dfd6bd0] Client handshake state: TLS client finish_client_handshake
default    15:27:32.408413-0700    boringssl_context_info_handler(1983) [C11.1:1][0x13dfd6bd0] Client handshake state: TLS client done
default    15:27:32.408483-0700    boringssl_context_copy_peer_sct_list(1003) [C11.1:1][0x13dfd6bd0] SSL_get0_signed_cert_timestamp_list returned no SCT extension data
default    15:27:32.408567-0700    boringssl_helper_create_sec_trust_with_certificates(607) [C11.1:1][0x13dfd6bd0] SecTrustCreateWithCertificates result: 0
default    15:27:32.408718-0700    boringssl_helper_create_sec_trust_with_certificates(612) [C11.1:1][0x13dfd6bd0] SecTrustSetOCSPResponse result: 0
default    15:27:32.408809-0700    boringssl_helper_create_sec_trust_with_certificates(621) [C11.1:1][0x13dfd6bd0] No TLS-provided SCTs
default    15:27:32.408889-0700    boringssl_context_add_handshake_message_pending(578) [C11.1:1][0x13dfd6bd0] Adding message(20)
default    15:27:32.408955-0700    boringssl_context_info_handler(1974) [C11.1:1][0x13dfd6bd0] Client handshake done
default    15:27:32.409006-0700    nw_protocol_boringssl_signal_connected(701) [C11.1:1][0x13dfd6bd0] TLS connected [version(0x0304) ciphersuite(0x1302) group(0x001d) peer_key(0x0804) alpn() resumed(0) offered_ticket(0) false_started(0) ocsp(0) sct(0)]
default    15:27:32.409084-0700    nw_flow_connected [C11.1 76.90.112.55:443 in_progress channel-flow (satisfied (Path is satisfied), interface: en0, ipv4, ipv6, dns)] Output protocol connected
default    15:27:32.409284-0700    nw_connection_report_state_with_handler_on_nw_queue [C11] reporting state ready
default    15:27:32.409454-0700    boringssl_context_message_handler(2258) [C11.1:1][0x13dfd6bd0] Reading SSL3_RT_HANDSHAKE 65 bytes
default    15:27:32.409537-0700    boringssl_context_new_session_handler(1117) [C11.1:1][0x13dfd6bd0] New session available
default    15:27:32.409588-0700    boringssl_context_message_handler(2258) [C11.1:1][0x13dfd6bd0] Reading SSL3_RT_HANDSHAKE 65 bytes
default    15:27:32.409634-0700    boringssl_context_new_session_handler(1117) [C11.1:1][0x13dfd6bd0] New session available

Thank you for sharing your findings. A few things stick out to me of importance; first the server's certificate now includes SCT value's embedded in it. That's important for verification.


Second, I didn't notice it before, but I do see you're doing an HTTP upgrade to an upstream server. This may have been giving you problems as well going from secure HTTPS/2 -> HTTP -> HTTPS/1.1.



Matt Eaton

DTS Engineering, CoreOS

meaton3 at apple.com

BoringSSL certificate verification failure when connecting to secure websocket on iOS
 
 
Q