jpayne@69: /* jpayne@69: * Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved. jpayne@69: * jpayne@69: * Licensed under the OpenSSL license (the "License"). You may not use jpayne@69: * this file except in compliance with the License. You can obtain a copy jpayne@69: * in the file LICENSE in the source distribution or at jpayne@69: * https://www.openssl.org/source/license.html jpayne@69: */ jpayne@69: jpayne@69: #ifndef HEADER_OSSL_STORE_H jpayne@69: # define HEADER_OSSL_STORE_H jpayne@69: jpayne@69: # include jpayne@69: # include jpayne@69: # include jpayne@69: # include jpayne@69: jpayne@69: # ifdef __cplusplus jpayne@69: extern "C" { jpayne@69: # endif jpayne@69: jpayne@69: /*- jpayne@69: * The main OSSL_STORE functions. jpayne@69: * ------------------------------ jpayne@69: * jpayne@69: * These allow applications to open a channel to a resource with supported jpayne@69: * data (keys, certs, crls, ...), read the data a piece at a time and decide jpayne@69: * what to do with it, and finally close. jpayne@69: */ jpayne@69: jpayne@69: typedef struct ossl_store_ctx_st OSSL_STORE_CTX; jpayne@69: jpayne@69: /* jpayne@69: * Typedef for the OSSL_STORE_INFO post processing callback. This can be used jpayne@69: * to massage the given OSSL_STORE_INFO, or to drop it entirely (by returning jpayne@69: * NULL). jpayne@69: */ jpayne@69: typedef OSSL_STORE_INFO *(*OSSL_STORE_post_process_info_fn)(OSSL_STORE_INFO *, jpayne@69: void *); jpayne@69: jpayne@69: /* jpayne@69: * Open a channel given a URI. The given UI method will be used any time the jpayne@69: * loader needs extra input, for example when a password or pin is needed, and jpayne@69: * will be passed the same user data every time it's needed in this context. jpayne@69: * jpayne@69: * Returns a context reference which represents the channel to communicate jpayne@69: * through. jpayne@69: */ jpayne@69: OSSL_STORE_CTX *OSSL_STORE_open(const char *uri, const UI_METHOD *ui_method, jpayne@69: void *ui_data, jpayne@69: OSSL_STORE_post_process_info_fn post_process, jpayne@69: void *post_process_data); jpayne@69: jpayne@69: /* jpayne@69: * Control / fine tune the OSSL_STORE channel. |cmd| determines what is to be jpayne@69: * done, and depends on the underlying loader (use OSSL_STORE_get0_scheme to jpayne@69: * determine which loader is used), except for common commands (see below). jpayne@69: * Each command takes different arguments. jpayne@69: */ jpayne@69: int OSSL_STORE_ctrl(OSSL_STORE_CTX *ctx, int cmd, ... /* args */); jpayne@69: int OSSL_STORE_vctrl(OSSL_STORE_CTX *ctx, int cmd, va_list args); jpayne@69: jpayne@69: /* jpayne@69: * Common ctrl commands that different loaders may choose to support. jpayne@69: */ jpayne@69: /* int on = 0 or 1; STORE_ctrl(ctx, STORE_C_USE_SECMEM, &on); */ jpayne@69: # define OSSL_STORE_C_USE_SECMEM 1 jpayne@69: /* Where custom commands start */ jpayne@69: # define OSSL_STORE_C_CUSTOM_START 100 jpayne@69: jpayne@69: /* jpayne@69: * Read one data item (a key, a cert, a CRL) that is supported by the OSSL_STORE jpayne@69: * functionality, given a context. jpayne@69: * Returns a OSSL_STORE_INFO pointer, from which OpenSSL typed data can be jpayne@69: * extracted with OSSL_STORE_INFO_get0_PKEY(), OSSL_STORE_INFO_get0_CERT(), ... jpayne@69: * NULL is returned on error, which may include that the data found at the URI jpayne@69: * can't be figured out for certain or is ambiguous. jpayne@69: */ jpayne@69: OSSL_STORE_INFO *OSSL_STORE_load(OSSL_STORE_CTX *ctx); jpayne@69: jpayne@69: /* jpayne@69: * Check if end of data (end of file) is reached jpayne@69: * Returns 1 on end, 0 otherwise. jpayne@69: */ jpayne@69: int OSSL_STORE_eof(OSSL_STORE_CTX *ctx); jpayne@69: jpayne@69: /* jpayne@69: * Check if an error occurred jpayne@69: * Returns 1 if it did, 0 otherwise. jpayne@69: */ jpayne@69: int OSSL_STORE_error(OSSL_STORE_CTX *ctx); jpayne@69: jpayne@69: /* jpayne@69: * Close the channel jpayne@69: * Returns 1 on success, 0 on error. jpayne@69: */ jpayne@69: int OSSL_STORE_close(OSSL_STORE_CTX *ctx); jpayne@69: jpayne@69: jpayne@69: /*- jpayne@69: * Extracting OpenSSL types from and creating new OSSL_STORE_INFOs jpayne@69: * --------------------------------------------------------------- jpayne@69: */ jpayne@69: jpayne@69: /* jpayne@69: * Types of data that can be ossl_stored in a OSSL_STORE_INFO. jpayne@69: * OSSL_STORE_INFO_NAME is typically found when getting a listing of jpayne@69: * available "files" / "tokens" / what have you. jpayne@69: */ jpayne@69: # define OSSL_STORE_INFO_NAME 1 /* char * */ jpayne@69: # define OSSL_STORE_INFO_PARAMS 2 /* EVP_PKEY * */ jpayne@69: # define OSSL_STORE_INFO_PKEY 3 /* EVP_PKEY * */ jpayne@69: # define OSSL_STORE_INFO_CERT 4 /* X509 * */ jpayne@69: # define OSSL_STORE_INFO_CRL 5 /* X509_CRL * */ jpayne@69: jpayne@69: /* jpayne@69: * Functions to generate OSSL_STORE_INFOs, one function for each type we jpayne@69: * support having in them, as well as a generic constructor. jpayne@69: * jpayne@69: * In all cases, ownership of the object is transferred to the OSSL_STORE_INFO jpayne@69: * and will therefore be freed when the OSSL_STORE_INFO is freed. jpayne@69: */ jpayne@69: OSSL_STORE_INFO *OSSL_STORE_INFO_new_NAME(char *name); jpayne@69: int OSSL_STORE_INFO_set0_NAME_description(OSSL_STORE_INFO *info, char *desc); jpayne@69: OSSL_STORE_INFO *OSSL_STORE_INFO_new_PARAMS(EVP_PKEY *params); jpayne@69: OSSL_STORE_INFO *OSSL_STORE_INFO_new_PKEY(EVP_PKEY *pkey); jpayne@69: OSSL_STORE_INFO *OSSL_STORE_INFO_new_CERT(X509 *x509); jpayne@69: OSSL_STORE_INFO *OSSL_STORE_INFO_new_CRL(X509_CRL *crl); jpayne@69: jpayne@69: /* jpayne@69: * Functions to try to extract data from a OSSL_STORE_INFO. jpayne@69: */ jpayne@69: int OSSL_STORE_INFO_get_type(const OSSL_STORE_INFO *info); jpayne@69: const char *OSSL_STORE_INFO_get0_NAME(const OSSL_STORE_INFO *info); jpayne@69: char *OSSL_STORE_INFO_get1_NAME(const OSSL_STORE_INFO *info); jpayne@69: const char *OSSL_STORE_INFO_get0_NAME_description(const OSSL_STORE_INFO *info); jpayne@69: char *OSSL_STORE_INFO_get1_NAME_description(const OSSL_STORE_INFO *info); jpayne@69: EVP_PKEY *OSSL_STORE_INFO_get0_PARAMS(const OSSL_STORE_INFO *info); jpayne@69: EVP_PKEY *OSSL_STORE_INFO_get1_PARAMS(const OSSL_STORE_INFO *info); jpayne@69: EVP_PKEY *OSSL_STORE_INFO_get0_PKEY(const OSSL_STORE_INFO *info); jpayne@69: EVP_PKEY *OSSL_STORE_INFO_get1_PKEY(const OSSL_STORE_INFO *info); jpayne@69: X509 *OSSL_STORE_INFO_get0_CERT(const OSSL_STORE_INFO *info); jpayne@69: X509 *OSSL_STORE_INFO_get1_CERT(const OSSL_STORE_INFO *info); jpayne@69: X509_CRL *OSSL_STORE_INFO_get0_CRL(const OSSL_STORE_INFO *info); jpayne@69: X509_CRL *OSSL_STORE_INFO_get1_CRL(const OSSL_STORE_INFO *info); jpayne@69: jpayne@69: const char *OSSL_STORE_INFO_type_string(int type); jpayne@69: jpayne@69: /* jpayne@69: * Free the OSSL_STORE_INFO jpayne@69: */ jpayne@69: void OSSL_STORE_INFO_free(OSSL_STORE_INFO *info); jpayne@69: jpayne@69: jpayne@69: /*- jpayne@69: * Functions to construct a search URI from a base URI and search criteria jpayne@69: * ----------------------------------------------------------------------- jpayne@69: */ jpayne@69: jpayne@69: /* OSSL_STORE search types */ jpayne@69: # define OSSL_STORE_SEARCH_BY_NAME 1 /* subject in certs, issuer in CRLs */ jpayne@69: # define OSSL_STORE_SEARCH_BY_ISSUER_SERIAL 2 jpayne@69: # define OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT 3 jpayne@69: # define OSSL_STORE_SEARCH_BY_ALIAS 4 jpayne@69: jpayne@69: /* To check what search types the scheme handler supports */ jpayne@69: int OSSL_STORE_supports_search(OSSL_STORE_CTX *ctx, int search_type); jpayne@69: jpayne@69: /* Search term constructors */ jpayne@69: /* jpayne@69: * The input is considered to be owned by the caller, and must therefore jpayne@69: * remain present throughout the lifetime of the returned OSSL_STORE_SEARCH jpayne@69: */ jpayne@69: OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_name(X509_NAME *name); jpayne@69: OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_issuer_serial(X509_NAME *name, jpayne@69: const ASN1_INTEGER jpayne@69: *serial); jpayne@69: OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_key_fingerprint(const EVP_MD *digest, jpayne@69: const unsigned char jpayne@69: *bytes, size_t len); jpayne@69: OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_alias(const char *alias); jpayne@69: jpayne@69: /* Search term destructor */ jpayne@69: void OSSL_STORE_SEARCH_free(OSSL_STORE_SEARCH *search); jpayne@69: jpayne@69: /* Search term accessors */ jpayne@69: int OSSL_STORE_SEARCH_get_type(const OSSL_STORE_SEARCH *criterion); jpayne@69: X509_NAME *OSSL_STORE_SEARCH_get0_name(OSSL_STORE_SEARCH *criterion); jpayne@69: const ASN1_INTEGER *OSSL_STORE_SEARCH_get0_serial(const OSSL_STORE_SEARCH jpayne@69: *criterion); jpayne@69: const unsigned char *OSSL_STORE_SEARCH_get0_bytes(const OSSL_STORE_SEARCH jpayne@69: *criterion, size_t *length); jpayne@69: const char *OSSL_STORE_SEARCH_get0_string(const OSSL_STORE_SEARCH *criterion); jpayne@69: const EVP_MD *OSSL_STORE_SEARCH_get0_digest(const OSSL_STORE_SEARCH *criterion); jpayne@69: jpayne@69: /* jpayne@69: * Add search criterion and expected return type (which can be unspecified) jpayne@69: * to the loading channel. This MUST happen before the first OSSL_STORE_load(). jpayne@69: */ jpayne@69: int OSSL_STORE_expect(OSSL_STORE_CTX *ctx, int expected_type); jpayne@69: int OSSL_STORE_find(OSSL_STORE_CTX *ctx, OSSL_STORE_SEARCH *search); jpayne@69: jpayne@69: jpayne@69: /*- jpayne@69: * Function to register a loader for the given URI scheme. jpayne@69: * ------------------------------------------------------- jpayne@69: * jpayne@69: * The loader receives all the main components of an URI except for the jpayne@69: * scheme. jpayne@69: */ jpayne@69: jpayne@69: typedef struct ossl_store_loader_st OSSL_STORE_LOADER; jpayne@69: OSSL_STORE_LOADER *OSSL_STORE_LOADER_new(ENGINE *e, const char *scheme); jpayne@69: const ENGINE *OSSL_STORE_LOADER_get0_engine(const OSSL_STORE_LOADER *loader); jpayne@69: const char *OSSL_STORE_LOADER_get0_scheme(const OSSL_STORE_LOADER *loader); jpayne@69: /* struct ossl_store_loader_ctx_st is defined differently by each loader */ jpayne@69: typedef struct ossl_store_loader_ctx_st OSSL_STORE_LOADER_CTX; jpayne@69: typedef OSSL_STORE_LOADER_CTX *(*OSSL_STORE_open_fn)(const OSSL_STORE_LOADER jpayne@69: *loader, jpayne@69: const char *uri, jpayne@69: const UI_METHOD *ui_method, jpayne@69: void *ui_data); jpayne@69: int OSSL_STORE_LOADER_set_open(OSSL_STORE_LOADER *loader, jpayne@69: OSSL_STORE_open_fn open_function); jpayne@69: typedef int (*OSSL_STORE_ctrl_fn)(OSSL_STORE_LOADER_CTX *ctx, int cmd, jpayne@69: va_list args); jpayne@69: int OSSL_STORE_LOADER_set_ctrl(OSSL_STORE_LOADER *loader, jpayne@69: OSSL_STORE_ctrl_fn ctrl_function); jpayne@69: typedef int (*OSSL_STORE_expect_fn)(OSSL_STORE_LOADER_CTX *ctx, int expected); jpayne@69: int OSSL_STORE_LOADER_set_expect(OSSL_STORE_LOADER *loader, jpayne@69: OSSL_STORE_expect_fn expect_function); jpayne@69: typedef int (*OSSL_STORE_find_fn)(OSSL_STORE_LOADER_CTX *ctx, jpayne@69: OSSL_STORE_SEARCH *criteria); jpayne@69: int OSSL_STORE_LOADER_set_find(OSSL_STORE_LOADER *loader, jpayne@69: OSSL_STORE_find_fn find_function); jpayne@69: typedef OSSL_STORE_INFO *(*OSSL_STORE_load_fn)(OSSL_STORE_LOADER_CTX *ctx, jpayne@69: const UI_METHOD *ui_method, jpayne@69: void *ui_data); jpayne@69: int OSSL_STORE_LOADER_set_load(OSSL_STORE_LOADER *loader, jpayne@69: OSSL_STORE_load_fn load_function); jpayne@69: typedef int (*OSSL_STORE_eof_fn)(OSSL_STORE_LOADER_CTX *ctx); jpayne@69: int OSSL_STORE_LOADER_set_eof(OSSL_STORE_LOADER *loader, jpayne@69: OSSL_STORE_eof_fn eof_function); jpayne@69: typedef int (*OSSL_STORE_error_fn)(OSSL_STORE_LOADER_CTX *ctx); jpayne@69: int OSSL_STORE_LOADER_set_error(OSSL_STORE_LOADER *loader, jpayne@69: OSSL_STORE_error_fn error_function); jpayne@69: typedef int (*OSSL_STORE_close_fn)(OSSL_STORE_LOADER_CTX *ctx); jpayne@69: int OSSL_STORE_LOADER_set_close(OSSL_STORE_LOADER *loader, jpayne@69: OSSL_STORE_close_fn close_function); jpayne@69: void OSSL_STORE_LOADER_free(OSSL_STORE_LOADER *loader); jpayne@69: jpayne@69: int OSSL_STORE_register_loader(OSSL_STORE_LOADER *loader); jpayne@69: OSSL_STORE_LOADER *OSSL_STORE_unregister_loader(const char *scheme); jpayne@69: jpayne@69: /*- jpayne@69: * Functions to list STORE loaders jpayne@69: * ------------------------------- jpayne@69: */ jpayne@69: int OSSL_STORE_do_all_loaders(void (*do_function) (const OSSL_STORE_LOADER jpayne@69: *loader, void *do_arg), jpayne@69: void *do_arg); jpayne@69: jpayne@69: # ifdef __cplusplus jpayne@69: } jpayne@69: # endif jpayne@69: #endif