# Contexts

Contexts are used to manage groups of certificates together. They contain a centralised configuration, and a pool of stored certificates.

Contexts are automatically used when checking a certificate's signer, trust chain, or grants & roles. In most cases, every certificate you create should be assigned to a context.

When a context is destroyed, all associated certificates are also destroyed at the same time.

## API

* [ec\_ctx\_create()](/contexts.md#ec-ctx-create)
* [ec\_ctx\_destroy()](/contexts.md#ec-ctx-destroy)
* [ec\_ctx\_autoload()](/contexts.md#ec-ctx-autoload)
* [ec\_ctx\_validator()](/contexts.md#ec-ctx-validator)
* [ec\_ctx\_next()](/contexts.md#ec-ctx-next)
* [ec\_ctx\_save()](/contexts.md#ec-ctx-save)
* [ec\_ctx\_remove()](/contexts.md#ec-ctx-remove)
* [ec\_ctx\_cert()](https://github.com/erayd/libec-doc/tree/f47c3e9a304777f09654e80a52051e695de22716/chapters/ec-ctx-cert/README.md)
* [ec\_ctx\_anchor()](/contexts.md#ec-ctx-anchor)

### ec\_ctx\_create()

`ec_ctx_t *ec_ctx_create(void);`

Creates a new context. Returns `NULL` on failure.

Contexts created using this function must be destroyed using `ec_ctx_destroy()` once they are no longer required.

```c
#include <ec.h>
...
ec_ctx_t *ctx = ec_ctx_create();
if(ctx != NULL) {
    //context created OK
}
...
```

### ec\_ctx\_destroy()

`void ec_ctx_destroy(ec_ctx_t *ctx);`

Destroys a context previously created with `ec_ctx_create()`.

```c
#include <ec.h>
...
ec_ctx_destroy(ctx);
...
```

### ec\_ctx\_autoload()

`typedef ec_cert_t *(*ec_autoload_t)(ec_id_t id);`\
`void ec_ctx_autoload(ec_ctx_t *ctx, ec_autoload_t autoload);`

Sets the autoload function that the context will use when trying to locate certificates it doesn't have available in its internal store.

This can be used to e.g. load certificates from disk, via a network connection etc.

```c
#include <ec.h>
...
ec_cert_t *my_autoloader(ec_id_t id) {
    ec_cert_t *c = //load cert from somewhere
    return c;
}
...
ec_ctx_autoload(ctx, my_autoloader);
...
```

### ec\_ctx\_validator()

`void ec_ctx_validator(ec_ctx_t *ctx, ec_record_validator_t validator);`

Sets the validator function used to check whether records with `EC_RECORD_REQUIRE` are acceptable. The validator function should return zero for acceptable, nonzero otherwise.

A validator function *must* be set in order to use `EC_CHECK_REQUIRE`. The validator must reject as failed any records it does not understand.

All arguments to the validator are guaranteed to be present and correct, and the certificate will have passed at least `EC_CHECK_CERT` before the validator is run.

```c
#include <ec.h>
...
int my_validator(ec_ctx_t *ctx, ec_cert_t *c, ec_record_t *r) {
    if(record_relates_to_goldfish(r))
        return 0;
    else
        return 1;
}
...
ec_ctx_validator(ctx, my_validator);
...
```

### ec\_ctx\_next()

`ec_ctx_t *ec_ctx_next(ec_ctx_t *ctx, ec_ctx_t *next);`

Sets the next context to search when attempting to load a certificate from the context's internal store. Always returns `next`.

This is used when trying to locate a certificate using `ec_ctx_cert()` which is not available in the context's internal store of via autoload.

```c
#include <ec.h>
...
ec_ctx_next(ctx, my_other_ctx);
...
```

### ec\_ctx\_save()

`ec_cert_t *ec_ctx_save(ec_ctx_t *ctx, ec_cert_t *c);`

Saves a certificate in the context's internal store, and returns a pointer to the certificate. Returns NULL on failure.

Saving a certificate transfers its ownership to the context, and it will be automatically freed when it is overwritten or when the context is destroyed. The user should ***not*** manually destroy certificates which have been saved in a context.

```c
#include <ec.h>
...
if(ec_ctx_save(ctx, c) == NULL) {
    //failed to save certificate
}
...
```

### ec\_ctx\_remove()

`ec_cert_t *ec_ctx_remove(ec_ctx_t *ctx, ec_id_t id);`

Remove a certificate from the context store. Returns the certificate if present, NULL otherwise.

Once a certificate has been removed from its context, the user is now responsible for destroying it with `ec_cert_destroy()` once it is no longer required.

```c
#include <ec.h>
...
ec_cert_t *c = ec_ctx_remove(ctx, my_cert_id);
if(c != NULL) {
    //certificate was present
}
...
```

### ec\_ctx\_cert()

`ec_cert_t *ec_ctx_cert(ec_ctx_t *ctx, ec_id_t id);`

Loads a certificate from the context's internal store. Returns NULL on failure (e.g. if a certificate is not found).

If an autoloader is defined, an attempt will be made to autoload the certificate if it is not already present in the store.

If an additional search context has been defined using `ec_ctx_next()`, that context will also be searched (*after* attempting to autoload).

```c
#include <ec.h>
...
ec_cert_t *c = ec_ctx_cert(c, my_cert_id);
if(c != NULL) {
    //certificate loaded OK
}
...
```

### ec\_ctx\_anchor()

`ec_cert_t *ec_ctx_anchor(ec_ctx_t *ctx, ec_cert_t *c);`

Get the trust anchor for a certificate. Returns NULL on failure.

If `c` does not pass EC\_CHECK\_CHAIN, this is considered an error. The same search method as `ec_ctx_cert()` is used to find the CA certificate.

```c
#include <ec.h>
...
ec_cert_t *ca = ec_ctx_anchor(ctx, c);
if(ca == NULL) {
    //unable to get CA
}
...
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://libec.erayd.net/contexts.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
