Error received from borring ssl if RSA private is not saved to keychain

I used secure enclave to encrypt my private key as a generic password as suggested by eskimo in https://developer.apple.com/forums/thread/682480?login=true&r_s_legacy=true

But if I don't save the private key also as a key to keychain, when I use the public key for network connection certification I receive an error from inside borring ssl and the network request fails: [boringssl] boringssl_private_key_sign(84) SecKeyCreateSignature failed: -50 [boringssl] boringssl_session_handshake_incomplete(90) [C17.1.1.1:2][0x11f2262d0] SSL library error [boringssl] boringssl_session_handshake_error_print(41) [C17.1.1.1:2][0x11f2262d0] Error: 4795274440:error:1000011f:SSL routines:OPENSSL_internal:PRIVATE_KEY_OPERATION_FAILED:/Library/Caches/com.apple.xbs/Sources/boringssl/boringssl-351.100.8.0.1/ssl/ssl_privkey.cc:220: [boringssl] nw_protocol_boringssl_handshake_negotiate_proceed(767) [C17.1.1.1:2][0x11f2262d0] handshake failed at state 12288: not completed [boringssl] boringssl_private_key_sign(84) SecKeyCreateSignature failed: -50 [boringssl] boringssl_session_handshake_incomplete(90) [C17.2.1.1:2][0x11f5259b0] SSL library error [boringssl] boringssl_session_handshake_error_print(41) [C17.2.1.1:2][0x11f5259b0] Error: 4795274440:error:1000011f:SSL routines:OPENSSL_internal:PRIVATE_KEY_OPERATION_FAILED:/Library/Caches/com.apple.xbs/Sources/boringssl/boringssl-351.100.8.0.1/ssl/ssl_privkey.cc:220: [boringssl] nw_protocol_boringssl_handshake_negotiate_proceed(767) [C17.2.1.1:2][0x11f5259b0] handshake failed at state 12288: not completed Connection 17: received failure notification Connection 17: failed to connect 3:-9858, reason -1 Connection 17: encountered error(3:-9858) [boringssl] boringssl_private_key_sign(84) SecKeyCreateSignature failed: -50 [boringssl] boringssl_session_handshake_incomplete(90) [C18.1.1.1:2][0x11dd87390] SSL library error [boringssl] boringssl_session_handshake_error_print(41) [C18.1.1.1:2][0x11dd87390] Error: 4795274440:error:1000011f:SSL routines:OPENSSL_internal:PRIVATE_KEY_OPERATION_FAILED:/Library/Caches/com.apple.xbs/Sources/boringssl/boringssl-351.100.8.0.1/ssl/ssl_privkey.cc:220: [boringssl] nw_protocol_boringssl_handshake_negotiate_proceed(767) [C18.1.1.1:2][0x11dd87390] handshake failed at state 12288: not completed

Any idea why this happens? Why does boring ssl need my private key to be persistent in the keychain?

when I use the public key for network connection certification

I don’t understand what you mean by this. Public keys don’t play much of a role in standard TLS [1], except insofar as they’re embedded with a certificate. Can you clarify how your public and private keys are flowing through your system?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] See the discussion in TLS for App Developers.

So, lemme see if I understand this correctly:

  1. You generate a private key using SecKeyCreateRandomKey.

  2. You get the public key using SecKeyCopyPublicKey.

  3. You send the public key to the server.

  4. It sends you back a certificate that’s wrapped around that public key.

Then what happens? In theory the certificate and the private key should form a digital identity, which you could then use with TLS. However, there’s no API for creating a digital identity from in-memory credentials. So how does these credentials get in to TLS?

And what API are you using for TLS? NSURLSession? Network framework? Or something else?

Oh, are you on macOS? Or an iOS-based platform?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

So far I’ve been assuming that your goal is to implement mutual TLS (mTLS), as defined by TLS for App Developers. If that’s not the case, let me know and I’ll reset my assumptions.

On the Alamofire front, DTS does not support, and hence does not maintain expertise in, third-party tools and libraries. I’m going to respond in terms of Apple APIs. If you need help understanding how your third-party library uses those APIs, you should escalate that via your library’s support channel.

My understanding is that Alamofire uses NSURLSession under the covers. NSURLSession supports mTLS via its authentication challenge mechanism (NSURLAuthenticationChallenge). Specifically, if the server requests a certificate from the client then NSULRSession will issue a NSURLAuthenticationMethodClientCertificate authentication challenge. The delegate responds to this challenge by:

  1. Creating a credential that contains a digital identity.

  2. Resolving the challenge with that credential.

With regards that point 1, the digital identity is represented by a SecIdentity object and you create the credential using either -[NSURLCredential initWithIdentity:certificates:persistence:] or +[NSURLCredential credentialWithIdentity:certificates:persistence:].

Presumably Alamofire is doing this for you under the covers. My specific question is, how does it create the SecIdentity object?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Hi eskimo, You where guessing correctly, The process is done for TLS. After I receive the signed certificate(der form) from the server I extract the public key, delete the old public key, save the new one, save the certificate. A SecIdentity can now be retrieved from keychain. I use this identity in NSURLAuthenticationMethodClientCertificate challenge I receive. But if I delete the private key from the keychain this challenge fails and I get the above error. Since I want to remove the private key from the keychain in its current form and save it encrypted I have a problem.

Is there any way to have a valid SecIdentity without the private key in the keychain?

After I receive the signed certificate (der form) from the server I extract the public key, delete the old public key, save the new one, save the certificate. A SecIdentity can now be retrieved from keychain.

Hmmm, what do you mean by “old public key” and “new one” here?

If you’ve sent the public key to the server and its wrapped that in a certificate, the public key from the certificate should match the one in the keychain, and so I’m confused as to why there are two public keys in play here.

I use this identity in NSURLAuthenticationMethodClientCertificate challenge I receive.

OK, this bit makes sense (-:

But if I delete the private key from the keychain this challenge fails and I get the above error.

Right, because an identity represents the combination of a private key and a certificates whose public key matches that private key. If you delete the private key out from underneath the identity, it’s not going to work.

Since I want to remove the private key from the keychain in its current form and save it encrypted I have a problem.

And I’m confuse by this too. What do you mean by “save it encrypted”?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

The purpose of my task

OK, I’m going to ask you to put your reply in the reply field. Comments are meant to be used for small comments [1], and if you post a huge reply as a comment it’s basically unreadable.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] DevForums has lots of UI cues that cause folks to use comments rather than replies, a fact I’m trying to get fixed (r. 80839588).

Error received from borring ssl if RSA private is not saved to keychain
 
 
Q