grpc / grpc-swift

The Swift language implementation of gRPC.
Apache License 2.0
2.01k stars 416 forks source link

How to do mutual TLS using signed cert received from Server and OverrideAuthority #978

Closed BioZrod closed 3 years ago

BioZrod commented 3 years ago

What are you trying to achieve?

I am trying to connect to a remote server using mutual TLS. First I created a GRPC connection to bootstrap and get a signed cert from server. Which successfully get a response from server and I get the cert bytes. After that using the signed cert I got from server I want to create a second GRPC connection but this connection requires me to set it using overrideAuthority, example of what I want to achieve in Java:

channel2 = OkHttpChannelBuilder.forAddress("example.com", 443) .useTransportSecurity() .sslSocketFactory(context.getSocketFactory()) .overrideAuthority("metricsd-example.com") .build(); MetricsControllerGrpc.MetricsControllerBlockingStub stub2 = MetricsControllerGrpc.newBlockingStub(channel2);

What have you tried so far?

I found the function withTLS(serverHostnameOverride: String) but i doesn't seem to change hostname when trying to connect to server. Also I read other issues and some pointed that it might be important the order in which "withTLS" is called.

builder = ClientConnection.secure(group: group).withTLS(certificateChain: [serverSignedCert]).withTLS(privateKey: privKey).withTLS(trustRoots: configuration.trustRoots!).withTLS(serverHostnameOverride: self.METRICS_AUTHORITY_HEADER)

Here is the code of the function trying to set up the GRPC connection using withTLS(serverHostnameOverride: String)

self.CONTROLLER_ADDRESS = "example.com"
        self.CONTROLLER_PORT = 443
        self.METRICS_AUTHORITY_HEADER = "metricsd-" + CONTROLLER_ADDRESS

func CollectAndPushMetrics() {

        let certificateFileName = "rootca"
        let certificateFilePath = Bundle.main.path(forResource: certificateFileName, ofType: "pem")

        do {

            do {

                let pemCert = try NIOSSLCertificate.fromPEMFile(certificateFilePath!) // this is ROOTCA
                //Step i: get certificate

                let serverSignedCert = try NIOSSLCertificate(bytes: [UInt8](signedCert as Data), format: .der ) // This is Signed Cert

                let getquery : [String: Any] = [ kSecClass as String: kSecClassKey,
                                                kSecAttrApplicationTag as String: "csrKeyPrivate",
                                                kSecAttrKeyType as String: kSecAttrKeyTypeRSA,
                                                kSecReturnData as String: true]

                var tempPrivateKeyBits: CFTypeRef?
                SecItemCopyMatching(getquery as CFDictionary, &tempPrivateKeyBits)

                let privateKeyData = tempPrivateKeyBits as! Data
                let privatekeyBytes = [UInt8](privateKeyData)
                let privKey = try NIOSSLPrivateKey(bytes: privatekeyBytes , format: .der)// This is RSA Key that signed CSR

                //Step ii: create TLS configuration
                var configuration = TLSConfiguration.forClient()
                configuration.trustRoots = .certificates(pemCert)
                configuration.certificateChain = [.certificate(serverSignedCert)]
                configuration.privateKey = .privateKey(privKey)
                configuration.certificateVerification = .fullVerification

                //Step iii: generate SSL context
                //TODO: Figure out exactly why this step is needed and how it works
                do {
                    let sslContext = try NIOSSLContext(configuration: configuration)

                    do {
                        let handler = try NIOSSLClientHandler(context: sslContext, serverHostname: self.CONTROLLER_ADDRESS + "\(self.CONTROLLER_PORT)")
                        //Step iv: Create an event loop group
                        let group = MultiThreadedEventLoopGroup(numberOfThreads: 1)

                        //Step v: Create client connection builder

                        let builder: ClientConnection.Builder
                        builder = ClientConnection.secure(group: group).withTLS(certificateChain: [serverSignedCert]).withTLS(privateKey: privKey).withTLS(trustRoots: configuration.trustRoots!).withTLS(serverHostnameOverride: self.METRICS_AUTHORITY_HEADER)

                        //Step vi: Start the connection and create the client

                        let connection = builder.connect(host: self.CONTROLLER_ADDRESS , port: self.CONTROLLER_PORT)

                        print("Metricsd Connection Status=>: \(connection)")

                        //Step vii: Create client
                        let client: MetricsControllerClient = MetricsControllerClient(channel: connection)

                        //Step viii: Call specific service request
                        let collect = client.collect(metricContainer)

                        collect.response.whenComplete { result in
                            print("Output for Collect Response request: \(result)")
                        }

                        collect.response.whenFailure { error in
                            print("Output for Collect Response failed request: \(error)")
                        }

                    } catch {
                        print("Error setting NIOSSLClientHandler: \(error)")
                        return
                    }
                } catch {
                    print("Error setting NIOSSLContext: \(error)")
                    return
                }

            } catch {
                print("Error Creating NIOSSLCertificate from signed Cert: \(error)")
            }

        }

    }
glbrntt commented 3 years ago

Also I read other issues and some pointed that it might be important the order in which "withTLS" is called.

That isn't correct: the order doesn't matter here.

What's the output when running your code?


Just a note: the following code isn't necessary; the TLS configuration you're making here is mirroring exactly what you're doing with the withTLS(...) functions on the builder. The same goes for creating the context and handler; this is all done internally by gRPC, you don't need to do this.

                //Step ii: create TLS configuration
                var configuration = TLSConfiguration.forClient()
                configuration.trustRoots = .certificates(pemCert)
                configuration.certificateChain = [.certificate(serverSignedCert)]
                configuration.privateKey = .privateKey(privKey)
                configuration.certificateVerification = .fullVerification

                //Step iii: generate SSL context
                //TODO: Figure out exactly why this step is needed and how it works
                do {
                    let sslContext = try NIOSSLContext(configuration: configuration)

                    do {
                        let handler = try NIOSSLClientHandler(context: sslContext, serverHostname: self.CONTROLLER_ADDRESS + "\(self.CONTROLLER_PORT)")
BioZrod commented 3 years ago

Also I read other issues and some pointed that it might be important the order in which "withTLS" is called.

That isn't correct: the order doesn't matter here.

What's the output when running your code?

Just a note: the following code isn't necessary; the TLS configuration you're making here is mirroring exactly what you're doing with the withTLS(...) functions on the builder. The same goes for creating the context and handler; this is all done internally by gRPC, you don't need to do this.

                //Step ii: create TLS configuration
                var configuration = TLSConfiguration.forClient()
                configuration.trustRoots = .certificates(pemCert)
                configuration.certificateChain = [.certificate(serverSignedCert)]
                configuration.privateKey = .privateKey(privKey)
                configuration.certificateVerification = .fullVerification

                //Step iii: generate SSL context
                //TODO: Figure out exactly why this step is needed and how it works
                do {
                    let sslContext = try NIOSSLContext(configuration: configuration)

                    do {
                        let handler = try NIOSSLClientHandler(context: sslContext, serverHostname: self.CONTROLLER_ADDRESS + "\(self.CONTROLLER_PORT)")

Thank for pointing out I have duplicated code I will remove it and see how it goes. On the console while running the code I can only see this that is related to grpc after a couple of seconds. But I can't see the client.collect.response.whenComplete Output.

2020-09-29T11:17:59-0500 info: connection_id=2221BEA1-F99C-4242-A178-DEA172B4525F/0 event_loop=SelectableEventLoop { selector = Selector { descriptor = 3 }, thread = NIOThread(name = NIO-ELT-0-#0) } remote_address=[IPv4]100.24.223.5/100.24.223.5:443 gRPC connection ready

2 questions:

glbrntt commented 3 years ago
  • How Can i print or see more info on what GRPC code is doing.

This depends slightly on what version of gRPC Swift you're using. I'll answer assuming you're using alpha-18 or newer.

gRPC Swift uses SwiftLog which provides a logging API. By default there is no logging backend, that is, logs are dropped by default, so you need to configure both a logging backend (to configure how logs are handled) and then pass a logger to gRPC.

SwiftLog comes with a logging backend for printing to stdout/stderr, there are some docs here.

You'll then to create a logger, and pass that to gRPC. For the client, gRPC accepts two different loggers: a background logger (for connection level information) and a request logger for, well, request level information.

The background logger is set on the builder with withBackgroundActivityLogger, and request level loggers can be provided in the CallOptions.

Note that you may want to increase the level of these loggers to .debug, either when bootstrapping the LoggingSystem or on the Logger you pass to gRPC.

  • If I delete the configuration, then how can I set the "configuration.certificateVerification = .fullVerification" flag.

.fullVerification is the default for clients. However, this option appears to be missing from the builder, I'll fix that.

BioZrod commented 3 years ago

Hey hello again thank for your help so far, I got the logger set up and got the following logs: (Swift Grpc alpha-19)

2020-09-30T10:48:04-0500 info gRPC : grpc_connection_id=B6A79F1E-67B0-455F-BD08-3DA4E2023876/0 new_state=connecting old_state=idle connectivity state change
2020-09-30T10:48:04-0500 debug gRPC : grpc_connection_id=B6A79F1E-67B0-455F-BD08-3DA4E2023876/0 connectivity_state=connecting vending channel future
2020-09-30T10:48:04-0500 debug gRPC : grpc_connection_id=B6A79F1E-67B0-455F-BD08-3DA4E2023876/0 making client bootstrap with event loop group of type SelectableEventLoop
2020-09-30T10:48:04-0500 debug gRPC : grpc_connection_id=B6A79F1E-67B0-455F-BD08-3DA4E2023876/0 Network.framework is available but the group is not typed for NIOTS, falling back to ClientBootstrap
2020-09-30T10:48:04-0500 debug gRPC : grpc_connection_id=B6A79F1E-67B0-455F-BD08-3DA4E2023876/0 creating a ClientBootstrap
2020-09-30T10:48:04-0500 debug gRPC : grpc_connection_id=B6A79F1E-67B0-455F-BD08-3DA4E2023876/0 connectivity_state=connecting activating connection
2020-09-30T10:48:04-0500 error gRPC : grpc_connection_id=B6A79F1E-67B0-455F-BD08-3DA4E2023876/0 error=handshakeFailed(NIOSSL.BoringSSLError.sslError([Error: 268435709 error:100000fd:SSL routines:OPENSSL_internal:NO_COMMON_SIGNATURE_ALGORITHMS])) grpc client error
2020-09-30T10:48:04-0500 debug gRPC : connectivity_state=active grpc_connection_id=B6A79F1E-67B0-455F-BD08-3DA4E2023876/0 deactivating connection
2020-09-30T10:48:04-0500 debug gRPC : grpc_connection_id=B6A79F1E-67B0-455F-BD08-3DA4E2023876/0 delay_secs=1.0 scheduling connection attempt
2020-09-30T10:48:04-0500 info gRPC : grpc_connection_id=B6A79F1E-67B0-455F-BD08-3DA4E2023876/0 new_state=transientFailure old_state=connecting connectivity state change
2020-09-30T10:48:05-0500 info gRPC : grpc_connection_id=B6A79F1E-67B0-455F-BD08-3DA4E2023876/0 new_state=connecting old_state=transientFailure connectivity state change
2020-09-30T10:48:05-0500 debug gRPC : grpc_connection_id=B6A79F1E-67B0-455F-BD08-3DA4E2023876/0 making client bootstrap with event loop group of type SelectableEventLoop
2020-09-30T10:48:05-0500 debug gRPC : grpc_connection_id=B6A79F1E-67B0-455F-BD08-3DA4E2023876/0 Network.framework is available but the group is not typed for NIOTS, falling back to ClientBootstrap
2020-09-30T10:48:05-0500 debug gRPC : grpc_connection_id=B6A79F1E-67B0-455F-BD08-3DA4E2023876/0 creating a ClientBootstrap
locationManager(_:didUpdateLocations:) <-16.39021490,-71.55000234> +/- 30.00m (speed 0.00 mps / course -1.00) @ 9/30/20, 10:48:05 AM Peru Standard Time
2020-09-30T10:48:06-0500 debug gRPC : grpc_connection_id=B6A79F1E-67B0-455F-BD08-3DA4E2023876/0 connectivity_state=connecting activating connection
2020-09-30T10:48:06-0500 error gRPC : grpc_connection_id=B6A79F1E-67B0-455F-BD08-3DA4E2023876/0 error=handshakeFailed(NIOSSL.BoringSSLError.sslError([Error: 268435709 error:100000fd:SSL routines:OPENSSL_internal:NO_COMMON_SIGNATURE_ALGORITHMS])) grpc client error
2020-09-30T10:48:06-0500 debug gRPC : grpc_connection_id=B6A79F1E-67B0-455F-BD08-3DA4E2023876/0 connectivity_state=active deactivating connection
2020-09-30T10:48:06-0500 debug gRPC : grpc_connection_id=B6A79F1E-67B0-455F-BD08-3DA4E2023876/0 delay_secs=1.4619619026107884 scheduling connection attempt
2020-09-30T10:48:06-0500 info gRPC : grpc_connection_id=B6A79F1E-67B0-455F-BD08-3DA4E2023876/0 new_state=transientFailure old_state=connecting connectivity state change
locationManager(_:didUpdateLocations:) <-16.39021490,-71.55000234> +/- 30.00m (speed 0.00 mps / course -1.00) @ 9/30/20, 10:48:06 AM Peru Standard Time
2020-09-30T10:48:07-0500 info gRPC : grpc_connection_id=B6A79F1E-67B0-455F-BD08-3DA4E2023876/0 new_state=connecting old_state=transientFailure connectivity state change
2020-09-30T10:48:07-0500 debug gRPC : grpc_connection_id=B6A79F1E-67B0-455F-BD08-3DA4E2023876/0 making client bootstrap with event loop group of type SelectableEventLoop
2020-09-30T10:48:07-0500 debug gRPC : grpc_connection_id=B6A79F1E-67B0-455F-BD08-3DA4E2023876/0 Network.framework is available but the group is not typed for NIOTS, falling back to ClientBootstrap
2020-09-30T10:48:07-0500 debug gRPC : grpc_connection_id=B6A79F1E-67B0-455F-BD08-3DA4E2023876/0 creating a ClientBootstrap
2020-09-30T10:48:08-0500 debug gRPC : connectivity_state=connecting grpc_connection_id=B6A79F1E-67B0-455F-BD08-3DA4E2023876/0 activating connection
2020-09-30T10:48:08-0500 error gRPC : grpc_connection_id=B6A79F1E-67B0-455F-BD08-3DA4E2023876/0 error=handshakeFailed(NIOSSL.BoringSSLError.sslError([Error: 268435709 error:100000fd:SSL routines:OPENSSL_internal:NO_COMMON_SIGNATURE_ALGORITHMS])) grpc client error
2020-09-30T10:48:08-0500 debug gRPC : grpc_connection_id=B6A79F1E-67B0-455F-BD08-3DA4E2023876/0 connectivity_state=active deactivating connection
2020-09-30T10:48:08-0500 debug gRPC : grpc_connection_id=B6A79F1E-67B0-455F-BD08-3DA4E2023876/0 delay_secs=2.6081436306815915 scheduling connection attempt
2020-09-30T10:48:08-0500 info gRPC : old_state=connecting new_state=transientFailure grpc_connection_id=B6A79F1E-67B0-455F-BD08-3DA4E2023876/0 connectivity state change
2020-09-30T10:48:10-0500 info gRPC : grpc_connection_id=B6A79F1E-67B0-455F-BD08-3DA4E2023876/0 new_state=connecting old_state=transientFailure connectivity state change
2020-09-30T10:48:10-0500 debug gRPC : grpc_connection_id=B6A79F1E-67B0-455F-BD08-3DA4E2023876/0 making client bootstrap with event loop group of type SelectableEventLoop
2020-09-30T10:48:10-0500 debug gRPC : grpc_connection_id=B6A79F1E-67B0-455F-BD08-3DA4E2023876/0 Network.framework is available but the group is not typed for NIOTS, falling back to ClientBootstrap
2020-09-30T10:48:10-0500 debug gRPC : grpc_connection_id=B6A79F1E-67B0-455F-BD08-3DA4E2023876/0 creating a ClientBootstrap
2020-09-30T10:48:10-0500 debug gRPC : grpc_connection_id=B6A79F1E-67B0-455F-BD08-3DA4E2023876/0 connectivity_state=connecting activating connection
2020-09-30T10:48:11-0500 error gRPC : grpc_connection_id=B6A79F1E-67B0-455F-BD08-3DA4E2023876/0 error=handshakeFailed(NIOSSL.BoringSSLError.sslError([Error: 268435709 error:100000fd:SSL routines:OPENSSL_internal:NO_COMMON_SIGNATURE_ALGORITHMS])) grpc client error
2020-09-30T10:48:11-0500 debug gRPC : grpc_connection_id=B6A79F1E-67B0-455F-BD08-3DA4E2023876/0 connectivity_state=active deactivating connection
2020-09-30T10:48:11-0500 debug gRPC : grpc_connection_id=B6A79F1E-67B0-455F-BD08-3DA4E2023876/0 delay_secs=3.6194117248219198 scheduling connection attempt
2020-09-30T10:48:11-0500 info gRPC : old_state=connecting new_state=transientFailure grpc_connection_id=B6A79F1E-67B0-455F-BD08-3DA4E2023876/0 connectivity state change`

It seems the error is in the handshake algorithm how can I change it?

2020-09-30T10:48:08-0500 error gRPC : grpc_connection_id=B6A79F1E-67B0-455F-BD08-3DA4E2023876/0 error=handshakeFailed(NIOSSL.BoringSSLError.sslError([Error: 268435709 error:100000fd:SSL routines:OPENSSL_internal:NO_COMMON_SIGNATURE_ALGORITHMS])) grpc client error

Also I don't understand this log:

2020-09-30T10:48:04-0500 debug gRPC : grpc_connection_id=B6A79F1E-67B0-455F-BD08-3DA4E2023876/0 Network.framework is available but the group is not typed for NIOTS, falling back to ClientBootstrap
2020-09-30T10:48:04-0500 debug gRPC : grpc_connection_id=B6A79F1E-67B0-455F-BD08-3DA4E2023876/0 creating a ClientBootstrap
glbrntt commented 3 years ago

Also I don't understand this log:

2020-09-30T10:48:04-0500 debug gRPC : grpc_connection_id=B6A79F1E-67B0-455F-BD08-3DA4E2023876/0 Network.framework is available but the group is not typed for NIOTS, falling back to ClientBootstrap
2020-09-30T10:48:04-0500 debug gRPC : grpc_connection_id=B6A79F1E-67B0-455F-BD08-3DA4E2023876/0 creating a ClientBootstrap

This relates to support for NIO Transport Services, if you provide a NIOTSEventLoopGroup rather than a MultiThreadedEventLoopGroup then you get a stack which uses Network.framework (there are a few details documented here). The log is just saying that Network.framework is supported on the platform you're running on (so we could use NIOTS) but the EventLoopGroup you provided isn't for NIO Transport Services. (It's not related to the problem you're seeing here.)


It seems the error is in the handshake algorithm how can I change it?

2020-09-30T10:48:08-0500 error gRPC : grpc_connection_id=B6A79F1E-67B0-455F-BD08-3DA4E2023876/0 error=handshakeFailed(NIOSSL.BoringSSLError.sslError([Error: 268435709 error:100000fd:SSL routines:OPENSSL_internal:NO_COMMON_SIGNATURE_ALGORITHMS])) grpc client error

We don't currently expose specifying the signature verification or signing algorithm in gRPC, however, doing so is supported in SwiftNIO SSL. Without setting it manually I assume we just defer to BoringSSL, presumably the default values don't overlap with what your server is offering. @Lukasa does that sound about right, and can you shed some light on the defaults? Presumably we want to expose those options in gRPC as well.

Lukasa commented 3 years ago

Sure. This is a fairly uncommon error!

For TLS 1.2 and later (which is almost certainly what we're seeing here) the two sets of signature algorithms are defined as follows. Firstly, in the Client Hello and Server Hello, each peer communicates what kinds of signatures it supports from the remote peer. Secondly, each implementation supports a number of signature algorithms depending on the specific private key type it is using.

In this instance the easiest way to debug this is to get a packet capture of the failing TLS Handshake to see what each peer offers.

BioZrod commented 3 years ago

Hello @Lukasa One question how can I change the maximun TLS to use to 1.2 and I think these are the packets from that handshake

packets.zip

Lukasa commented 3 years ago

Assuming that packet capture is right, both you and the remote peer are willing to negotiate (and indeed trying to negotiate) TLS 1.3. That's totally fine, there's nothing wrong with that. It does make it moderately harder to diagnose the actual problem, though, because the traffic is already encrypted. SwiftNIO SSL allows you to dump the keys but I don't think grpc-swift has the hooks to support it.

What's the server implementation in this case?

BioZrod commented 3 years ago

I don't have the server implementation. What the I got as a suggestion from whom implemented the connection to the server from an android app is to change my TLS to 1.2 if possible. And to check my RSA key as he run into an issue that he had to remove the padding on it.

So is there any way to change to TLS 1.2?

Lukasa commented 3 years ago

NIO will already negotiate TLS 1.2. By default it tries to support TLS 1.0 through TLS 1.3. If you were trying to raise the value you can use the TLSConfiguration object and set minVersion to .tlsv12.

glbrntt commented 3 years ago

Minor sidetone here; the gRPC spec requires TLS 1.2 as a minimum.

@BioZrod setting the maximum is possible but a little unfriendly in gRPC. You'll have to create your ClientConnection with a Configuration rather than via the builder. You'll also have to create the NIOSSL.TLSConfiguration manually, set the min and max TLS version and pass that to the gRPC wrapper here and set that on the Configuration.

BioZrod commented 3 years ago

Hello thank you for help the issue seems to be that when using tls 1.3 it was adding padding to the packet that for some reason made the server confused. @glbrntt With your help I managed to built the configuration and force it to use 1.2 and got rid of that error.

I got a new error but I am pretty sure it is unrelated to swift-grpc if you are curious here I attach the pcap for it. I am using other library [https://github.com/cbaker6/CertificateSigningRequest] to create a csr and then sent it to the server and successfully got a signed cert like this as Data here is as base64String:

MIICqzCCAZOgAwIBAgIQJHC8G7Yq/BM97KT93ulDTDANBgkqhkiG9w0BAQsFADA+MQswCQYDVQQGEwJVUzEvMC0GA1UEAwwmY2VydGlmaWVyLm9wZW5zY2hlbWEubWFnbWEuZXRhZ2Vjb20uaW8wHhcNMjAxMDA2MjIxMTUwWhcNMjAxMDA3MDE1ODMwWjB2MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExDTALBgNVBAcTBFRlc3QxDTALBgNVBAoTBFRlc3QxDTALBgNVBAsTBFRlc3QxLTArBgNVBAMTJDEzMDBFNEIwLTc0NjAtNEUwQi1BQjc2LTc0OTY4QUY0MTUyQTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQCp8kk2iLqHFGz98PDvqDM6Pbxc07WwV+Qyk0LmYPuGMgRJd5mzyCPkjI+qNQzCJhq147vXMTXfuJ5nfiOcJM3pAgMBAAGjNTAzMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDAjAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEBCwUAA4IBAQCXkxPxQUMYVJZ1AxQINNjwkiqZKURk58lGeKR0qx2ex3gF2+sRe3S47Kj9v1yO7c5LxVJgpGKVwgJZ50G1V0KJ5bMyOffHoztL/FC1blEBBLbuUudugLezRa2OLvm27M6X61KJrNN7H27S8CMiuLSd3odM90HXYGBW8vV3ZuL5SCK4x/X6cewBC3UbhmZxzNPrExrLxYcYrdqV76Qk3eoIi+Ma4Cc43SrA1fVR2wFVvW6VE4HXuzzI+am/MBuT0gozqpsnphB1q5+E4SnGO2thZq7Wo+Tw2M8+EhOiqHtTDagGnikLynHcDOZjfWNeeVTf2tyBRR8to+2Y4w3db66p

Then by using the 2 functions below I configure TLS with that signed cert and this private RSA key that I have stored in keychain

MIIBOgIBAAJBAKnySTaIuocUbP3w8O+oMzo9vFzTtbBX5DKTQuZg+4YyBEl3mbPII+SMj6o1DMImGrXju9cxNd+4nmd+I5wkzekCAwEAAQJATctLGFuehxcijVwt7obgbFi2UQfYs9CH9V7T0QG0Icki2vDBWxRz3413dM6dDMVpWHiA/7nsKhgrzJeTMEVgwQIhAO6mtqqjo3kyHEknwTiYPZTgZ7KXUdV9aeQZGvRlMAuTAiEAtkz62wc4ED5fsfEhEt80HCzZngAno0BGE2v8g2OHhhMCIQDN82deWTuhQqJwa3NvEMrMKOC0mavQjpuMcjH1yUEuKwIgA6nWXLJvcPwf5i6HUJ7FqE9KbD9qjIBNKDTCVU2ZupsCIF3Rtb3bjT2PA2A+zGuAXA8N3az17+ujZn4BPaARUr0f

If you by chance have any info on how this 2 functions from NIOSSL work and how they use the data from a cert retrieved from keychain in case of private key and just the data I received from server for signedcert it would very useful for me as there seems to be a mismatch there as I got the error: SSLV3_ALERT_BAD_CERTIFICATE

let serverSignedCert = try NIOSSLCertificate(bytes: [UInt8](signedCert as Data), format: .der ) // This is Signed Cert
let privKey = try NIOSSLPrivateKey(bytes: privatekeyBytes , format: .der)// This is RSA Key that signed CSR

Again thank you for your help so far.

tls12_iphone.zip

Lukasa commented 3 years ago

Did you base64 decode the strings?

BioZrod commented 3 years ago

After a little bit of trial and error I figured out the following issues:

I couldn't find any information on what that error might be generated from.

Logs from GRPC:

debug gRPC : grpc_connection_id=BC873BDD-05E4-4F6A-B5F8-2DBD1AB82B60/0 TLS handshake completed, negotiated protocol: h2

info gRPC : remote_address=[IPv4]52.22.179.166/52.22.179.166:443 event_loop=SelectableEventLoop { selector = Selector { descriptor = 9 }, thread = NIOThread(name = NIO-ELT-1-#0) } grpc_connection_id=BC873BDD-05E4-4F6A-B5F8-2DBD1AB82B60/0 gRPC connection ready

debug gRPC : connectivity_state=active grpc_connection_id=BC873BDD-05E4-4F6A-B5F8-2DBD1AB82B60/0 connection ready

info gRPC : new_state=ready old_state=connecting grpc_connection_id=BC873BDD-05E4-4F6A-B5F8-2DBD1AB82B60/0 connectivity state change

debug gRPC : h2_settings_max_concurrent_streams=100 grpc_connection_id=BC873BDD-05E4-4F6A-B5F8-2DBD1AB82B60/0 h2_settings_enable_connect_protocol=1 h2_settings_initial_window_size=65535 received initial HTTP2 settings

debug gRPC : h2_active_streams=1 grpc_connection_id=BC873BDD-05E4-4F6A-B5F8-2DBD1AB82B60/0 h2_stream_id=HTTP2StreamID(1) HTTP2 stream created

debug gRPC : h2_active_streams=0 grpc_connection_id=BC873BDD-05E4-4F6A-B5F8-2DBD1AB82B60/0 h2_stream_id=HTTP2StreamID(1) HTTP2 stream closed

Output for Collect Response request: failure(Invalid HTTP response status: 401)

error gRPC : grpc_connection_id=702B7434-F5E1-4A01-861B-63076EDBFF51/0 error=NoSuchStream(streamID: HTTP2StreamID(1)) grpc client error

debug gRPC : connectivity_state=ready grpc_connection_id=702B7434-F5E1-4A01-861B-63076EDBFF51/0 deactivating connection
glbrntt commented 3 years ago

HTTP response status: 401 is unauthorised. Are you setting an authorization header?

BioZrod commented 3 years ago

HTTP response status: 401 is unauthorised. Are you setting an authorization header?

No, How can I set it should it be the signed cert that I got from server?

BioZrod commented 3 years ago

Original issue with was solved by changing config to TLS 1.2 and using hostnameOVerride