Latest update.
This commit is contained in:
+14
-5
@@ -132,7 +132,9 @@ SCT *SCT_new_from_base64(unsigned char version, const char *logid_base64,
|
||||
* 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;
|
||||
@@ -140,13 +142,13 @@ int CTLOG_new_from_base64(CTLOG **ct_log, const char *pkey_base64, const char *n
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -154,11 +156,11 @@ int CTLOG_new_from_base64(CTLOG **ct_log, const char *pkey_base64, const char *n
|
||||
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;
|
||||
@@ -166,3 +168,10 @@ int CTLOG_new_from_base64(CTLOG **ct_log, const char *pkey_base64, const char *n
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -100,6 +100,9 @@ struct sct_ctx_st {
|
||||
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 */
|
||||
@@ -109,12 +112,15 @@ struct ct_policy_eval_ctx_st {
|
||||
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.
|
||||
*/
|
||||
|
||||
+60
-14
@@ -22,6 +22,8 @@
|
||||
* 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;
|
||||
@@ -32,6 +34,8 @@ struct ctlog_st {
|
||||
* It takes ownership of any CTLOG instances added to it.
|
||||
*/
|
||||
struct ctlog_store_st {
|
||||
OPENSSL_CTX *libctx;
|
||||
char *propq;
|
||||
STACK_OF(CTLOG) *logs;
|
||||
};
|
||||
|
||||
@@ -70,53 +74,78 @@ static void ctlog_store_load_ctx_free(CTLOG_STORE_LOAD_CTX* ctx)
|
||||
}
|
||||
|
||||
/* 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;
|
||||
@@ -132,7 +161,8 @@ static int ctlog_new_from_conf(CTLOG **ct_log, const CONF *conf, const char *sec
|
||||
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)
|
||||
@@ -168,7 +198,7 @@ static int ctlog_store_load_log(const char *log_name, int log_name_len,
|
||||
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) {
|
||||
@@ -234,22 +264,32 @@ end:
|
||||
* 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;
|
||||
@@ -259,12 +299,18 @@ err:
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
+18
-2
@@ -25,15 +25,25 @@
|
||||
*/
|
||||
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;
|
||||
@@ -41,12 +51,18 @@ CT_POLICY_EVAL_CTX *CT_POLICY_EVAL_CTX_new(void)
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -312,7 +312,7 @@ int SCT_validate(SCT *sct, const CT_POLICY_EVAL_CTX *ctx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
sctx = SCT_CTX_new();
|
||||
sctx = SCT_CTX_new(ctx->libctx, ctx->propq);
|
||||
if (sctx == NULL)
|
||||
goto err;
|
||||
|
||||
|
||||
+22
-6
@@ -20,13 +20,23 @@
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
@@ -39,6 +49,7 @@ void SCT_CTX_free(SCT_CTX *sctx)
|
||||
OPENSSL_free(sctx->ihash);
|
||||
OPENSSL_free(sctx->certder);
|
||||
OPENSSL_free(sctx->preder);
|
||||
OPENSSL_free(sctx->propq);
|
||||
OPENSSL_free(sctx);
|
||||
}
|
||||
|
||||
@@ -191,13 +202,17 @@ err:
|
||||
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) {
|
||||
@@ -213,7 +228,7 @@ __owur static int ct_public_key_hash(X509_PUBKEY *pkey, unsigned char **hash,
|
||||
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) {
|
||||
@@ -225,6 +240,7 @@ __owur static int ct_public_key_hash(X509_PUBKEY *pkey, unsigned char **hash,
|
||||
md = NULL;
|
||||
ret = 1;
|
||||
err:
|
||||
EVP_MD_free(sha256);
|
||||
OPENSSL_free(md);
|
||||
OPENSSL_free(der);
|
||||
return ret;
|
||||
@@ -237,7 +253,7 @@ int SCT_CTX_set1_issuer(SCT_CTX *sctx, const X509 *issuer)
|
||||
|
||||
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)
|
||||
@@ -247,7 +263,7 @@ 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;
|
||||
}
|
||||
|
||||
+2
-1
@@ -122,7 +122,8 @@ int SCT_CTX_verify(const SCT_CTX *sctx, const SCT *sct)
|
||||
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))
|
||||
|
||||
Reference in New Issue
Block a user