Skip to content

IDSCP2 User API

Leon edited this page Sep 15, 2021 · 5 revisions

This documentation describes the user API for the IDSCP2 protocol. All the files and directories are relative to idscp2/src/main/kotlin/de/fhg/aisec/ids/idscp2/.

See User Documentation for a showcase, how to configure and use an IDSCP2 peer.

Remote Attestation

Remote attestation (RA) is responsible for proving the remote peer to be in a trusted communication state. The IDSCP2 protocol supports a RA driver interface that allows using different RA implementations, e.g. Intel SGX or TPM drivers.

RA Driver

RA driver instances are generated by the FSM on the fly using the RA registries. Each peer must register the RA prover implementation for proving the local state to the remote peer, as well as the RA verifier for verifying the state of the remote peer. Thus, the user has to register the desired drivers to the registries.

Default RA driver implementations can be found at default_drivers/remote_attestation/.

RA Registry

Register a driver to the prover registry. It takes the instance, an unique cipher suite identifier, the driver factory, which is actually the prover driver implementation class, and an optional implementation-specific driver configuration, that will be passed to the driver instances on on creation.

fun <PC> registerDriver(
                   instance: String, 
                   driverFactory: (RaProverFsmListener) -> RaProverDriver<PC>, 
                   driverConfig: PC?
)

The same method is supported by the verifier registry.

fun <VC> registerDriver(
                   instance: String, 
                   driverFactory: (RaVerifierFsmListener) -> RaVerifierDriver<VC>, 
                   driverConfig: VC?
)

Unregister a driver from the RA registry using the unique identifier. This is supported by both, the verifier and the prover registry.

fun unregisterDriver(instance: String)

RA registries can be found at idscp_core/ra_registry/.

AttestationConfig

The attestation config provides the RA cipher suites and the RA timeout interval from the user to the FSM. A builder pattern can can be used for setting the local RA prover suite (supported suite), the local RA verifier suite (expected suite) and the RA timeout delay.

fun setSupportedRaSuite(suite: Array<String>): Builder
    
fun setExpectedRaSuite(suite: Array<String>): Builder

fun setRaTimeoutDelay(delay: Long): Builder

fun build(): AttestationConfig

Check if two attestation configs are equal:

fun equals(other: Any?): Boolean

Build the hash of the attestation config:

fun hashCode(): Int

The AttestationConfig can be found at idscp_core/api/configuration/.


DAPS Driver

The Daps driver is responsible for providing authorization tokens of the local peer to the FSM and for verifying the remote authorization tokens during the handshake. This is done by the FSM. The user just has to select a DAPS implementation, create it and pass it to the Idscp2Configuration.

Default DAPS driver implementations can be found at default_drivers/daps/.


SecureChannelDriver

The SecureChannelDriver interface is implemented by the SecureChannelDriver implementations and is responsible for starting the SecureServer (e.g. TLSv1.3 server) or for connecting to IDSCP2 peers. First one is not directly used by the user, instead the SecureChannelDriver is passed to the Idscp2ServerFactory that will create the Idscp2Server and wrap the SecureServer component, such that the user does only have to deal with the secure channel layer.

In contrast, for connecting the user has to directly use the SecureChannelDriver. It returns a completable connection future that must be handled via asynchronous future handlers. See User Documentation for an example.

interface SecureChannelDriver<CC : Idscp2Connection, SecureChannelConfiguration> {
    fun connect(
        connectionFactory: (FSM, String) -> CC,
        configuration: Idscp2Configuration,
        secureChannelConfig: SecureChannelConfiguration
    ): CompletableFuture<CC>

    fun listen(
        connectionListenerPromise: CompletableFuture<ServerConnectionListener<CC>>,
        secureChannelConfig: SecureChannelConfiguration,
        serverConfiguration: Idscp2Configuration,
        connectionFactory: (FSM, String) -> CC
    ): SecureServer
}

Default SecureChannel driver implementations can be found at default_drivers/secure_channel/.


IDSCP2 Configuration

The Idscp2Configuration is responsible for passing the daps driver, the attestation configuration, the handshake timeout interval and the acknowledgment timeout interval to the FSM. A builder pattern is used for creating it.

fun setAttestationConfig(config: AttestationConfig): Builder

fun setDapsDriver(dapsDriver: DapsDriver): Builder
   
fun setHandshakeTimeoutDelay(delay: Long): Builder

fun setAckTimeoutDelay(delay: Long): Builder

fun build(): Idscp2Configuration

Check if two Idscp2Configurations are equal:

fun equals(other: Any?): Boolean

Build the has of the Idscp2Configuration:

fun hashCode(): Int

Get the Idscp2Configuration in string format

fun toString(): String

The Idscp2Configuration can be found at idscp_core/api/configuration/.


IDSCP2 Connection

The Idscp2Connection will be created by the protocol either on connecting to a remote peer or on accepting a new peer at the Idscp2Server. It provides the following API to the user:

Register or unregister a connection listener that will be notified on connection closure and on connection errors:

fun addConnectionListener(listener: Idscp2ConnectionListener)

fun removeConnectionListener(listener: Idscp2ConnectionListener): Boolean

Register or unregister a message listener that will receive incoming IDSCP2 data messages:

fun addMessageListener(listener: Idscp2MessageListener)

fun removeMessageListener(listener: Idscp2MessageListener): Boolean

To avoid race conditions that could occur when the listeners are not registered yet while the connection already receives some data from the remote peer, the user has to unlock messaging after listener registration for a client connection:

fun unlockMessaging()

Close the Idscp2Connection. Throws an exception when the connection has never been started.

@Throws(Idscp2Exception::class)
fun close()

Send bytes to the remote IDSCP2 peer without blocking. This returns an Idscp2WouldBlockException when the FSM would block this operation due to earlier messages that first have to be transmitted. An Idscp2Exception is thrown when the connection is closed, an error occurred or the connection is currently not established due to re-attestations.

@Throws(Idscp2Exception::class, Idscp2WouldBlockException::class, Idscp2NotConnectedException::class)
fun nonBlockingSend(msg: ByteArray)

Send bytes to the remote IDSCP2 peer with blocking when the FSM would block. Throws an Idscp2TimeoutException when the timeout interval in milliseconds is reached. The retry interval specifies the duration in milliseconds that should be waited until sending the data again. An Idscp2Exception is thrown when the connection is closed, an error occurred or the connection is currently not established due to re-attestations.

@Throws(Idscp2Exception::class, Idscp2TimeoutException::class, Idscp2NotConnectedException::class)
fun blockingSend(msg: ByteArray, timeout: Long, retryInterval: Long = 0)

Trigger a re-attestation of the remote peer. Throws an Idscp2Exception on error or when the connection is closed.

@Throws(Idscp2Exception::class)
fun repeatRa()

Check if the connection is in a connected/trusted state.

val isConnected: Boolean

Check if the connection is locked forever.

val isClosed: Boolean

Get the local DAT.

val localDynamicAttributeToken: ByteArray

Get the peer's internal connection ID.

val id: String

The Idscp2Connection, as well as the following listeners, can be found at idscp_core/api/idscp_connection/.

Connection Listener

The connection listener interface has to be implemented by an instance that has to be registered to the Idscp2Connection for keeping track of the connection state.

interface Idscp2ConnectionListener {
    fun onError(t: Throwable)
    fun onClose()
}

Message Listener

The message listener interface has to be implemented by an instance that has to be registered to the Idscp2Connection to receive the IDSCP2 payload (bytes) from the remote peer.

fun interface Idscp2MessageListener {
    fun onMessage(connection: Idscp2Connection, data: ByteArray)
}

IDSCP2 Server

The IDSCP2 server is responsible for accepting new IDSCP2 connection requests from other peers. It is created using the Idscp2ServerFactory and provides the following methods to the user:

Check if the IDSCP2 server is running:

val isRunning: Boolean

Get all IDSCP2 connections that are currently open at this Idscp2Server:

val allConnections: Set<CC>

Terminate the Idscp2Server and all its open connections:

fun terminate()

The Idscp2Server can be found at idscp_core/api/idscp_server/.

Idscp2ServerFactory

Constructing an Idscp2ServerFactory requires a connection factory, responsible for creating new Idscp2Connections during the handshake with the new peer, an Idscp2EndpointListener that will be notified on new connections and server errors, the Idscp2Configuration, the SecureChannelDriver, which is used for starting a secure server on which the Idscp2Server is based on, as well as the implementation-specific SecureChannelConfiguration, which might contain address and security information.

connectionFactory: (FSM, String) -> CC,
endpointListener: Idscp2EndpointListener<CC>,
serverConfiguration: Idscp2Configuration,
secureChannelDriver: SecureChannelDriver<CC, SecureChannelConfiguration>,
secureChannelConfig: SecureChannelConfiguration

Using the listen method on the Idscp2ServerFactory, the user can create and start an IDSCP2 server:

@Throws(Idscp2Exception::class)
fun listen(): Idscp2Server<CC: Idscp2Connection>

The Idscp2ServerFactory can be found at idscp_core/api/idscp_server/.

Idscp2EndpointListener

The Idscp2EndpointListener is registered at the Idscp2Server via the Idscp2ServerFactory to keep track of new connections.

interface Idscp2EndpointListener<T: Idscp2Connection> {
    fun onConnection(connection: T)
}

The Idscp2EndpointListener can be found at idscp_core/api/.