dialer
dialer

Reputation: 4845

How to impelment custom I/O code with cryptlib?

I'm using Peter Gutmann's cryptlib to implement TLS encryption.

Normally, cryptlib's functions cryptPopData and cryptPushData would process protocol specific handshakes, encrypt or decrypt data, and also read from or write to a network socket which is internally managed by cryptlib. This worked, but now I need to implement I/O myself (and the I/O API is not compatible with sockets).

What needs to happen is roughly this(1):

[I prepare] unencrypted TxData -> [cryptlib] -> encrypted TxData -> [I send]
[I receive] encrypted RxData -> [cryptlib] -> decrypted RxData -> [I process]

According to the chapter "Managing your Own Network Connections and I/O" in the cryptlib manual p. 127, this exact scenario should be possible, but I don't understand it.

You can also use this facility if you want to use any high-performance I/O capabilities provided by your system, for example asynchronous I/O or hardware-accelerated I/O in which a dedicated subsystem manages all network transfers and posts a completion notification to your application when the transfer is complete. This allows you to use your own connection-management/socket-multiplexing/read-write code rather than using the facilities provided by cryptlib.

The following discussion refers to network sockets because this is the most common abstraction that’s used for network I/O, however cryptlib will work with any network I/O identifier that can be represented by an integer value or handle. If your network abstraction requires more than a straightforward handle, you can pass in a reference or index to an array of whatever data structures your system requires to handle network I/O.

The explanatory text states that an application can use this to implement I/O itself rather than having cryptlib perform the I/O, which is what I need. It also mentions that, even though the programming examples concern sockets, the principle can also be applied to other types of I/O.

However, all the programming examples provided boil down to this:

/* Wait for data to arrive */
[Some application defined code that reads data from the network and puts it into an application defined buffer]

/* Read data from the session */
cryptPopData( cryptSession, ... );

I do not understand how the encrypted RxData which is received by the application code becomes visible to cryptlib so that it can be processed by cryptlib (and, if applicable, decrypted). Without this step, how is cryptPopData supposed to give me decrypted data if I never tell it what I received from the remote device?

It's the same with TxData - I don't see any cryptlib API that gives me outgoing encrypted(1) data that it would like to be sent over the network.

I would have expected either 2 application-provided I/O callbacks (one for reading and one for writing), OR a secondary push/pop interface that pops outgoing network data out of cryptlib, and pushes incoming network data into cryptlib.

(1) I realise that it would be more nuanced - it could also be the data for the initial TLS handshaking - in which case cryptlib would require me to send data without me having provided unencrypted TxData, and that it would require me to receive data without me actually getting a decrypted RxData payload out of it.

Upvotes: 1

Views: 75

Answers (0)

Related Questions