wizeOnes
wizeOnes

Reputation: 129

What about my Swift-NIO-SSL handshake is failing?

I am trying to figure out what about my TLS handshake is failing. I am not exactly sure what this error code means. Can someone provide more context here?

2000-00-00T00:00:00-0000 error [[GRPC-LOGG]] : error=handshakeFailed(NIOSSL.BoringSSLError.sslError([Error: 268436496 error:10000410:SSL routines:OPENSSL_internal:SSLV3_ALERT_HANDSHAKE_FAILURE at /Users/username/Library/Developer/Xcode/DerivedData/ios-dc-bocetydygnmhxsdxqxaivnvasghk/SourcePackages/checkouts/swift-nio-ssl/Sources/CNIOBoringSSL/ssl/tls_record.cc:592])) grpc.conn.addr_local=10.220.93.246 grpc.conn.addr_remote=23.98.156.101 grpc_connection_id=C1C6376D-9F74-48AF-9D7A-D903BB68D716/0 [GRPC] grpc client error

I did take a look at the tls_record.cc file; which is reporting SSL3_AL_FATAL. The tls_record.cc can be seen below.

tls_record.cc

f (alert_level == SSL3_AL_FATAL) {
    OPENSSL_PUT_ERROR(SSL, SSL_AD_REASON_OFFSET + alert_descr);
    ERR_add_error_dataf("SSL alert number %d", alert_descr);
    *out_alert = 0;  // No alert to send back to the peer.
    return ssl_open_record_error;
  }



I am using gRPC-Swift to make this call.

        var clientConnection: ClientConnection.Builder

        var tlsConfig = TLSConfiguration.makeClientConfiguration()
        tlsConfig.certificateVerification = .noHostnameVerification
        tlsConfig.trustRoots = .certificates([nioCert!])
        
        let clientConfig = GRPCTLSConfiguration.makeClientConfigurationBackedByNIOSSL(configuration: tlsConfig, hostnameOverride: sniName)
        
        clientConnection = ClientConnection.usingTLS(with: clientConfig, on: eventLoopGroup)
                .withTLSCustomVerificationCallback({ ... })

        clientConnection.connect(host: hostName, port: port)
    



When running curl -v https://hostname:port/foo command, this is what I get back from the server:

*   Trying 12.43.425.642:443...
* Connected to q003.ed14.ws.samplecloud.dogi (12.43.425.642) port 443 (#0)
* ALPN: offers h2
* ALPN: offers http/1.1
*  CAfile: /etc/ssl/cert.pem
*  CApath: none
* (304) (OUT), TLS handshake, Client hello (1):
* LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to q003.ed14.ws.samplecloud.dogi:443 
* Closing connection 0
curl: (35) LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to q003.ed14.ws.samplecloud.dogi:443

I have added a ClientError Logger to the gRPC connection and this is what I am getting:

[!! GRPC-CLIENT-ERROR]: handshakeFailed(NIOSSL.BoringSSLError.sslError([Error: 268435581 error:1000007d:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED at /Users/username/Library/Developer/Xcode/DerivedData/ios-dc-bocetydygnmhxsdxqxaivnvasghk/SourcePackages/checkouts/swift-nio-ssl/Sources/CNIOBoringSSL/ssl/handshake.cc:393])) file:[<unknown>] line:[0]]



The error in the log above points back to the tls_record:

 if (alert_level == SSL3_AL_FATAL) {
    OPENSSL_PUT_ERROR(SSL, SSL_AD_REASON_OFFSET + alert_descr); // << this line
    ERR_add_error_dataf("SSL alert number %d", alert_descr);
    *out_alert = 0;  // No alert to send back to the peer.
    return ssl_open_record_error;
  }

I think there is an issue with how I am attaching my certificates. When I view the network traffic, I do not see any client certificate showing up in the TLS handshake:

Client Certificates: -
Server Certificates: 3

It seems as though I was attaching my certificates to swift-grpc's server part of the framework and not the client, this is how you attach them for the client-side:

        tlsConfig.certificateChain = [.certificate(nioCert!)]
        
        let privateKeyNIO = try? NIOSSLPrivateKey.init(bytes: privateKeyByteAry, format: .der)
        tlsConfig.privateKey = NIOSSLPrivateKeySource.privateKey(privateKeyNIO!)

Note that I am still getting the same error as reported above.

Update:

I have confirmed that the client certificates are not showing up in the request. I am not sure why this is the case; I am clearly attaching a client cert.


    tlsConfig.certificateChain = [NIOSSLCertificateSource.certificate(nioCert!)]
    let privateKeyNIO = try? NIOSSLPrivateKey.init(bytes: privateKeyByteAry, format: .der)
    tlsConfig.privateKey = NIOSSLPrivateKeySource.privateKey(privateKeyNIO!)

Upvotes: 0

Views: 787

Answers (0)

Related Questions