Skip to the content.

sxg_signer_list_t

SXG supports multiple signers, so generating one SXG file requires a set of signers. This struct represents a set of signers. By using multiple signers, you can generate signatures with different parameters. Using multiple signatures gives you the flexibility of expiration or ways to obtain certificates.

If you want to use sxg_signer_list_t API, add

#include <libsxg/sxg_signer_list.h>

But in most cases, we recommend to include master header of this project like

#include <libsxg.h>

Fields

sxg_signer_list_t

Vector of sxg_signer_t, you can read all fields, but you should modify them via dedicated APIs except contents of sxg_signer_t.

sxg_signer_t* signers

signer_list Head pointer of signers vector. Initially NULL.

size_t size

Length of signers vector. Initially 0. Every sxg_add_* function will increment this field

size_t capacity

Allocated memory field size of signers vector. Initially 0. Should be changed only when memory allocation happens.

sxg_signer_t

Represents one signer. You should change date and expires members to your own need. There are undocumented fields (type, private_key and public_key), which are not intended to be accessed directly by library users.

char* name

Name of the signer. Will be embedded into SXG file. Always null terminated.

time_t date

Unix time of SXG start time.

time_t expires

Unix time of SXG expiration time.

char* validity_url

Validity URL embedded into SXG file. Always null terminated.

Functions

sxg_signer_list_t sxg_empty_signer_list()

Creates empty signer list. Never fails.

Arguments

Nothing.

Returns

Empty sxg_signer_list_t structure with zero size and zero capacity.

Example

sxg_signer_list_t signers = sxg_empty_signer_list();

void sxg_signer_list_release(sxg_signer_list_t* target)

Releases memory of the signer list specified as target. Key and cert object’s reference count will be decremented. Never fails.

Arguments

Returns

Nothing.

Example

sxg_signer_list_t signers = sxg_empty_signer_list();
/* You can call release function even if signer list is empty. */
sxg_signer_list_release(&signers);

bool sxg_add_ecdsa_signer(const char* name, uint64_t date, uint64_t expires, const char* validity_url, EVP_PKEY* private_key, X509* public_key, const char* certificate_url, sxg_signer_list_t* target)

Appends new ecdsa signer to signer list. Copies the string parameters and increments the reference count of private_key and public_key.

Arguments

Returns

Returns true on success. On fail, target will not be changed.

Example

/* Load private key */
FILE* const keyfile = fopen("/path/to/private_key.pem", "r");
assert(keyfile != NULL);
EVP_PKEY* private_key = PEM_read_PrivateKey(keyfile, NULL, NULL, NULL);
fclose(keyfile);
assert(private_key != NULL);

/* Load certificate */
FILE* certfile = fopen("/path/to/certificate.pem", "r");
assert(certfile != NULL);
char passwd[] = "";
X509* cert = PEM_read_X509(certfile, 0, 0, passwd);
fclose(certfile);
assert(cert != NULL);

sxg_signer_list_t signers = sxg_empty_signer_list();
const time_t now = time(NULL);
bool success = sxg_add_ecdsa_signer(
      "ecdsa256signer", now, now + 60 * 60 * 24,
      "https://original.example.com/resource.validity.msg", private_key, cert,
      "https://yourcdn.veryfast.test/cert.cbor", &signers));

assert(success);
assert(signers.size == 1u);

EVP_PKEY_free(private_key);
X509_free(cert);
sxg_signer_list_release(&signers);

bool sxg_add_ed25519_signer(const char* name, uint64_t date, uint64_t expires, const char* validity_url, EVP_PKEY* private_key, EVP_PKEY* public_key, sxg_signer_list_t* target)

Appends new Ed25519 signer to signer list. Copies the string parameters and increments the reference counts of private_key and public_key. Note: Ed25519 signer does not use certificates, so Ed25519 signer does not require certificate_url.

Arguments

Returns

Returns true on success. On fail, target will not be changed.

Example

/* Load private key */
FILE* const keyfile = fopen("/path/to/private_key.pem", "r");
assert(keyfile != NULL);
EVP_PKEY* private_key = PEM_read_PrivateKey(keyfile, NULL, NULL, NULL);
fclose(keyfile);
assert(private_key != NULL);

/* Load public key */
FILE* publickey_file = fopen("/path/to/public_key.pem", "r");
assert(publickeyA_file != NULL);
EVP_PKEY* public_key = PEM_read_pubkey(publickey_file, 0, 0, &passwd);
fclose(publickey_file);
assert(public_key != NULL);

sxg_signer_list_t signers = sxg_empty_signer_list();
const time_t now = time(NULL);
bool success = sxg_add_ed25519_signer(
      "ed25519signer", now, now + 60 * 60 * 24,
      "https://original.example.com/resource.validity.msg", private_key,
      public_key, &signers));

assert(success);
assert(signers.size == 1u);

EVP_PKEY_free(private_key);
EVP_PKEY_free(public_key);
sxg_signer_list_release(&signers);