public class EnclaveHost
Represents an enclave running on the local CPU. Instantiating this object loads and initialises the enclave, making it ready to receive connections.
You can get a class EnclaveHost
using one of the static factory methods.
An enclave won't actually be loaded and initialised immediately until the start
method is explicitly called.
This gives you time to configure the class EnclaveHost
before startup.
Multiple enclaves can be loaded at once, however, you may not mix simulation/debug/production enclaves together.
Although the enclave must currently run against Java 8, the host can use any version of Java that is supported.
class EnclaveHost
,
start
,
class EnclaveHost
protected EnclaveHost()
Represents an enclave running on the local CPU. Instantiating this object loads and initialises the enclave, making it ready to receive connections.
You can get a class EnclaveHost
using one of the static factory methods.
An enclave won't actually be loaded and initialised immediately until the start
method is explicitly called.
This gives you time to configure the class EnclaveHost
before startup.
Multiple enclaves can be loaded at once, however, you may not mix simulation/debug/production enclaves together.
Although the enclave must currently run against Java 8, the host can use any version of Java that is supported.
class EnclaveHost
,
start
,
class EnclaveHost
@NotNull public java.lang.String getEnclaveClassName()
The name of the sub-class of Enclave that was loaded.
@NotNull public EnclaveMode getEnclaveMode()
The mode the enclave is running in.
@Synchronized public void start(@Nullable AttestationParameters attestationParameters, @Nullable java.util.function.Consumer<java.util.List> mailCallback)
Causes the enclave to be loaded and the Enclave
object constructed inside.
This method must be called before sending is possible. Remember to call
close
to free the associated enclave resources when you're done with it.
attestationParameters
- Either an class AttestationParameters.EPID
object initialised with the required API keys,or an class AttestationParameters.DCAP
object (which requires no extra parameters) when the host operating system ispre-configured for DCAP attestation, typically by a cloud provider. This parameter is ignored if the enclave isin mock or simulation mode and a mock attestation is used instead. Likewise, null can also be used for developmentpurposes.mailCallback
- A callback that will be invoked when the enclave requires the host to carry mail-related
actions, such as requesting delivery to the client or acknowledgement of mail. These actions, or class MailCommand
s, are
grouped together within the scape of a deliverMail
or callEnclave
call. This enables the host to action these
commands within the same transaction.
If null then the enclave cannot send or acknowledge mail, although you can still deliver it.
IllegalArgumentException
- If the enclaveMode
is either release or debug and no attestation parameters
are provided.IllegalStateException
- If the host has been closed.close
@NotNull public EnclaveInstanceInfo getEnclaveInstanceInfo()
Provides the info of this specific loaded instance. Note that the enclave instance info will remain valid across restarts of the host JVM/reloads of the enclave.
IllegalStateException
- if the enclave has not been started.@Nullable public byte[] callEnclave(@NotNull byte[] bytes, @NotNull java.util.function.Function<byte[],byte[]> callback)
Passes the given byte array to the enclave. The format of the byte arrays are up to you but will typically use some sort of serialization mechanism, alternatively, DataOutputStream is a convenient way to lay out pieces of data in a fixed order.
For this method to work the enclave class must override and implement receiveFromUntrustedHost
The return
value from that method (which can be null) is returned here. It will not be received via the provided callback.
With the provided callback the enclave also has the option of using
Enclave.callUntrustedHost
and sending/receiving byte arrays in the opposite
direction. By chaining callbacks together, a kind of virtual stack can be constructed
allowing complex back-and-forth conversations between enclave and untrusted host.
Any uncaught exceptions thrown by receiveFromUntrustedHost
will propagate across the enclave-host boundary and
will be rethrown here.
bytes
- Bytes to send to the enclave.callback
- Bytes received from the enclave via Enclave.callUntrustedHost
.receiveFromUntrustedHost
.UnsupportedOperationException
- If the enclave has not provided an implementation of receiveFromUntrustedHost
.IllegalStateException
- If the host has not been started.@Nullable public byte[] callEnclave(@NotNull byte[] bytes)
Passes the given byte array to the enclave. The format of the byte arrays are up to you but will typically use some sort of serialization mechanism, alternatively, DataOutputStream is a convenient way to lay out pieces of data in a fixed order.
For this method to work the enclave class must override and implement receiveFromUntrustedHost
The return
value from that method (which can be null) is returned here. It will not be received via the provided callback.
The enclave does not have the option of using Enclave.callUntrustedHost
for
sending bytes back to the host. Use the overload which takes in a callback Function instead.
Any uncaught exceptions thrown by receiveFromUntrustedHost
will propagate across the enclave-host boundary and
will be rethrown here.
bytes
- Bytes to send to the enclave.receiveFromUntrustedHost
.UnsupportedOperationException
- If the enclave has not provided an implementation of receiveFromUntrustedHost
.IllegalStateException
- If the host has not been started.public void deliverMail(long id, @NotNull byte[] mail, @Nullable java.lang.String routingHint, @NotNull java.util.function.Function<byte[],byte[]> callback)
Delivers the given encrypted mail bytes to the enclave. The enclave is required to override and implement receiveMail
to receive it. If the enclave throws an exception it will be rethrown.
It's up to the caller to decide what to do with mails that don't seem to be
handled properly: discarding it and logging an error is a simple option, or
alternatively queuing it to disk in anticipation of a bug fix or upgrade
is also workable.
It's possible the callback provided to start
will receive a class MailCommand.PostMail
or class MailCommand.AcknowledgeMail
on the same thread, requesting mail to be sent back in response and/or acknowledgement, respectively. However, it's
also possible the enclave will hold the mail without requesting any action.
When an enclave is started, you must redeliver, in order, any unacknowledged mail so the enclave can rebuild its internal state.
id
- An identifier that will be used to identify acknowledged mail via class MailCommand.AcknowledgeMail
. Thescope of this ID is up until the enclave acknowledges the mail, so it doesn't have to be fully unique forever, nordoes it need to be derived from anything in particular. A good choice is a row ID in a database or a queue messageID, for example.mail
- The encrypted mail received from a remote client.routingHint
- An arbitrary bit of data identifying the sender on the host side. The enclave can pass thisback through to class MailCommand.PostMail
to ask the host to deliver the reply to the right location.callback
- If the enclave calls Enclave.callUntrustedHost
then thebytes will be passed to this object for consumption and generation of theresponse.UnsupportedOperationException
- If the enclave has not provided an implementation for receiveMail
.IllegalStateException
- If the host has not been started.start
,
class MailCommand.PostMail
,
class MailCommand.AcknowledgeMail
public void deliverMail(long id, @NotNull byte[] mail, @Nullable java.lang.String routingHint)
Delivers the given encrypted mail bytes to the enclave. The enclave is required to override and implement receiveMail
to receive it. If the enclave throws an exception it will be rethrown.
It's up to the caller to decide what to do with mails that don't seem to be
handled properly: discarding it and logging an error is a simple option, or
alternatively queuing it to disk in anticipation of a bug fix or upgrade
is also workable.
It's possible the callback provided to start
will receive a class MailCommand.PostMail
or class MailCommand.AcknowledgeMail
on the same thread, requesting mail to be sent back in response and/or acknowledgement, respectively. However, it's
also possible the enclave will hold the mail without requesting any action.
When an enclave is started, you must redeliver, in order, any unacknowledged mail so the enclave can rebuild its internal state.
Note: The enclave does not have the option of using Enclave.callUntrustedHost
for
sending bytes back to the host. Use the overload which takes in a callback Function instead.
id
- an identifier that will be used to identify acknowledged mail via class MailCommand.AcknowledgeMail
. Thescope of this ID is up until the enclave acknowledges the mail, so it doesn't have to be fully unique forever, nordoes it need to be derived from anything in particular. A good choice is a row ID in a database or a queue messageID, for example.mail
- the encrypted mail received from a remote client.routingHint
- An arbitrary bit of data identifying the sender on the host side. The enclave can pass thisback through to class MailCommand.PostMail
to ask the host to deliver the reply to the right location.UnsupportedOperationException
- If the enclave has not provided an implementation for receiveMail
.IllegalStateException
- If the host has not been started.start
,
class MailCommand.PostMail
,
class MailCommand.AcknowledgeMail
,
Function@Synchronized public void close()
@NotNull public static java.lang.String getCapabilitiesDiagnostics()
Diagnostics output outlining CPU capabilities. This is a free text field and should only be used for debugging, logging. Don't try to parse the output.
@NotNull public static EnclaveHost load(@NotNull java.lang.String enclaveClassName)
Load the signed enclave for the given enclave class name.
IllegalArgumentException
- if there is no enclave file for the given class name.EnclaveLoadException
- if the enclave does not load correctly or if the platform does
not support hardware enclaves or if enclave support is disabled.MockOnlySupportedException
- if the host OS is not Linux or if the CPU doesn't support even SIMULATION
enclaves.public static void checkPlatformSupportsEnclaves(boolean enableSupport)
Checks to see if the platform supports hardware based enclaves.
This method checks to see if the CPU and the BIOS are capable of supporting enclaves and whether support has been enabled.
If enclaves are supported but not enabled some platforms allow support to be enabled via a software call. This method can optionally be used to attempt to enable support on the platform. Enabling enclave support via software may require the application calling this method to be started with root privileges.
enableSupport
- Set to true to attempt to enable enclave support on the platform if support iscurrently disabled.EnclaveLoadException
- if HARDWARE enclave support is not available on the platform. The exception
message gives a detailed reason why HARDWARE enclaves are not supported.MockOnlySupportedException
- if mock only enclave is supported on the platform. The exception message
gives a detailed reason why mock only enclaves are supported.