Files
s390-tools/include/ekmfweb/ekmfweb.h
Ingo Franzki 40e4b71159 libekmfweb: Get EKMF Web settings and check features
Retrieve EKMF Web settings such as the template names used by
EKMF Web for generating identity keys, as well as volume encryption
keys (XTS and non-XTS). Also check that the EKMF Web server has the
required 'Pervasive Encryption' feature installed.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00

1072 lines
52 KiB
C

/*
* libekmfweb - EKMFWeb client library
*
* Copyright IBM Corp. 2020
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#ifndef LIB_EKMFWEB_H
#define LIB_EKMFWEB_H
#include <stddef.h>
#include <stdbool.h>
typedef void CURL;
struct ekmf_config {
/** The base URL of the server. Should use https:// ! */
const char *base_url;
/** Optional: File name of the CA bundle PEM file, or a name of a
* directory the multiple CA certificates. If this is NULL, then the
* default system path for CA certificates is used */
const char *tls_ca;
/** Optional: File name of the client certificate PEM file */
const char *tls_client_cert;
/** Optional: File name of the clients key PEM file */
const char *tls_client_key;
/** Optional: Passphrase to read the clients key PEM file */
const char *tls_client_key_passphrase;
/** Optional: File name of a PEM file holding a CA certificate of the
* issuer */
const char *tls_issuer_cert;
/** Optional: File name of a PEM file containing the servers pinned
* public key. Public key pinning requires that verify_peer or
* verify_host (or both) is true. */
const char *tls_pinned_pubkey;
/** Optional: File name of a PEM file containing the server's
* certificate. This can be used to allow peer verification with
* self-signed server certificates */
const char *tls_server_cert;
/** If true, the peer certificate is verified */
bool tls_verify_peer;
/** If true, that the server certificate is for the server it is known
* as (i.e. the hostname in the url) */
bool tls_verify_host;
/** Maximum number of redirects to follow. Zero means that redirects are
* not followed. -1 means to infinitely follow redirects. */
long max_redirs;
/** File name of the login token (JSON Web Token) used for the last
* login. */
const char *login_token;
/** File name of a file containing the client identity secure key blob.
* This key represents the client identity against EKMFWeb. Some
* requests sent to EKMFWeb are signed with this (secure) key */
const char *identity_secure_key;
/** File name of a PEM file containing the EKMFWeb servers public key
* used to sign key export responses. */
const char *ekmf_server_pubkey;
};
struct ekmf_cca_lib {
void *cca_lib; /* Handle of CCA host library loaded via dlopen */
};
enum ekmf_ext_lib_type {
EKMF_EXT_LIB_CCA = 1,
};
struct ekmf_ext_lib {
enum ekmf_ext_lib_type type;
union {
struct ekmf_cca_lib *cca; /* Used if type = EKMF_EXT_LIB_CCA */
};
};
/**
* Connects to the specified server url and obtains the servers certificate
* and its chain of signing certificates and stores them in the specified
* PEM files.
*
* @param config the configuration structure. Only the base_url must
* be specified, all others are optional.
* @param server_cert_pem Optional: name of a PEM file to store the servers
* certificate
* @param server_pubkey_pem Optional: name of a PEM file to store the servers
* public key (can be used for public key pinning)
* @param ca_bundle_pem Optional: name of a PEM file to store the CA
* certificate chain as a bundle
* @param verified On return: If the server 's certificate has been
* verified using the CA specification from the config
* (if ca = NULL: default system CAs, otherwise path
* or file to CAs).
* @param error_msg on return: If not NULL, then a textual error message
* is returned in case of a failing request. The caller
* must free the error string when it is not NULL.
* @param verbose if true, verbose messages are printed
*
* @returns zero for success, a negative errno in case of an error.
*/
int ekmf_get_server_cert_chain(const struct ekmf_config *config,
const char *server_cert_pem,
const char *server_pubkey_pem,
const char *ca_bundle_pem,
bool *verified, char **error_msg, bool verbose);
/**
* Print the certificate(s) contained in the specified PEM file.
*
* @param cert_pem the file name of the PEM file to print
* @param verbose if true, verbose messages are printed
*
* @returns -EIO if the file could not be opened. -ENOENT if the PEM file
* does not contain any certificates. 0 if success.
*/
int ekmf_print_certificates(const char *cert_pem, bool verbose);
/**
* Checks if the login token stored in the file denoted by field login_token
* of the config structure is valid or not. The file (if existent) contains a
* JSON Web Token (JWT, see RFC7519). It is valid if the current date and time
* is before its expiration time ("exp" claim), and after or equal its
* not-before time ("nbf" claim).
* Note: The signature (if any) of the JWT is not checked, nor any other JWT
* fields.
*
* @param config the configuration structure
* @param valid On return: true if the token is valid, false if not
* @param login_token On return: If not NULL: the login token, if the
* token is still valid. The returned string must
* be freed by the caller when no longer needed.
* @param verbose if true, verbose messages are printed
*
* @returns a negative errno in case of an error, 0 if success.
*/
int ekmf_check_login_token(const struct ekmf_config *config, bool *valid,
char **login_token, bool verbose);
/**
* Performs a login of the specified user with a passcode. On success the
* returned login token is stored in the file denoted by field login_token
* of the config structure, so that it can be used by subsequent requests.
*
* To perform a single request, set curl_handle to NULL. This will cause the
* function to initialize a new CURL handle, use it, and destroy it.
* If you plan to perform multiple requests to the same host, supply the address
* of a CURL pointer that is initially NULL. This function will then initialize
* a new CURL handle on the first call. On subsequent calls, pass in the address
* of the same CURL pointer so that the CURL handle is reused. After the last
* request, the CURL handle must be destroyed by calling ekmf_curl_destroy).
*
* @param config the configuration structure
* @param curl_handle address of a CURL handle used for reusing the same
* CURL handle with multiple requests.
* @param user_id the user-ID to log-in.
* @param passcode the passcode to log-in the user.
* @param error_msg on return: If not NULL, then a textual error message
* is returned in case of a failing request. The caller
* must free the error string when it is not NULL.
* @param verbose if true, verbose messages are printed
*
* @returns zero for success, a negative errno in case of an error.
* -EACCES is returned, if the passcode is no longer valid.
*/
int ekmf_login(const struct ekmf_config *config, CURL **curl_handle,
const char *user_id, const char *passcode, char **error_msg,
bool verbose);
enum ekmf_key_type {
EKMF_KEY_TYPE_ECC = 1,
EKMF_KEY_TYPE_RSA = 2,
};
struct ekmf_key_gen_info {
enum ekmf_key_type type;
union {
struct {
int curve_nid;
} ecc;
struct {
size_t modulus_bits;
unsigned int pub_exp;
} rsa;
} params;
};
/**
* Generate a secure identity key used to identify the client to EKMFWeb.
* The secure key blob is stored in a file specified in field
* identity_secure_key of the config structure. If an secure key already exists
* at that location, it is overwritten.
*
* @param config the configuration structure. Only field
* identity_secure_key must be specified, all others
* are optional.
* @param info key generation info, such as key type (ECC or RSA)
* and key parameters.
* @param ext_lib External secure key crypto library to use
* @param verbose if true, verbose messages are printed
*
* @returns a negative errno in case of an error, 0 if success.
*/
int ekmf_generate_identity_key(const struct ekmf_config *config,
const struct ekmf_key_gen_info *info,
const struct ekmf_ext_lib *ext_lib,
bool verbose);
/**
* Re-encipher the secure identity key (form field identity_secure_key in
* config) used to identify the client to EKMFWeb.
* The secure key blob is encrypted using the HSM master key. Whenever the HSM
* master key is being changed, the secure identity key must be re-enciphered.
* You can either pro-actively re-encipher a secure key once the new master key
* has been prepared (but not yet made active): to_new = true; or you can
* re-encipher a secure key when the HSM master key has already been changed:
* to_new = false. This requires that the HSM still has the old master key.
* Not all HSMs support this.
*
* For pro-active re-encipherment it is suggested to store the re-enciphered
* secure key on a separate place, until the new HSM master key has been made
* active. Specify a file name in reenc_secure_key to do so. For an in-place
* re-encipherment, set reenc_secure_key = NULL.
*
* @param config the configuration structure. Only field
* identity_secure_key must be specified, all others
* are optional.
* @param to_new If true: the identity key is re-enciphered from the
* current to the new master key.
* If false: the identity key is re-enciphered from the
* old to the current master key.
* @param reenc_secure_key if not NULL, then the re-enciphered secure key is
* stored into the filename specified here. Otherwise
* the re-enciphered secure key replaces the original
* secure identity key.
* @param ext_lib External secure key crypto library to use
* @param verbose if true, verbose messages are printed
*
* @returns a negative errno in case of an error, 0 if success.
* A -ENODEV indicates that the master keys are not loaded.
*/
int ekmf_reencipher_identity_key(const struct ekmf_config *config,
bool to_new, const char *reenc_secure_key,
const struct ekmf_ext_lib *ext_lib,
bool verbose);
struct ekmf_rsa_pss_params {
int salt_len; /* salt length in bytes, or OpenSSL constants
RSA_PSS_SALTLEN_DIGEST (-1),
RSA_PSS_SALTLEN_AUTO (-2), or
RSA_PSS_SALTLEN_MAX(-3) */
int mgf_digest_nid; /* OpenSSl digest nid, or zero to use the same
digest algorithm as the signature algorithm */
};
/**
* Generate a certificate signing request using the secure identity key (field
* identity_secure_key in config structure) with the specified subject name,
* certificate extensions (if any), and writes the CSR to the specified file
* in PEM format.
*
* To renew an existing certificate, specify renew_cert = true. In this case
* the existing certificate (field sign_certificate in config struct) is read,
* and the subject name is extracted from it. Any specified subject name RDNs
* are added to the CSR. Also, the extensions are taken from the existing
* certificate, and any specified extensions are added to the CSR.
*
* The CSR is signed using the secure identity key (field identity_secure_key in
* config structure) with an signing algorithm matching the identity key (ECDSA,
* RSA-PKCS, or RSA-PSS if rsa_pss is true), and the specified digest. If the
* digest nid is zero, then a default digest is used.
*
* @param config the configuration structure. Only field
* identity_secure_key must be specified, all others
* are optional.
* @param subject_rdns an array of strings, each string representing an
* RDN in the form '[+]type=value'. If the type is
* prepended with a '+', then this RDN is added to the
* previous one.
* @param num_subject_rdns number of RDN elements in the array.
* @param subject_utf8 if true, RDNs of type MBSTRING_UTF8 are created,
* otherwise type is MBSTRING_ASC is used.
* @param renew_cert_filename if not NULL, specifies the file name of a PEM file
* containing an existing certificate that is renewed
* @param extensions an array of strings, each string representing an
* certificate extension in the form 'type=value'.
* @param num_extensions number of extension elements in the array.
* @param digest_nid the OpenSSL digest nid to use with the signature
* algorithm, or 0 to use the default
* @param rsa_pss_params if not NULL and the identity key is an RSA key, then
* the CSR is signed with RSA-PSS using the specified
* PSS parameters. Ignored if the identity key is an EC
* key
* @param csr_pem_filename the name of the PEM file to which the CSR is written
* @param new_hdr if true, output "NEW" in the PEM header lines
* @param ext_lib External secure key crypto library to use
* @param verbose if true, verbose messages are printed
*
* @returns a negative errno in case of an error, 0 if success:
* -EINVAL: invalid parameter
* -ENOMEM: Failed to allocate memory
* -EBADMSG: an RDN or extension is not formatted correctly
* -EIO: OpenSSL failed to create the CSR
* -EEXIST: if one of the RDN name entries or extensions to add is a
* duplicate
* -ENOTSUP: the specified digest is not supported
* any other errno from file I/O routines
*/
int ekmf_generate_csr(const struct ekmf_config *config,
const char *subject_rdns[], size_t num_subject_rdns,
bool subject_utf8, const char *renew_cert_filename,
const char *extensions[], size_t num_extensions,
int digest_nid,
struct ekmf_rsa_pss_params *rsa_pss_params,
const char *csr_pem_filename, bool new_hdr,
const struct ekmf_ext_lib *ext_lib, bool verbose);
/**
* Generate a self signed certificate using the secure identity key (field
* identity_secure_key in config structure) with the specified subject name,
* certificate extensions (if any), and writes the certificate the specified
* file in PEM format.
*
* To renew an existing certificate, specify renew_cert = true. In this case
* the existing certificate (field sign_certificate in config struct) is read,
* and the subject name is extracted from it. Any specified subject name RDNs
* are added to the certificate. Also, the extensions are taken from the
* existing certificate, and any specified extensions are added to the new
* certificate.
*
* The certificate is signed using the secure identity key (field
* identity_secure_key in config structure) with an signing algorithm matching
* the identity key (ECDSA, RSA-PKCS, or RSA-PSS if rsa_pss is true), and the
* specified digest. If the digest nid is zero, then a default digest is used.
*
* @param config the configuration structure. Only field
* identity_secure_key must be specified, all others
* are optional.
* @param subject_rdns an array of strings, each string representing an
* RDN in the form '[+]type=value'. If the type is
* prepended with a '+', then this RDN is added to the
* previous one.
* @param num_subject_rdns number of RDN elements in the array.
* @param subject_utf8 if true, RDNs of type MBSTRING_UTF8 are created,
* otherwise type is MBSTRING_ASC is used.
* @param renew_cert_filename if not NULL, specifies the file name of a PEM file
* containing an existing certificate that is renewed
* @param extensions an array of strings, each string representing an
* certificate extension in the form 'type=value'.
* @param num_extensions number of extension elements in the array.
* @param validity_days number if day from the current date how long the
* certificate is valid.
* @param digest_nid the OpenSSL digest nid to use with the signature
* algorithm, or 0 to use the default
* @param rsa_pss_params if not NULL and the identity key is an RSA key, then
* the certificate is signed with RSA-PSS using the
* specified PSS parameters. Ignored if the identity
* key is an EC key
* @param cert_pem_filename the name of the PEM file to which the Certificate
* is written
* @param ext_lib External secure key crypto library to use
* @param verbose if true, verbose messages are printed
*
* @returns a negative errno in case of an error, 0 if success.
* -EINVAL: invalid parameter
* -ENOMEM: Failed to allocate memory
* -EBADMSG: an RDN or extension is not formatted correctly
* -EIO: OpenSSL failed to create the certificate
* -EEXIST: if one of the RDN name entries or extensions to add is a
* duplicate
* -ENOTSUP: the specified digest is not supported
* any other errno from file I/O routines
*/
int ekmf_generate_ss_cert(const struct ekmf_config *config,
const char *subject_rdns[], size_t num_subject_rdns,
bool subject_utf8, const char *renew_cert_filename,
const char *extensions[], size_t num_extensions,
int validity_days, int digest_nid,
struct ekmf_rsa_pss_params *rsa_pss_params,
const char *cert_pem_filename,
const struct ekmf_ext_lib *ext_lib, bool verbose);
/**
* Retrieves settings from the EKMFWeb server, such as the template names for
* generating keys in EKMFWeb.
*
* To perform a single request, set curl_handle to NULL. This will cause the
* function to initialize a new CURL handle, use it, and destroy it.
* If you plan to perform multiple requests to the same host, supply the address
* of a CURL pointer that is initially NULL. This function will then initialize
* a new CURL handle on the first call. On subsequent calls, pass in the address
* of the same CURL pointer so that the CURL handle is reused. After the last
* request, the CURL handle must be destroyed by calling ekmf_curl_destroy).
*
* @param config the configuration structure
* @param curl_handle address of a CURL handle used for reusing the same
* CURL handle with multiple requests.
* @param identity_template on return: If not NULL, the name of the template
* used to generate identity keys with. The caller
* must free the error string when it is not NULL.
* @param xts_key1_template on return: If not NULL, the name of the template
* used to generate the first XTS key with. The caller
* must free the error string when it is not NULL.
* @param xts_key1_template on return: If not NULL, the name of the template
* used to generate the second XTS key with. The caller
* must free the error string when it is not NULL.
* @param xts_key1_template on return: If not NULL, the name of the template
* used to generate a non-XTS key with. The caller
* must free the error string when it is not NULL.
* @param error_msg on return: If not NULL, then a textual error message
* is returned in case of a failing request. The caller
* must free the error string when it is not NULL.
* @param verbose if true, verbose messages are printed
*
* @returns zero for success, a negative errno in case of an error.
* -EACCES is returned, if no or no valid login token is available.
*/
int ekmf_get_settings(const struct ekmf_config *config, CURL **curl_handle,
char **identity_template, char **xts_key1_template,
char **xts_key2_template, char **non_xts_template,
char **error_msg, bool verbose);
/**
* Checks if the EKMFWeb server has the required Pervasive Encryption feature
* installed
*
* To perform a single request, set curl_handle to NULL. This will cause the
* function to initialize a new CURL handle, use it, and destroy it.
* If you plan to perform multiple requests to the same host, supply the address
* of a CURL pointer that is initially NULL. This function will then initialize
* a new CURL handle on the first call. On subsequent calls, pass in the address
* of the same CURL pointer so that the CURL handle is reused. After the last
* request, the CURL handle must be destroyed by calling ekmf_curl_destroy).
*
* @param config the configuration structure
* @param curl_handle address of a CURL handle used for reusing the same
* CURL handle with multiple requests.
* @param error_msg on return: If not NULL, then a textual error message
* is returned in case of a failing request. The caller
* must free the error string when it is not NULL.
* @param verbose if true, verbose messages are printed
*
* @returns zero for success, a negative errno in case of an error.
* -ENOTSUP is returned, if the feature is not installed.
*/
int ekmf_check_feature(const struct ekmf_config *config, CURL **curl_handle,
char **error_msg, bool verbose);
/**
* Request the EKMFWeb server's public signing key and store it into PEM file
* specified in field server_pubkey of the config structure.
*
* To perform a single request, set curl_handle to NULL. This will cause the
* function to initialize a new CURL handle, use it, and destroy it.
* If you plan to perform multiple requests to the same host, supply the address
* of a CURL pointer that is initially NULL. This function will then initialize
* a new CURL handle on the first call. On subsequent calls, pass in the address
* of the same CURL pointer so that the CURL handle is reused. After the last
* request, the CURL handle must be destroyed by calling ekmf_curl_destroy).
*
* @param config the configuration structure
* @param curl_handle address of a CURL handle used for reusing the same
* CURL handle with multiple requests.
* @param error_msg on return: If not NULL, then a textual error message
* is returned in case of a failing request. The caller
* must free the error string when it is not NULL.
* @param verbose if true, verbose messages are printed
*
* @returns zero for success, a negative errno in case of an error.
* -EACCES is returned, if no or no valid login token is available.
*/
int ekmf_get_public_key(const struct ekmf_config *config, CURL **curl_handle,
char **error_msg, bool verbose);
/**
* Requests a key to be retrieved from EKMFweb and imported under the current
* HSM's master key.
*
* To perform a single request, set curl_handle to NULL. This will cause the
* function to initialize a new CURL handle, use it, and destroy it.
* If you plan to perform multiple requests to the same host, supply the address
* of a CURL pointer that is initially NULL. This function will then initialize
* a new CURL handle on the first call. On subsequent calls, pass in the address
* of the same CURL pointer so that the CURL handle is reused. After the last
* request, the CURL handle must be destroyed by calling ekmf_curl_destroy).
*
* @param config the configuration structure
* @param curl_handle address of a CURL handle used for reusing the same
* CURL handle with multiple requests.
* @param key_uuid the UUID of the key to retrieve
* @param sess_ec_curve_nid The OpenSSL nid of the EC curve used for the session
* ECC key. If 0, then the default curve is used.
* @param sign_rsa_digest_nid The OpenSSL nid of a digest used to sign the
* request with if the identity key is an RSA-type key.
* If 0, then the default digest is used.
* Ignored for ECC-type identity keys.
* @param use_rsa_pss If true, and the identity key is an RSA-type key,
* use RSA-PSS to sign the request.
* @param signature_kid the Key ID for the signature of the request
* @param key_blob a buffer to store the retrieved key blob to
* @param key_blob_length On entry: the size ofthe buffer
* On return: the size of the key blob retrieved
* @param error_msg on return: If not NULL, then a textual error message
* is returned in case of a failing request. The caller
* must free the error string when it is not NULL.
* @param ext_lib External secure key crypto library to use
* @param verbose if true, verbose messages are printed
*
* @returns zero for success, a negative errno in case of an error.
* -EACCES is returned, if no or no valid login token is available.
* -EPERM is returned if the login token does not have permission to
* retrieve the key
*/
int ekmf_retrieve_key(const struct ekmf_config *config, CURL **curl_handle,
const char *key_uuid, int sess_ec_curve_nid,
int sign_rsa_digest_nid, bool use_rsa_pss,
const char *signature_kid, unsigned char *key_blob,
size_t *key_blob_length, char **error_msg,
const struct ekmf_ext_lib *ext_lib, bool verbose);
struct ekmf_tag_definition {
/** name of the tag */
const char *name;
/** Optional: description of the tag (can be NULL) */
const char *description;
};
struct ekmf_tag_def_list {
/** array of tag definitions */
struct ekmf_tag_definition *tag_defs;
/** number of tag definitions in array above */
size_t num_tag_defs;
};
struct ekmf_template_info {
/** name of the template */
const char *name;
/** UUID of the template */
const char *uuid;
/** type of the keys generated with this template , e.g. CIPHER */
const char *key_type;
/** algorithm of the keys generated with this template, e.g. AES */
const char *algorithm;
/** bit size of the keys generated with this template */
size_t key_size;
/** state of the template , e.g. ACTIVE */
const char *state;
/** state of the keys generated with this template , e.g. ACTIVE */
const char *key_state;
/** label template when generating keys with this template */
const char *label_template;
/** label tag definition list */
struct ekmf_tag_def_list label_tags;
/** true if keys generated with this template can be exported */
bool export_allowed;
/** the keystore type of the keys generated with this template */
const char *keystore_type;
/** Type of ECC curve, e.g. PRIME_CURVE (for algorithm = ECC) */
const char *curve;
/** timestamp when the template was created */
const char *created_on;
/** timestamp when the template was updated */
const char *updated_on;
};
struct ekmf_tag {
/** name of the tag */
const char *name;
/** value of the tag */
const char *value;
};
struct ekmf_tag_list {
/** array of tags */
struct ekmf_tag *tags;
/** number of tags in array above */
size_t num_tags;
};
struct ekmf_exporting_key {
/** name of the exporting key */
const char *name;
/** uuid of the exporting key */
const char *uuid;
};
struct ekmf_export_control {
/** If true, export is allowed using the exporting keys below */
bool export_allowed;
/** array of erporting keys */
struct ekmf_exporting_key *exporting_keys;
/** number of keys in array above */
size_t num_exporting_keys;
};
struct ekmf_key_info {
/** label (name) of the key */
const char *label;
/** Optional: description of the key (can be NULL) */
const char *description;
/** UUID of the key */
const char *uuid;
/** type of the key, e.g. CIPHER */
const char *key_type;
/** algorithm of the key, e.g. AES */
const char *algorithm;
/** bit size of the key */
size_t key_size;
/** state of the key, e.g. ACTIVE */
const char *state;
/** type of the keystore, e.g. PERVASIVE_ENCRYPTION */
const char *keystore_type;
/** name of the template used to generate the key */
const char *template;
/** UUID of the template used to generate the key */
const char *template_uuid;
/** label tag list */
struct ekmf_tag_list label_tags;
/** custom tag list */
struct ekmf_tag_list custom_tags;
/** export control information */
struct ekmf_export_control export_control;
/** timestamp when the key was activated */
const char *activate_on;
/** timestamp when the key expires */
const char *expires_on;
/** timestamp when the key was created */
const char *created_on;
/** timestamp when the key was updated */
const char *updated_on;
};
#define EKMF_KEY_STATE_PRE_ACTIVATION "PRE-ACTIVATION"
#define EKMF_KEY_STATE_ACTIVE "ACTIVE"
#define EKMF_KEY_STATE_DEACTIVATED "DEACTIVATED"
#define EKMF_KEY_STATE_COMPROMISED "COMPROMISED"
#define EKMF_KEY_STATE_DESTROYED "DESTROYED"
#define EKMF_KEY_STATE_DESTROYED_COMPROMISED "DESTROYED-COMPROMISED"
/**
* Callback function used with the ekmf_list_templates function. This
* callback is called for each template found.
*
* @param curl_handle a CURL handle that can be used to perform further
* EKMFWeb functions within the callback.
* @param template_info a struct containing information about the template.
* If any of the information needs to be kept, then the
* callback function must make a copy of the
* information. The memory holding the information
* passed to the callback is no longer valid after the
* callback has returned.
* @param private the private pointer that was specified with the
* ekmf_list_templates invocation.
*
* @returns zero for success, a negative errno in case of an error.
* When a nonzero return code is returned, the template listing process stops,
* and ekmf_list_templates returns the return code from the callback.
*/
typedef int (*ekmf_template_cb_t)(CURL *curl_handle,
struct ekmf_template_info *template_info,
void *private);
/**
* List available key templates. Only templates in state ACTIVE, with key
* algorithm AES and keystore type PERVASIVE_ENCRYPTION are listed. The
* templates are ordered by name in ascending order.
*
* To perform a single request, set curl_handle to NULL. This will cause the
* function to initialize a new CURL handle, use it, and destroy it.
* If you plan to perform multiple requests to the same host, supply the address
* of a CURL pointer that is initially NULL. This function will then initialize
* a new CURL handle on the first call. On subsequent calls, pass in the address
* of the same CURL pointer so that the CURL handle is reused. After the last
* request, the CURL handle must be destroyed by calling ekmf_curl_destroy).
*
* @param config the configuration structure
* @param curl_handle address of a CURL handle used for reusing the same
* CURL handle with multiple requests.
* @param template_cb a callback function that is called for each template
* found
* @param private a pointer that is passed as-is to the callback
* @param name_pattern a pattern to filter by name, or NULL to list all.
* @param state the state of the templates to list. If NULL then
* templates in state 'ACTIVE' are listed
* @param error_msg on return: If not NULL, then a textual error message
* is returned in case of a failing request. The caller
* must free the error string when it is not NULL.
* @param verbose if true, verbose messages are printed
*
* @returns zero for success, a negative errno in case of an error.
* -EACCES is returned, if no or no valid login token is available.
* -EPERM is returned if the login token does not have permission to
* list the templates
*/
int ekmf_list_templates(const struct ekmf_config *config, CURL **curl_handle,
ekmf_template_cb_t template_cb, void *private,
const char *name_pattern, const char *state,
char **error_msg, bool verbose);
/**
* Get a template by its UUID.
*
* To perform a single request, set curl_handle to NULL. This will cause the
* function to initialize a new CURL handle, use it, and destroy it.
* If you plan to perform multiple requests to the same host, supply the address
* of a CURL pointer that is initially NULL. This function will then initialize
* a new CURL handle on the first call. On subsequent calls, pass in the address
* of the same CURL pointer so that the CURL handle is reused. After the last
* request, the CURL handle must be destroyed by calling ekmf_curl_destroy).
*
* @param config the configuration structure
* @param curl_handle address of a CURL handle used for reusing the same
* CURL handle with multiple requests.
* @param template_uuid the UUID of the template to get
* @param template an address of a template info pointer. On return
* the pointer is updated to point to a newly allocated
* template info struct. It must be freed by the caller
* using ekmf_free_template_info when no longer needed.
* @param error_msg on return: If not NULL, then a textual error message
* is returned in case of a failing request. The caller
* must free the error string when it is not NULL.
* @param verbose if true, verbose messages are printed
*
* @returns zero for success, a negative errno in case of an error.
* -EACCES is returned, if no or no valid login token is available.
* -EPERM is returned if the login token does not have permission to
* get the template
*/
int ekmf_get_template(const struct ekmf_config *config, CURL **curl_handle,
const char *template_uuid,
struct ekmf_template_info **template, char **error_msg,
bool verbose);
/**
* Get the last used sequence number of a template by its UUID.
*
* To perform a single request, set curl_handle to NULL. This will cause the
* function to initialize a new CURL handle, use it, and destroy it.
* If you plan to perform multiple requests to the same host, supply the address
* of a CURL pointer that is initially NULL. This function will then initialize
* a new CURL handle on the first call. On subsequent calls, pass in the address
* of the same CURL pointer so that the CURL handle is reused. After the last
* request, the CURL handle must be destroyed by calling ekmf_curl_destroy).
*
* @param config the configuration structure
* @param curl_handle address of a CURL handle used for reusing the same
* CURL handle with multiple requests.
* @param template_uuid the UUID of the template to get
* @param seqNumber On return: the last used sequence number of this
* template.
* @param error_msg on return: If not NULL, then a textual error message
* is returned in case of a failing request. The caller
* must free the error string when it is not NULL.
* @param verbose if true, verbose messages are printed
*
* @returns zero for success, a negative errno in case of an error.
* -EACCES is returned, if no or no valid login token is available.
* -EPERM is returned if the login token does not have permission to
* get the template
*/
int ekmf_get_last_seq_no(const struct ekmf_config *config, CURL **curl_handle,
const char *template_uuid, unsigned int *seqNumber,
char **error_msg, bool verbose);
/**
* Clones a template info structure by making a deep copy of all strings and
* arrays.
* The copied template info must be freed using ekmf_free_template_info() by
* the caller.
*
* @param src the source template info structure
* @param dest the destination template info structure
*
* @returns zero for success, a negative errno in case of an error
*/
int ekmf_clone_template_info(const struct ekmf_template_info *src,
struct ekmf_template_info **dest);
/**
* Free a template info structure.
*
* @param template the template to free
*/
void ekmf_free_template_info(struct ekmf_template_info *template);
/**
* Callback function used with the ekmf_list_keys function. This
* callback is called for each ky found.
*
* @param curl_handle a CURL handle that can be used to perform further
* EKMFWeb functions within the callback.
* @param template_info a struct containing information about the key.
* If any of the information needs to be kept, then the
* callback function must make a copy of the
* information. The memory holding the information
* passed to the callback is no longer valid after the
* callback has returned.
* @param private the private pointer that was specified with the
* ekmf_list_keys invocation.
*
* @returns zero for success, a negative errno in case of an error.
* When a nonzero return code is returned, the key listing process stops,
* and ekmf_list_keys returns the return code from the callback.
*/
typedef int (*ekmf_key_cb_t)(CURL *curl_handle,
struct ekmf_key_info *key_info,
void *private);
/**
* List available keys. The keys are ordered by name in ascending order.
*
* To perform a single request, set curl_handle to NULL. This will cause the
* function to initialize a new CURL handle, use it, and destroy it.
* If you plan to perform multiple requests to the same host, supply the address
* of a CURL pointer that is initially NULL. This function will then initialize
* a new CURL handle on the first call. On subsequent calls, pass in the address
* of the same CURL pointer so that the CURL handle is reused. After the last
* request, the CURL handle must be destroyed by calling ekmf_curl_destroy).
*
* @param config the configuration structure
* @param curl_handle address of a CURL handle used for reusing the same
* CURL handle with multiple requests.
* @param key_cb a callback function that is called for each key
* found
* @param private a pointer that is passed as-is to the callback
* @param name_pattern a pattern to filter by name, or NULL to list all.
* @param states the states of the keys to list, or NULL to list keys
* in ACTIVE state only. Multiple states can be
* specified separated by comma.*
* @param tags a list of custom tags to use as filter, or NULL
* @param error_msg on return: If not NULL, then a textual error message
* is returned in case of a failing request. The caller
* must free the error string when it is not NULL.
* @param verbose if true, verbose messages are printed
*
* @returns zero for success, a negative errno in case of an error.
* -EACCES is returned, if no or no valid login token is available.
* -EPERM is returned if the login token does not have permission to
* list the keys
*/
int ekmf_list_keys(const struct ekmf_config *config, CURL **curl_handle,
ekmf_key_cb_t key_cb, void *private,
const char *name_pattern, const char *states,
const struct ekmf_tag_list *tags,
char **error_msg, bool verbose);
/**
* Get information about a key by its UUID.
*
* To perform a single request, set curl_handle to NULL. This will cause the
* function to initialize a new CURL handle, use it, and destroy it.
* If you plan to perform multiple requests to the same host, supply the address
* of a CURL pointer that is initially NULL. This function will then initialize
* a new CURL handle on the first call. On subsequent calls, pass in the address
* of the same CURL pointer so that the CURL handle is reused. After the last
* request, the CURL handle must be destroyed by calling ekmf_curl_destroy).
*
* @param config the configuration structure
* @param curl_handle address of a CURL handle used for reusing the same
* CURL handle with multiple requests.
* @param key_uuid the UUID of the key to get info for
* @param key an address of a key info pointer. On return
* the pointer is updated to point to a newly allocated
* key info struct. It must be freed by the caller
* using ekmf_free_key_info when no longer needed.
* @param error_msg on return: If not NULL, then a textual error message
* is returned in case of a failing request. The caller
* must free the error string when it is not NULL.
* @param verbose if true, verbose messages are printed
*
* @returns zero for success, a negative errno in case of an error.
* -EACCES is returned, if no or no valid login token is available.
* -EPERM is returned if the login token does not have permission to
* get the key info
*/
int ekmf_get_key_info(const struct ekmf_config *config, CURL **curl_handle,
const char *key_uuid, struct ekmf_key_info **key,
char **error_msg, bool verbose);
/**
* Changes the state of a key identified by its UUID. To update a key,
* the timestamp from the last update is required. This can be found in
* the key info struct in field update_on.
*
* To perform a single request, set curl_handle to NULL. This will cause the
* function to initialize a new CURL handle, use it, and destroy it.
* If you plan to perform multiple requests to the same host, supply the address
* of a CURL pointer that is initially NULL. This function will then initialize
* a new CURL handle on the first call. On subsequent calls, pass in the address
* of the same CURL pointer so that the CURL handle is reused. After the last
* request, the CURL handle must be destroyed by calling ekmf_curl_destroy).
*
* @param config the configuration structure
* @param curl_handle address of a CURL handle used for reusing the same
* CURL handle with multiple requests.
* @param key_uuid the UUID of the key to get info for
* @param new_state the new state of the key
* @param updated_on the timestamp of the last update (must match)
* @param error_msg on return: If not NULL, then a textual error message
* is returned in case of a failing request. The caller
* must free the error string when it is not NULL.
* @param verbose if true, verbose messages are printed
*
* @returns zero for success, a negative errno in case of an error.
* -EACCES is returned, if no or no valid login token is available.
* -EPERM is returned if the login token does not have permission to
* update the key.
* -EAGAIN is returned if the timestamp does not match, indicating that
* the key has been updated in the meantime.
*/
int ekmf_set_key_state(const struct ekmf_config *config, CURL **curl_handle,
const char *key_uuid, const char *new_state,
const char *updated_on, char **error_msg, bool verbose);
/**
* Sets (changed/adds) custom tags of a key identified by its UUID. To update a
* key, the timestamp from the last update is required. This can be found in
* the key info struct in field update_on.
*
* To perform a single request, set curl_handle to NULL. This will cause the
* function to initialize a new CURL handle, use it, and destroy it.
* If you plan to perform multiple requests to the same host, supply the address
* of a CURL pointer that is initially NULL. This function will then initialize
* a new CURL handle on the first call. On subsequent calls, pass in the address
* of the same CURL pointer so that the CURL handle is reused. After the last
* request, the CURL handle must be destroyed by calling ekmf_curl_destroy).
*
* @param config the configuration structure
* @param curl_handle address of a CURL handle used for reusing the same
* CURL handle with multiple requests.
* @param key_uuid the UUID of the key to get info for
* @param tags a list of tags to set
* @param updated_on the timestamp of the last update (must match)
* @param new_updated_on on return: if not NULL, the new timestamp of the
* current update. Can be used for subsequent updates
* on the key.
* @param error_msg on return: If not NULL, then a textual error message
* is returned in case of a failing request. The caller
* must free the error string when it is not NULL.
* @param verbose if true, verbose messages are printed
*
* @returns zero for success, a negative errno in case of an error.
* -EACCES is returned, if no or no valid login token is available.
* -EPERM is returned if the login token does not have permission to
* update the key.
* -EAGAIN is returned if the timestamp does not match, indicating that
* the key has been updated in the meantime.
*/
int ekmf_set_key_tags(const struct ekmf_config *config, CURL **curl_handle,
const char *key_uuid, const struct ekmf_tag_list *tags,
const char *updated_on, char **new_updated_on,
char **error_msg, bool verbose);
/**
* Deletes custom tags of a key identified by its UUID. To update a
* key, the timestamp from the last update is required. This can be found in
* the key info struct in field update_on.
*
* To perform a single request, set curl_handle to NULL. This will cause the
* function to initialize a new CURL handle, use it, and destroy it.
* If you plan to perform multiple requests to the same host, supply the address
* of a CURL pointer that is initially NULL. This function will then initialize
* a new CURL handle on the first call. On subsequent calls, pass in the address
* of the same CURL pointer so that the CURL handle is reused. After the last
* request, the CURL handle must be destroyed by calling ekmf_curl_destroy).
*
* @param config the configuration structure
* @param curl_handle address of a CURL handle used for reusing the same
* CURL handle with multiple requests.
* @param key_uuid the UUID of the key to get info for
* @param tags a list of tags to delete. Only the name of the tags
* must be present in the tag structs of the list, the
* values are ignored.
* @param updated_on the timestamp of the last update (must match)
* @param new_updated_on on return: if not NULL, the new timestamp of the
* current update. Can be used for subsequent updates
* on the key.
* @param error_msg on return: If not NULL, then a textual error message
* is returned in case of a failing request. The caller
* must free the error string when it is not NULL.
* @param verbose if true, verbose messages are printed
*
* @returns zero for success, a negative errno in case of an error.
* -EACCES is returned, if no or no valid login token is available.
* -EPERM is returned if the login token does not have permission to
* update the key.
* -EAGAIN is returned if the timestamp does not match, indicating that
* the key has been updated in the meantime.
*/
int ekmf_delete_key_tags(const struct ekmf_config *config, CURL **curl_handle,
const char *key_uuid, const struct ekmf_tag_list *tags,
const char *updated_on, char **new_updated_on,
char **error_msg, bool verbose);
/**
* Clones a key info structure by making a deep copy of all strings and
* arrays.
* The copied key info must be freed using ekmf_free_key_info() by
* the caller.
*
* @param src the source key info structure
* @param dest the destination key info structure
*
* @returns zero for success, a negative errno in case of an error
*/
int ekmf_clone_key_info(const struct ekmf_key_info *src,
struct ekmf_key_info **dest);
/**
* Free a key info structure.
*
* @param key the key info to free
*/
void ekmf_free_key_info(struct ekmf_key_info *key);
/**
* Generates a new key in EKMFWeb
*
* To perform a single request, set curl_handle to NULL. This will cause the
* function to initialize a new CURL handle, use it, and destroy it.
* If you plan to perform multiple requests to the same host, supply the address
* of a CURL pointer that is initially NULL. This function will then initialize
* a new CURL handle on the first call. On subsequent calls, pass in the address
* of the same CURL pointer so that the CURL handle is reused. After the last
* request, the CURL handle must be destroyed by calling ekmf_curl_destroy).
*
* @param config the configuration structure
* @param curl_handle address of a CURL handle used for reusing the same
* CURL handle with multiple requests.
* @param template the name of the template to generate the key with
* @param description Optional: a textual description of the key (can be
* NULL)
* @param label_tags list of label tags. The label tags are required as
* defined in the template
* @param custom_tags Optional: list of custom tags (can be NULL)
* @param exporting_key Optional: The uuid of the key that is allowed to
* export the newly generated key (can be NULL).
* @param certificate Optional: The certificate to generate an identity
* key from. Should be NULL for generating AES keys.
* @param certificate_size Optional: the size of the certificate. Required if
* certificate is not NULL.
* @param key_info Optional: On return: If not NULL, a key info struct
* is returned here containing key information. This
* must be freed by the caller with ekmf_free_key_info
* when no longer needed.
* @param error_msg on return: If not NULL, then a textual error message
* is returned in case of a failing request. The caller
* must free the error string when it is not NULL.
* @param verbose if true, verbose messages are printed
*
* @returns zero for success, a negative errno in case of an error.
* -EACCES is returned, if no or no valid login token is available.
* -EPERM is returned if the login token does not have permission to
* generate keys
*/
int ekmf_generate_key(const struct ekmf_config *config, CURL **curl_handle,
const char *template, const char *description,
const struct ekmf_tag_list *label_tags,
const struct ekmf_tag_list *custom_tags,
const char *exporting_key,
const unsigned char *certificate, size_t certificate_size,
struct ekmf_key_info **key_info,
char **error_msg, bool verbose);
/**
* Close the connection to the EKMFWeb server by destroying the CURL handle.
*
* @param curl_handle the CURL handle to destroy
*/
void ekmf_curl_destroy(CURL *curl_handle);
#endif