Secure Transport is deprecated. Is there any replacement for SSLCreateContext function for C APIs?

I was overwhelmed by a fact that Apple didn't provide SSLCreateContext for its security APIs.

I checked API at Security/SecureTransport.h and it exists. However, it is deprecated.

I need a SSLCreateContext function available as C API. Is there any replacement for this function from Network framework?

This API went deprecated at iOS 13, and you'll be rewriting it. Whether to a new API, or also to Swift, etc?

What Apple offers: https://developer.apple.com/documentation/network/network_functions Closest analog is nw_parameters_create_secure_tcp, func nw_connection_create, etc.

Examples: https://developer.apple.com/documentation/network/implementing_netcat_with_network_framework https://stackoverflow.com/a/59523101

If you prefer a C API outside the purview of Apple, you may want to import libsodium, or libressl / libtls, or OpenSSL, into your project.

As @Hoffman has pointed out, the replacement for the SecureTransport APIs is now Network Framework. Specifically, you will want to take a look at the Security Options in Network Framework to configure TLS on a connection. There are Swift APIs or C APIs. A Swift example would look something like:

let tcpOptions = NWProtocolTCP.Options()
let tlsOptions = NWProtocolTLS.Options()
sec_protocol_options_set_min_tls_protocol_version(tlsOptions.securityProtocolOptions, .TLSv13)

sec_protocol_options_append_tls_ciphersuite(
    tlsOptions.securityProtocolOptions,
    tls_ciphersuite_t(rawValue: UInt16(TLS_AES_128_GCM_SHA256))!
)

let tlsParams = NWParameters(tls: tlsOptions, tcp: tcpOptions)
let endpoint = NWEndpoint.hostPort(host: "host", port: 443)
let connection = NWConnection(to: endpoint, using: tlsParams)

Let me know if you run into any issues.

Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com

I need a SSLCreateContext function available as C API.

Can you clarify your goal here? Were you using Secure Transport to implement TLS over TCP? Or UDP? Or some other transport protocol? [1]

Share and Enjoy

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

[1] For example, I once worked with a device who was using Secure Transport over an External Accessory framework stream!

Intention

I would like to add adapter for networking framework to socket-based transport layer at libgit2 library.

Library

This library creates ssl context as

/// TCP, right?
st->ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType);

and sets security protocols as

/// TLS
SSLSetProtocolVersionMin(st->ctx, kTLSProtocol1)
SSLSetProtocolVersionMax(st->ctx, kTLSProtocol12)

libgit2 library defines an interface for socket-based api. You have to provide read/write functions for each "socket-based" adapter.

The adapter write function signature is

static ssize_t adapter_write(git_stream *stream, const char *data, size_t len, int flags)

Adapters

SecureTransport is relying on socket-based functions and it uses straightforward approach without callbacks. Read something, get result.

Networking framework suggests a different approach with callbacks. So, instead of reading data in do-while loops, you have to add callbacks with "received/sent" partial result.

Semaphore approach

To adapt callback API I've added semaphore.

Although I'm not sure this approach is efficient in terms of nw_connections.


/// Rough draft
static ssize_t apple_network_adapter_write(git_stream *stream, const char *data, size_t len, int flags)
{
    apple_network_adapter_stream *st = (apple_network_adapter_stream *) stream;
    size_t data_len, processed;
    OSStatus ret;

    GIT_UNUSED(flags);

    data_len = min(len, SSIZE_MAX);
    
    nw_connection_t connection = ... ;/// retrieve connection
    dispatch_data_t ddata = dispatch_data_create(data, data_len, NULL, DISPATCH_DATA_DESTRUCTOR_DEFAULT);
    nw_content_context_t context = NW_CONNECTION_DEFAULT_MESSAGE_CONTEXT;
    
    /// We have to add semaphores for this API.
    /// Otherwise, it won't be able to "be" synced.
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
    __block int errno = 0;
    __block processed_length = -1;
    nw_connection_send(connection, ddata, context, true, ^(nw_error_t  _Nullable error) {
        if (error == NULL) {
            processed = len;
        }
        else {
            errno = nw_error_get_error_code(error);
        }
        dispatch_semaphore_signal(semaphore);
    });
    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

    ret = errno;

    if (ret != noErr) {
        return apple_network_adapter_error(ret);
    }
    
    GIT_ASSERT(processed < SSIZE_MAX);
    return (ssize_t)processed;
}

Hint

Also I find another hint with it that nearly every object in networking framework is defined as NSObjectProtocol object.

I would like to add adapter for networking framework to socket-based transport layer at libgit2 library.

If the final goal is to generate network traffic on the wire then Network framework is your best option.

Networking framework suggests a different approach with callbacks. So, instead of reading data in do-while loops, you have to add callbacks with "received/sent" partial result.

Yep. To use Network framework from a synchronous library you’ll need some sort of mechanism to bridge between that synchronous context and Network framework’s asynchronous one. The best way to do this depends on a variety of factors, but using a Dispatch semaphore is a time-honoured approach [1].

Share and Enjoy

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

[1] It’s definitely less than ideal — because it doesn’t propagate QoS — but that just puts it in the same bucket as the whole concept of synchronous networking (-:

Secure Transport is deprecated. Is there any replacement for SSLCreateContext function for C APIs?
 
 
Q