How do I use my own root certificate in IOS Secure Transport API?

I am trying to use the Apple Secure Transport API on top of an installed transport layer with my own root certificate. I have a root certificate like SecCertificateRef

but I can't figure out how to get it to be trusted.

I've looked at the following features, each of which seems painfully close to what I need:

  • SSLAddDistinguishedName()

    not implemented;
  • SSLSetTrustedRoots()

    deprecated;
  • SSLSetCertificateAuthorities()

    is for client authentication only.

If I could override SecTrustRef

in SecContextRef

then it SecTrustSetAnchorCertificates()

will do the job. Unfortunately this avenue only led me to SSLGetPeerSecTrust()

, which appears to be the Apple API.

+3


source to share


2 answers


I think what you want is the following:

OSStatus status = SSLSetSessionOption(sslContext, kSSLSessionOptionBreakOnServerAuth, true);

      

and then during the handshake



 OSStatus status = SSLHandshake(sslContext);
    if (status == errSSLPeerAuthCompleted)
    {
        SecTrustRef trust = NULL;
        status = SSLCopyPeerTrust(sslContext, &trust);

        // Perform your custom trust rules here.  e.g.
        BOOL bTrusted = NO;
        NSArray* anchor = [NSArray arrayWithObject:(id)pCACert];
        OSStatus result = SecTrustSetAnchorCertificates(trust, (CFArrayRef)anchor);
        /* Uncomment this to enable both system certs and the one we are supplying */
        //result = SecTrustSetAnchorCertificatesOnly(trust, NO);
        SecTrustResultType trustResult;
        result = SecTrustEvaluate(trust, &trustResult);
        if (result == errSecSuccess)
        {
          switch (trustResult)
          {
            case kSecTrustResultProceed:
            case kSecTrustResultUnspecified:
              bTrusted = YES;
              break;

            case kSecTrustResultInvalid:
            case kSecTrustResultDeny:
            case kSecTrustResultRecoverableTrustFailure:
            case kSecTrustResultFatalTrustFailure:
            case kSecTrustResultOtherError:
            default:
              break;
          }
        }

        // If trusted, continue the handshake
        if (bTrusted)
          status = SSLHandshake(sslContext);
        else 
        {
          /* Your trust failure handling here ~ disconnect */
        }
    }

      

where pCAcert is the root certificate (SecCertificateRef) you want to trust

+2


source


If I understand this, you are trying:

{your application} - [ssl session] → {your server}

The server uses some certificate signed by your own CA (root). You are trying to send your CA certificate to your phone and use it as a trusted CA, not the global CAs that are there.

This is similar to what you are looking for:

Preparing for the session

  • Call SSLNewContext (on OS X) or SSLCreateContext (on iOS and OS X) to create a new SSL session context.

  • Write the SSLWrite and SSLRead I / O functions and call SSLSetIOFuncs to pass them to the secure transport.

  • Establish a connection using CFNetwork, BSD Sockets, or Open Transport. Then call SSLSetConnection to specify the connection to which the SSL session context is using.

  • Call SSLSetPeerDomainName to specify the fully qualified domain name of the partner you want to connect to (optional, but highly recommended).

  • Call SSLSetCertificate to specify the certificate to be used in authentication (required for backend, optional for client).



OSStatus SSLSetCertificate ( SSLContextRef context, CFArrayRef certRefs );

      

certRefs
Certificates for installation. This array contains elements of type SecCertificateRef, with the exception of certRefs [0], which is of type SecIdentityRef.

Discussion Installing a certificate or certificates is required for server connections, but optional for clients. Specifying a certificate for the client enables SSL client-side authentication. You must place a SecIdentityRef object in certRefs [0] that identifies the sheet and its associated secret key. The root of the certificate is optional; if not specified, the root certificate that verifies that the certificate chain specified here must be present in the system's trusted anchor certificate set.

from: https://developer.apple.com/library/mac/documentation/Security/Reference/secureTransportRef/

+1


source







All Articles