## GcrSecretExchange

GcrSecretExchange — Exchange secrets between processes in an unexposed way.

## Synopsis

    struct              GcrSecretExchange;
    struct              GcrSecretExchangeClass;
    #define             GCR_SECRET_EXCHANGE_PROTOCOL_1
    GcrSecretExchange * gcr_secret_exchange_new             (const gchar *protocol);
    gchar *             gcr_secret_exchange_begin           (GcrSecretExchange *self);
    gboolean            gcr_secret_exchange_receive         (GcrSecretExchange *self,
                                                             const gchar *exchange);
    const gchar *       gcr_secret_exchange_get_protocol    (GcrSecretExchange *self);
    const gchar *       gcr_secret_exchange_get_secret      (GcrSecretExchange *self,
                                                             gsize *secret_len);
    gchar *             gcr_secret_exchange_send            (GcrSecretExchange *self,
                                                             const gchar *secret,
                                                             gssize secret_len);

## Description

Allows exchange of secrets between two processes on the same system without exposing those secrets to things like loggers, non-pageable memory etc.

This does not protect against active attacks like MITM attacks.

Each side creates a GcrSecretExchange object, and one of the sides calls `gcr_secret_exchange_begin()`. This creates a string, which should be passed to the other side. Each side passes the strings it receives into `gcr_secret_exchange_receive()`.

In order to send a reply (either with or without a secret) use `gcr_secret_exchange_send()`. A side must have had `gcr_secret_exchange_receive()` successfully called before it can use `gcr_secret_exchange_send()`.

The GcrSecretExchange objects can be used for multiple iterations of the conversation, or for just one request/reply. The only limitation being that the initial request cannot contain a secret.

Caveat: Information about the approximate length (rounded up to the nearest 16 bytes) may be leaked. If this is considered inacceptable, do not use GcrSecretExchange.

## Details

### struct GcrSecretExchange

    struct GcrSecretExchange {
    };

An object representing one side of a secret exchange.

### struct GcrSecretExchangeClass

    struct GcrSecretExchangeClass {
    };

The class for GcrSecretExchange

### GCR_SECRET_EXCHANGE_PROTOCOL_1

    #define GCR_SECRET_EXCHANGE_PROTOCOL_1 "sx-aes-1"

The current secret exchange protocol. Key agreement is done using DH with the 1536 bit IKE parameter group. Keys are derived using SHA256 with HKDF. The transport encryption is done with 128 bit AES.

### gcr_secret_exchange_new ()

    GcrSecretExchange * gcr_secret_exchange_new             (const gchar *protocol);

Create a new secret exchange object.

Specify a protocol of `NULL` to allow any protocol. This is especially relevant on the side of the exchange that does not call `gcr_secret_exchange_begin()`, that is the originator. Currently the only protocol supported is `GCR_SECRET_EXCHANGE_PROTOCOL_1`.

`protocol` : | the exchange protocol to use. [allow-none]
Returns : | A new GcrSecretExchange object. [transfer full]

### gcr_secret_exchange_begin ()

    gchar *             gcr_secret_exchange_begin           (GcrSecretExchange *self);

Begin the secret exchange. The resulting string should be sent to the other side of the exchange. The other side should use `gcr_secret_exchange_receive()` to process the string.

`self` : | a GcrSecretExchange object
Returns : | A newly allocated string to be sent to the other side of the secret exchange. [transfer full]

### gcr_secret_exchange_receive ()

    gboolean            gcr_secret_exchange_receive         (GcrSecretExchange *self,
                                                             const gchar *exchange);

Receive a string from the other side of secret exchange. This string will have been created by `gcr_secret_exchange_begin()` or `gcr_secret_exchange_send()`

`self` : | a GcrSecretExchange object
`exchange` : | the string received
Returns : | whether the string was successfully parsed and received

### gcr_secret_exchange_get_protocol ()

    const gchar *       gcr_secret_exchange_get_protocol    (GcrSecretExchange *self);

Will return `NULL` if no protocol was specified, and either `gcr_secret_exchange_begin()` or `gcr_secret_exchange_receive()` have not been called successfully.

`self` : | a GcrSecretExchange object Get the secret exchange protocol.
Returns : | the protocol or `NULL`

### gcr_secret_exchange_get_secret ()

    const gchar *       gcr_secret_exchange_get_secret      (GcrSecretExchange *self,
                                                             gsize *secret_len);

Returns the last secret received. If no secret has yet been received this will return `NULL`. The string is owned by the GcrSecretExchange object and will be valid until the next time that `gcr_secret_exchange_receive()` is called on this object, or the object is destroyed.

Depending on the secret passed into the other side of the secret exchange, the resurt may be a binary string. It does however have a null terminator, so if you're certain that it is does not contain arbitrary binary data, it can be used as a string.

`self` : | a GcrSecretExchange object
`secret_len` : | optionally, a location to store the length of returned secret. [allow-none]
Returns : | the last secret received. [transfer none][array length=secret_len]

### gcr_secret_exchange_send ()

    gchar *             gcr_secret_exchange_send            (GcrSecretExchange *self,
                                                             const gchar *secret,
                                                             gssize secret_len);

Send a reply to the other side of the secret exchange, optionally sending a secret.

`gcr_secret_exchange_receive()` must have been successfully called at least once on this object. In other words this object must have received data from the other side of the secret exchange, before we can send a secret.

`self` : | a GcrSecretExchange object
`secret` : | optionally, a secret to send to the other side. [allow-none]
`secret_len` : | length of `secret`, or -1 if null terminated
Returns : | a newly allocated string to be sent to the other side of the secret exchange. [transfer full]