PostOffice

public abstract class PostOffice extends AbstractPostOffice

A post office is an object for creating a stream of related mail encrypted to a destinationPublicKey.

Related mail form an ordered list on the same topic. This ordering is defined by the sequence number field in each mail header (see EnclaveMailHeader.sequenceNumber) and it's important the ordering is preserved for the receiving enclave.

A post office also requires a senderPrivateKey, which is used to authenticate each mail and is received by the recipient as an authenticated public key (see EnclaveMail.authenticatedSender). This can be used by the recipient for user authentication but is also required if they want to reply back.

The sender key can either be a short-term eptherimal key which is used only once and then discarded (e.g. when the client process exits) or it can be a long-term identity key. If the later then it's important to keep track of the current sequence number (using nextSequenceNumber) and persit it so that in the event of a client restart the sequence number can be restored (using setNextSequenceNumber). Otherwise the it will reset to zero and since the enclave has already seen mail with the same sender key it will reject it.

Starting from zero, the post office applies an increasing sequence number to each mail it creates. The sequence number, along with the topic and optional envelope (which can be provided when encrypting), are authenticted to the receiving enclave. This means it can detect dropped or reordered messages and thus the ordering is preserved.

However for this to work, the same post office instance must be used for the same sender key and topic pair. This means there can only be one PostOffice instance per (destination, sender, topic) triple. It's up the user to make sure this is the case.

To make it make it more difficult for an adversary to guess the contents of the mail just by observing their sizes, the post office pads the mail to a minimum size. By default it uses a moving average of the previous mail created. This can be changed with minSizePolicy if that's not a sensible policy for the application.

The recepient of mail can decrypt using decryptMail on a post office instance which has the same private key. For a mail response this will be the same post office that created the original request. Inside an enclave nothing needs to be done as mail is automatically decrypted.

When inside an enclave instances can only be created using one of the Enclave.postOffice() methods, and cannot be created using PostOffice.create or EnclaveInstanceInfo.createPostOffice(). This is to ensure the enclave's private key is correctly applied as the sender.

Constructors

PostOffice
Link copied to clipboard
PostOffice PostOffice(PrivateKey senderPrivateKey, String topic)

Methods

create
Link copied to clipboard
static PostOffice create(PublicKey destinationPublicKey)

Create a new post office instance far encrypting mail to the given recipient. A random sender private key will be created and each mail will be authenticated with it (it can be retrieved using senderPrivateKey). The mail topic will be "default".

Do not use this for mail targeted at an enclave. Instead use EnclaveInstanceInfo.createPostOffice(), or if inside an enclave, Enclave.postOffice().

static PostOffice create(PublicKey destinationPublicKey, PrivateKey senderPrivateKey, String topic)

Create a new post office instance far encrypting mail to the given recipient. Each mail will be authenticated with the given private key and will have the given topic.

A new random sender key can be created using Curve25519PrivateKey.random.

Do not use this for mail targeted at an enclave. Instead use EnclaveInstanceInfo.createPostOffice(), or if inside an enclave, Enclave.postOffice().

decryptMail
Link copied to clipboard
EnclaveMail decryptMail(byte[] encryptedEnclaveMail)

Decodes and decrypts the mail with senderPrivateKey and verifies that the authenticated sender (EnclaveMail.authenticatedSender) matches the destinationPublicKey.

encryptMail
Link copied to clipboard
byte[] encryptMail(byte[] body)

Uses destinationPublicKey to encrypt mail with the given body. Only the corresponding private key will be able to decrypt the mail. The returned ciphertext will include topic, incremented sequence number (see nextSequenceNumber) in the clear but authenticated (for the recipient only) as coming from the holder of the sender private key.

The recipient needs to call PostOffice.decryptMail on a post office with the private key of destinationPublicKey to decrypt the bytes.

The encoded bytes contains the body, header and the handshake bytes that set up the shared session key. A mail may not be larger than the 2 gigabyte limit of a Java byte array. The format is not defined here and subject to change.

It's safe to call this method from multiple threads.

byte[] encryptMail(byte[] body, byte[] envelope)

Uses destinationPublicKey to encrypt mail with the given body. Only the coresponding private key will be able to decrypt the mail. The returned ciphertext will include topic, incremented sequence number (see nextSequenceNumber) and envelope in the clear but authenticated (for the recipient only) as coming from the holder of the sender private key.

The recipient needs to call PostOffice.decryptMail on a post office with the private key of destinationPublicKey to decrypt the bytes.

The encoded bytes contains the body, the envelope, header, the handshake bytes that set up the shared session key. A mail may not be larger than the 2 gigabyte limit of a Java byte array. The format is not defined here and subject to change.

It's safe to call this method from multiple threads.

byte[] encryptMail(byte[] body, byte[] envelope, byte[] privateHeader)
equals
Link copied to clipboard
boolean equals(Object other)
getDestinationPublicKey
Link copied to clipboard
abstract PublicKey getDestinationPublicKey()

The public key of the recipient to which mail will be encrypted to.

getEncryptCalled
Link copied to clipboard
boolean getEncryptCalled()
getKeyDerivation
Link copied to clipboard
abstract byte[] getKeyDerivation()
getMinSizePolicy
Link copied to clipboard
MinSizePolicy getMinSizePolicy()

Returns the MinSizePolicy used to apply the minimum size for each encrypted mail. If none is specified then MinSizePolicy.movingAverage is used.

getNextSequenceNumber
Link copied to clipboard
long getNextSequenceNumber()

Returns the sequence number that will be assigned to the next mail.

getSenderPrivateKey
Link copied to clipboard
PrivateKey getSenderPrivateKey()

The sender private key used to authenticate mail and create the EnclaveMail.authenticatedSender field.

getSenderPublicKey
Link copied to clipboard
PublicKey getSenderPublicKey()

Returns the corresponding public key of senderPrivateKey. The recipient of mail will receive this as the authenticated sender. They can use it to reply back, and we can use decryptMail on this post office instance to decrypt their response.

getSequenceNumber
Link copied to clipboard
long getSequenceNumber()
getTopic
Link copied to clipboard
String getTopic()

The topic mail created by this post office will have.

hashCode
Link copied to clipboard
int hashCode()
setEncryptCalled
Link copied to clipboard
void setEncryptCalled(boolean encryptCalled)
setMinSizePolicy
Link copied to clipboard
void setMinSizePolicy(MinSizePolicy minSizePolicy)

Returns the MinSizePolicy used to apply the minimum size for each encrypted mail. If none is specified then MinSizePolicy.movingAverage is used.

setNextSequenceNumber
Link copied to clipboard
PostOffice setNextSequenceNumber(long sequenceNumber)

Set the next sequence number to be used. This can only be called before any mail have been encrypted to ensure they have increasing sequence numbers.

You would typically only need to use this method to restore a post office if the private key is a long-term identity key. The enclave expects topics to start from zero and so setting this to any other value for a new stream will cause the enclave to reject the mail.

setSequenceNumber
Link copied to clipboard
void setSequenceNumber(long sequenceNumber)
toString
Link copied to clipboard
String toString()

Properties

destinationPublicKey
Link copied to clipboard
private PublicKey destinationPublicKey

The public key of the recipient to which mail will be encrypted to.

encryptCalled
Link copied to clipboard
private boolean encryptCalled
keyDerivation
Link copied to clipboard
private byte[] keyDerivation
minSizePolicy
Link copied to clipboard
private MinSizePolicy minSizePolicy

Returns the MinSizePolicy used to apply the minimum size for each encrypted mail. If none is specified then MinSizePolicy.movingAverage is used.

nextSequenceNumber
Link copied to clipboard
private long nextSequenceNumber

Returns the sequence number that will be assigned to the next mail.

senderPrivateKey
Link copied to clipboard
private PrivateKey senderPrivateKey

The sender private key used to authenticate mail and create the EnclaveMail.authenticatedSender field.

senderPublicKey
Link copied to clipboard
private PublicKey senderPublicKey

Returns the corresponding public key of senderPrivateKey. The recipient of mail will receive this as the authenticated sender. They can use it to reply back, and we can use decryptMail on this post office instance to decrypt their response.

sequenceNumber
Link copied to clipboard
private long sequenceNumber
topic
Link copied to clipboard
private String topic

The topic mail created by this post office will have.