Files
s390-tools/include/ekmfweb/ekmfweb.h
Ingo Franzki deb61b5cd9 libekmfweb: Add function to validate a certificate against the identity key
Function ekmf_validate_cert() checks if the public key contained in a x509
certificate matches the public key of the identity key.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Finn Callies <fcallies@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-11-07 14:33:26 +01:00

1091 lines
53 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);
/**
* Validates that a certificate has the same public key as the secure identity
* key (field identity_secure_key in config structure) .
*
* @param config the configuration structure. Only field
* identity_secure_key must be specified, all others
* are optional.
* @param x509_cert the X509 certificate object to validate
* @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, or certificate is not valid
* -ENOMEM: Failed to allocate memory
* any other errno from file I/O routines
*/
int ekmf_validate_cert(const struct ekmf_config *config, const X509 *x509_cert,
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