* 0 on decoding failure, or invalid parameter if any
* -1 on internal (malloc) failure
*/
-int CTLOG_new_from_base64(CTLOG **ct_log, const char *pkey_base64, const char *name)
+int CTLOG_new_from_base64_with_libctx(CTLOG **ct_log, const char *pkey_base64,
+ const char *name, OPENSSL_CTX *libctx,
+ const char *propq)
{
unsigned char *pkey_der = NULL;
int pkey_der_len;
EVP_PKEY *pkey = NULL;
if (ct_log == NULL) {
- CTerr(CT_F_CTLOG_NEW_FROM_BASE64, ERR_R_PASSED_INVALID_ARGUMENT);
+ CTerr(0, ERR_R_PASSED_INVALID_ARGUMENT);
return 0;
}
pkey_der_len = ct_base64_decode(pkey_base64, &pkey_der);
if (pkey_der_len < 0) {
- CTerr(CT_F_CTLOG_NEW_FROM_BASE64, CT_R_LOG_CONF_INVALID_KEY);
+ CTerr(0, CT_R_LOG_CONF_INVALID_KEY);
return 0;
}
pkey = d2i_PUBKEY(NULL, &p, pkey_der_len);
OPENSSL_free(pkey_der);
if (pkey == NULL) {
- CTerr(CT_F_CTLOG_NEW_FROM_BASE64, CT_R_LOG_CONF_INVALID_KEY);
+ CTerr(0, CT_R_LOG_CONF_INVALID_KEY);
return 0;
}
- *ct_log = CTLOG_new(pkey, name);
+ *ct_log = CTLOG_new_with_libctx(pkey, name, libctx, propq);
if (*ct_log == NULL) {
EVP_PKEY_free(pkey);
return 0;
return 1;
}
+
+int CTLOG_new_from_base64(CTLOG **ct_log, const char *pkey_base64,
+ const char *name)
+{
+ return CTLOG_new_from_base64_with_libctx(ct_log, pkey_base64, name, NULL,
+ NULL);
+}
size_t prederlen;
/* milliseconds since epoch (to check that the SCT isn't from the future) */
uint64_t epoch_time_in_ms;
+
+ OPENSSL_CTX *libctx;
+ char *propq;
};
/* Context when evaluating whether a Certificate Transparency policy is met */
CTLOG_STORE *log_store;
/* milliseconds since epoch (to check that SCTs aren't from the future) */
uint64_t epoch_time_in_ms;
+
+ OPENSSL_CTX *libctx;
+ char *propq;
};
/*
* Creates a new context for verifying an SCT.
*/
-SCT_CTX *SCT_CTX_new(void);
+SCT_CTX *SCT_CTX_new(OPENSSL_CTX *ctx, const char *propq);
/*
* Deletes an SCT verification context.
*/
* Information about a CT log server.
*/
struct ctlog_st {
+ OPENSSL_CTX *libctx;
+ char *propq;
char *name;
uint8_t log_id[CT_V1_HASHLEN];
EVP_PKEY *public_key;
* It takes ownership of any CTLOG instances added to it.
*/
struct ctlog_store_st {
+ OPENSSL_CTX *libctx;
+ char *propq;
STACK_OF(CTLOG) *logs;
};
}
/* Converts a log's public key into a SHA256 log ID */
-static int ct_v1_log_id_from_pkey(EVP_PKEY *pkey,
- unsigned char log_id[CT_V1_HASHLEN])
+static int ct_v1_log_id_from_pkey(CTLOG *log, EVP_PKEY *pkey)
{
int ret = 0;
unsigned char *pkey_der = NULL;
int pkey_der_len = i2d_PUBKEY(pkey, &pkey_der);
unsigned int len;
+ EVP_MD *sha256 = NULL;
if (pkey_der_len <= 0) {
CTerr(CT_F_CT_V1_LOG_ID_FROM_PKEY, CT_R_LOG_KEY_INVALID);
goto err;
}
+ sha256 = EVP_MD_fetch(log->libctx, "SHA2-256", log->propq);
+ if (sha256 == NULL) {
+ CTerr(CT_F_CT_V1_LOG_ID_FROM_PKEY, ERR_LIB_EVP);
+ goto err;
+ }
- ret = EVP_Digest(pkey_der, pkey_der_len, log_id, &len, EVP_sha256(), NULL);
+ ret = EVP_Digest(pkey_der, pkey_der_len, log->log_id, &len, sha256,
+ NULL);
err:
+ EVP_MD_free(sha256);
OPENSSL_free(pkey_der);
return ret;
}
-CTLOG_STORE *CTLOG_STORE_new(void)
+CTLOG_STORE *CTLOG_STORE_new_with_libctx(OPENSSL_CTX *libctx, const char *propq)
{
CTLOG_STORE *ret = OPENSSL_zalloc(sizeof(*ret));
if (ret == NULL) {
- CTerr(CT_F_CTLOG_STORE_NEW, ERR_R_MALLOC_FAILURE);
+ CTerr(0, ERR_R_MALLOC_FAILURE);
return NULL;
}
+ ret->libctx = libctx;
+ if (propq != NULL) {
+ ret->propq = OPENSSL_strdup(propq);
+ if (ret->propq == NULL) {
+ CTerr(0, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
+
ret->logs = sk_CTLOG_new_null();
- if (ret->logs == NULL)
+ if (ret->logs == NULL) {
+ CTerr(0, ERR_R_MALLOC_FAILURE);
goto err;
+ }
return ret;
err:
- OPENSSL_free(ret);
+ CTLOG_STORE_free(ret);
return NULL;
}
+CTLOG_STORE *CTLOG_STORE_new(void)
+{
+ return CTLOG_STORE_new_with_libctx(NULL, NULL);
+}
+
void CTLOG_STORE_free(CTLOG_STORE *store)
{
if (store != NULL) {
+ OPENSSL_free(store->propq);
sk_CTLOG_pop_free(store->logs, CTLOG_free);
OPENSSL_free(store);
}
}
-static int ctlog_new_from_conf(CTLOG **ct_log, const CONF *conf, const char *section)
+static int ctlog_new_from_conf(CTLOG_STORE *store, CTLOG **ct_log,
+ const CONF *conf, const char *section)
{
const char *description = NCONF_get_string(conf, section, "description");
char *pkey_base64;
return 0;
}
- return CTLOG_new_from_base64(ct_log, pkey_base64, description);
+ return CTLOG_new_from_base64_with_libctx(ct_log, pkey_base64, description,
+ store->libctx, store->propq);
}
int CTLOG_STORE_load_default_file(CTLOG_STORE *store)
if (tmp == NULL)
goto mem_err;
- ret = ctlog_new_from_conf(&ct_log, load_ctx->conf, tmp);
+ ret = ctlog_new_from_conf(load_ctx->log_store, &ct_log, load_ctx->conf, tmp);
OPENSSL_free(tmp);
if (ret < 0) {
* Takes ownership of the public key.
* Copies the name.
*/
-CTLOG *CTLOG_new(EVP_PKEY *public_key, const char *name)
+CTLOG *CTLOG_new_with_libctx(EVP_PKEY *public_key, const char *name,
+ OPENSSL_CTX *libctx, const char *propq)
{
CTLOG *ret = OPENSSL_zalloc(sizeof(*ret));
if (ret == NULL) {
- CTerr(CT_F_CTLOG_NEW, ERR_R_MALLOC_FAILURE);
+ CTerr(0, ERR_R_MALLOC_FAILURE);
return NULL;
}
+ ret->libctx = libctx;
+ if (propq != NULL) {
+ ret->name = OPENSSL_strdup(propq);
+ if (ret->propq == NULL) {
+ CTerr(0, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
+
ret->name = OPENSSL_strdup(name);
if (ret->name == NULL) {
- CTerr(CT_F_CTLOG_NEW, ERR_R_MALLOC_FAILURE);
+ CTerr(0, ERR_R_MALLOC_FAILURE);
goto err;
}
- if (ct_v1_log_id_from_pkey(public_key, ret->log_id) != 1)
+ if (ct_v1_log_id_from_pkey(ret, public_key) != 1)
goto err;
ret->public_key = public_key;
return NULL;
}
+CTLOG *CTLOG_new(EVP_PKEY *public_key, const char *name)
+{
+ return CTLOG_new_with_libctx(public_key, name, NULL, NULL);
+}
+
/* Frees CT log and associated structures */
void CTLOG_free(CTLOG *log)
{
if (log != NULL) {
OPENSSL_free(log->name);
EVP_PKEY_free(log->public_key);
+ OPENSSL_free(log->propq);
OPENSSL_free(log);
}
}
*/
static const time_t SCT_CLOCK_DRIFT_TOLERANCE = 300;
-CT_POLICY_EVAL_CTX *CT_POLICY_EVAL_CTX_new(void)
+CT_POLICY_EVAL_CTX *CT_POLICY_EVAL_CTX_new_with_libctx(OPENSSL_CTX *libctx,
+ const char *propq)
{
CT_POLICY_EVAL_CTX *ctx = OPENSSL_zalloc(sizeof(CT_POLICY_EVAL_CTX));
if (ctx == NULL) {
- CTerr(CT_F_CT_POLICY_EVAL_CTX_NEW, ERR_R_MALLOC_FAILURE);
+ CTerr(0, ERR_R_MALLOC_FAILURE);
return NULL;
}
+ ctx->libctx = libctx;
+ if (propq != NULL) {
+ ctx->propq = OPENSSL_strdup(propq);
+ if (ctx->propq == NULL) {
+ CTerr(0, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ }
+
/* time(NULL) shouldn't ever fail, so don't bother checking for -1. */
ctx->epoch_time_in_ms = (uint64_t)(time(NULL) + SCT_CLOCK_DRIFT_TOLERANCE) *
1000;
return ctx;
}
+CT_POLICY_EVAL_CTX *CT_POLICY_EVAL_CTX_new(void)
+{
+ return CT_POLICY_EVAL_CTX_new_with_libctx(NULL, NULL);
+}
+
void CT_POLICY_EVAL_CTX_free(CT_POLICY_EVAL_CTX *ctx)
{
if (ctx == NULL)
return;
X509_free(ctx->cert);
X509_free(ctx->issuer);
+ OPENSSL_free(ctx->propq);
OPENSSL_free(ctx);
}
return 0;
}
- sctx = SCT_CTX_new();
+ sctx = SCT_CTX_new(ctx->libctx, ctx->propq);
if (sctx == NULL)
goto err;
#include "ct_local.h"
-SCT_CTX *SCT_CTX_new(void)
+SCT_CTX *SCT_CTX_new(OPENSSL_CTX *libctx, const char *propq)
{
SCT_CTX *sctx = OPENSSL_zalloc(sizeof(*sctx));
if (sctx == NULL)
CTerr(CT_F_SCT_CTX_NEW, ERR_R_MALLOC_FAILURE);
+ sctx->libctx = libctx;
+ if (propq != NULL) {
+ sctx->propq = OPENSSL_strdup(propq);
+ if (sctx->propq == NULL) {
+ CTerr(CT_F_SCT_CTX_NEW, ERR_R_MALLOC_FAILURE);
+ OPENSSL_free(sctx);
+ return NULL;
+ }
+ }
+
return sctx;
}
OPENSSL_free(sctx->ihash);
OPENSSL_free(sctx->certder);
OPENSSL_free(sctx->preder);
+ OPENSSL_free(sctx->propq);
OPENSSL_free(sctx);
}
return 0;
}
-__owur static int ct_public_key_hash(X509_PUBKEY *pkey, unsigned char **hash,
- size_t *hash_len)
+__owur static int ct_public_key_hash(SCT_CTX *sctx, X509_PUBKEY *pkey,
+ unsigned char **hash, size_t *hash_len)
{
int ret = 0;
unsigned char *md = NULL, *der = NULL;
int der_len;
unsigned int md_len;
+ EVP_MD *sha256 = EVP_MD_fetch(sctx->libctx, "SHA2-256", sctx->propq);
+
+ if (sha256 == NULL)
+ goto err;
/* Reuse buffer if possible */
if (*hash != NULL && *hash_len >= SHA256_DIGEST_LENGTH) {
if (der_len <= 0)
goto err;
- if (!EVP_Digest(der, der_len, md, &md_len, EVP_sha256(), NULL))
+ if (!EVP_Digest(der, der_len, md, &md_len, sha256, NULL))
goto err;
if (md != *hash) {
md = NULL;
ret = 1;
err:
+ EVP_MD_free(sha256);
OPENSSL_free(md);
OPENSSL_free(der);
return ret;
int SCT_CTX_set1_issuer_pubkey(SCT_CTX *sctx, X509_PUBKEY *pubkey)
{
- return ct_public_key_hash(pubkey, &sctx->ihash, &sctx->ihashlen);
+ return ct_public_key_hash(sctx, pubkey, &sctx->ihash, &sctx->ihashlen);
}
int SCT_CTX_set1_pubkey(SCT_CTX *sctx, X509_PUBKEY *pubkey)
if (pkey == NULL)
return 0;
- if (!ct_public_key_hash(pubkey, &sctx->pkeyhash, &sctx->pkeyhashlen)) {
+ if (!ct_public_key_hash(sctx, pubkey, &sctx->pkeyhash, &sctx->pkeyhashlen)) {
EVP_PKEY_free(pkey);
return 0;
}
if (ctx == NULL)
goto end;
- if (!EVP_DigestVerifyInit(ctx, NULL, EVP_sha256(), NULL, sctx->pkey))
+ if (!EVP_DigestVerifyInit_ex(ctx, NULL, "SHA2-256", sctx->propq, sctx->pkey,
+ sctx->libctx))
goto end;
if (!sct_ctx_update(ctx, sctx, sct))
******************************************/
/*
- * Creates a new, empty policy evaluation context.
+ * Creates a new, empty policy evaluation context associated with the given
+ * library context and property query string.
* The caller is responsible for calling CT_POLICY_EVAL_CTX_free when finished
* with the CT_POLICY_EVAL_CTX.
*/
+CT_POLICY_EVAL_CTX *CT_POLICY_EVAL_CTX_new_with_libctx(OPENSSL_CTX *libctx,
+ const char *propq);
+
+/*
+ * The same as CT_POLICY_EVAL_CTX_new_with_libctx() but the default library
+ * context and property query string is used.
+ */
CT_POLICY_EVAL_CTX *CT_POLICY_EVAL_CTX_new(void);
/* Deletes a policy evaluation context and anything it owns. */
********************/
/*
- * Creates a new CT log instance with the given |public_key| and |name|.
+ * Creates a new CT log instance with the given |public_key| and |name| and
+ * associates it with the give library context |libctx| and property query
+ * string |propq|.
* Takes ownership of |public_key| but copies |name|.
* Returns NULL if malloc fails or if |public_key| cannot be converted to DER.
* Should be deleted by the caller using CTLOG_free when no longer needed.
*/
+CTLOG *CTLOG_new_with_libctx(EVP_PKEY *public_key, const char *name,
+ OPENSSL_CTX *libctx, const char *propq);
+
+/*
+ * The same as CTLOG_new_with_libctx except that the default library context and
+ * property query string are used.
+ */
CTLOG *CTLOG_new(EVP_PKEY *public_key, const char *name);
/*
* Creates a new CTLOG instance with the base64-encoded SubjectPublicKeyInfo DER
- * in |pkey_base64|. The |name| is a string to help users identify this log.
+ * in |pkey_base64| and associated with the given library context |libctx| and
+ * property query string |propq|. The |name| is a string to help users identify
+ * this log.
* Returns 1 on success, 0 on failure.
* Should be deleted by the caller using CTLOG_free when no longer needed.
*/
+int CTLOG_new_from_base64_with_libctx(CTLOG **ct_log, const char *pkey_base64,
+ const char *name, OPENSSL_CTX *libctx,
+ const char *propq);
+
+/*
+ * The same as CTLOG_new_from_base64_with_libctx() except that the default
+ * library context and property query string are used.
+ * Returns 1 on success, 0 on failure.
+ */
int CTLOG_new_from_base64(CTLOG ** ct_log,
const char *pkey_base64, const char *name);
**************************/
/*
- * Creates a new CT log store.
+ * Creates a new CT log store and associates it with the given libctx and
+ * property query string.
+ * Should be deleted by the caller using CTLOG_STORE_free when no longer needed.
+ */
+CTLOG_STORE *CTLOG_STORE_new_with_libctx(OPENSSL_CTX *libctx, const char *propq);
+
+/*
+ * Same as CTLOG_STORE_new_with_libctx except that the default libctx and
+ * property query string are used.
* Should be deleted by the caller using CTLOG_STORE_free when no longer needed.
*/
CTLOG_STORE *CTLOG_STORE_new(void);
EVP_PKEY_can_sign ? 3_0_0 EXIST::FUNCTION:
evp_pkey_get_EC_KEY_curve_nid ? 3_0_0 EXIST::FUNCTION:EC
X509_STORE_CTX_new_with_libctx ? 3_0_0 EXIST::FUNCTION:
+CT_POLICY_EVAL_CTX_new_with_libctx ? 3_0_0 EXIST::FUNCTION:CT
+CTLOG_new_with_libctx ? 3_0_0 EXIST::FUNCTION:CT
+CTLOG_new_from_base64_with_libctx ? 3_0_0 EXIST::FUNCTION:CT
+CTLOG_STORE_new_with_libctx ? 3_0_0 EXIST::FUNCTION:CT