*/
#ifndef HEADER_CT_H
-# define HEADER_CT_H
+#define HEADER_CT_H
-# include <openssl/opensslconf.h>
+#include <openssl/opensslconf.h>
-# ifndef OPENSSL_NO_CT
-# include <openssl/ossl_typ.h>
-# include <openssl/safestack.h>
-# include <openssl/x509.h>
-# include <openssl/cterr.h>
-# ifdef __cplusplus
+#ifndef OPENSSL_NO_CT
+#include <openssl/ossl_typ.h>
+#include <openssl/safestack.h>
+#include <openssl/x509.h>
+#include <openssl/cterr.h>
+#ifdef __cplusplus
extern "C" {
-# endif
+#endif
/* Minimum RSA key size, from RFC6962 */
-# define SCT_MIN_RSA_BITS 2048
+#define SCT_MIN_RSA_BITS 2048
/* All hashes are SHA256 in v1 of Certificate Transparency */
-# define CT_V1_HASHLEN SHA256_DIGEST_LENGTH
+#define CT_V1_HASHLEN SHA256_DIGEST_LENGTH
typedef enum {
- CT_LOG_ENTRY_TYPE_NOT_SET = -1,
- CT_LOG_ENTRY_TYPE_X509 = 0,
- CT_LOG_ENTRY_TYPE_PRECERT = 1
+ CT_LOG_ENTRY_TYPE_NOT_SET = -1,
+ CT_LOG_ENTRY_TYPE_X509 = 0,
+ CT_LOG_ENTRY_TYPE_PRECERT = 1
} ct_log_entry_type_t;
typedef enum {
- SCT_VERSION_NOT_SET = -1,
- SCT_VERSION_V1 = 0
+ SCT_VERSION_NOT_SET = -1,
+ SCT_VERSION_V1 = 0
} sct_version_t;
typedef enum {
- SCT_SOURCE_UNKNOWN,
- SCT_SOURCE_TLS_EXTENSION,
- SCT_SOURCE_X509V3_EXTENSION,
- SCT_SOURCE_OCSP_STAPLED_RESPONSE
+ SCT_SOURCE_UNKNOWN,
+ SCT_SOURCE_TLS_EXTENSION,
+ SCT_SOURCE_X509V3_EXTENSION,
+ SCT_SOURCE_OCSP_STAPLED_RESPONSE
} sct_source_t;
typedef enum {
- SCT_VALIDATION_STATUS_NOT_SET,
- SCT_VALIDATION_STATUS_UNKNOWN_LOG,
- SCT_VALIDATION_STATUS_VALID,
- SCT_VALIDATION_STATUS_INVALID,
- SCT_VALIDATION_STATUS_UNVERIFIED,
- SCT_VALIDATION_STATUS_UNKNOWN_VERSION
+ SCT_VALIDATION_STATUS_NOT_SET,
+ SCT_VALIDATION_STATUS_UNKNOWN_LOG,
+ SCT_VALIDATION_STATUS_VALID,
+ SCT_VALIDATION_STATUS_INVALID,
+ SCT_VALIDATION_STATUS_UNVERIFIED,
+ SCT_VALIDATION_STATUS_UNKNOWN_VERSION
} sct_validation_status_t;
DEFINE_STACK_OF(SCT)
* came from, so that the log names can be printed.
*/
void SCT_LIST_print(const STACK_OF(SCT) *sct_list, BIO *out, int indent,
- const char *separator, const CTLOG_STORE *logs);
+ const char *separator, const CTLOG_STORE *logs);
/*
* Gets the last result of validating this SCT.
* Returns a negative integer if an error occurs.
*/
__owur int SCT_LIST_validate(const STACK_OF(SCT) *scts,
- CT_POLICY_EVAL_CTX *ctx);
+ CT_POLICY_EVAL_CTX *ctx);
/*********************************
* not defined.
*/
STACK_OF(SCT) *o2i_SCT_LIST(STACK_OF(SCT) **a, const unsigned char **pp,
- size_t len);
+ size_t len);
/*
* Serialize (to DER format) a stack of SCTs and return the length.
* not defined.
*/
STACK_OF(SCT) *d2i_SCT_LIST(STACK_OF(SCT) **a, const unsigned char **pp,
- long len);
+ long len);
/*
* Serialize (to TLS format) an |sct| and write it to |out|.
const char *CTLOG_get0_name(const CTLOG *log);
/* Gets the ID of the CT log */
void CTLOG_get0_log_id(const CTLOG *log, const uint8_t **log_id,
- size_t *log_id_len);
+ size_t *log_id_len);
/* Gets the public key of the CT log */
EVP_PKEY *CTLOG_get0_public_key(const CTLOG *log);
* Returns the CT log, or NULL if no match is found.
*/
const CTLOG *CTLOG_STORE_get0_log_by_id(const CTLOG_STORE *store,
- const uint8_t *log_id,
- size_t log_id_len);
+ const uint8_t *log_id, size_t log_id_len);
/*
* Loads a CT log list into a |store| from a |file|.
* A new string will be malloc'd and assigned to |out|. This will be owned by
* the caller. Do not provide a pre-allocated string in |out|.
*/
-static int ct_base64_decode(const char *in, unsigned char **out)
+static int
+ct_base64_decode(const char *in, unsigned char **out)
{
- size_t inlen = strlen(in);
- int outlen, i;
- unsigned char *outbuf = NULL;
-
- if (inlen == 0) {
- *out = NULL;
- return 0;
- }
-
- outlen = (inlen / 4) * 3;
- outbuf = OPENSSL_malloc(outlen);
- if (outbuf == NULL) {
- CTerr(CT_F_CT_BASE64_DECODE, ERR_R_MALLOC_FAILURE);
- goto err;
- }
-
- outlen = EVP_DecodeBlock(outbuf, (unsigned char *)in, inlen);
- if (outlen < 0) {
- CTerr(CT_F_CT_BASE64_DECODE, CT_R_BASE64_DECODE_ERROR);
- goto err;
- }
-
- /* Subtract padding bytes from |outlen|. Any more than 2 is malformed. */
- i = 0;
- while (in[--inlen] == '=') {
- --outlen;
- if (++i > 2)
- goto err;
- }
-
- *out = outbuf;
- return outlen;
-err:
- OPENSSL_free(outbuf);
- return -1;
+ size_t inlen = strlen(in);
+ int outlen, i;
+ unsigned char *outbuf = NULL;
+
+ if (inlen == 0) {
+ *out = NULL;
+ return 0;
+ }
+
+ outlen = (inlen / 4) * 3;
+ outbuf = OPENSSL_malloc(outlen);
+ if (outbuf == NULL) {
+ CTerr(CT_F_CT_BASE64_DECODE, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ outlen = EVP_DecodeBlock(outbuf, (unsigned char *)in, inlen);
+ if (outlen < 0) {
+ CTerr(CT_F_CT_BASE64_DECODE, CT_R_BASE64_DECODE_ERROR);
+ goto err;
+ }
+
+ /* Subtract padding bytes from |outlen|. Any more than 2 is malformed. */
+ i = 0;
+ while (in[--inlen] == '=') {
+ --outlen;
+ if (++i > 2)
+ goto err;
+ }
+
+ *out = outbuf;
+ return outlen;
+ err:
+ OPENSSL_free(outbuf);
+ return -1;
}
-SCT *SCT_new_from_base64(unsigned char version, const char *logid_base64,
- ct_log_entry_type_t entry_type, uint64_t timestamp,
- const char *extensions_base64,
- const char *signature_base64)
+SCT *
+SCT_new_from_base64(unsigned char version, const char *logid_base64,
+ ct_log_entry_type_t entry_type, uint64_t timestamp,
+ const char *extensions_base64, const char *signature_base64)
{
- SCT *sct = SCT_new();
- unsigned char *dec = NULL;
- const unsigned char* p = NULL;
- int declen;
-
- if (sct == NULL) {
- CTerr(CT_F_SCT_NEW_FROM_BASE64, ERR_R_MALLOC_FAILURE);
- return NULL;
- }
-
- /*
- * RFC6962 section 4.1 says we "MUST NOT expect this to be 0", but we
- * can only construct SCT versions that have been defined.
- */
- if (!SCT_set_version(sct, version)) {
- CTerr(CT_F_SCT_NEW_FROM_BASE64, CT_R_SCT_UNSUPPORTED_VERSION);
- goto err;
- }
-
- declen = ct_base64_decode(logid_base64, &dec);
- if (declen < 0) {
- CTerr(CT_F_SCT_NEW_FROM_BASE64, X509_R_BASE64_DECODE_ERROR);
- goto err;
- }
- if (!SCT_set0_log_id(sct, dec, declen))
- goto err;
- dec = NULL;
-
- declen = ct_base64_decode(extensions_base64, &dec);
- if (declen < 0) {
- CTerr(CT_F_SCT_NEW_FROM_BASE64, X509_R_BASE64_DECODE_ERROR);
- goto err;
- }
- SCT_set0_extensions(sct, dec, declen);
- dec = NULL;
-
- declen = ct_base64_decode(signature_base64, &dec);
- if (declen < 0) {
- CTerr(CT_F_SCT_NEW_FROM_BASE64, X509_R_BASE64_DECODE_ERROR);
- goto err;
- }
-
- p = dec;
- if (o2i_SCT_signature(sct, &p, declen) <= 0)
- goto err;
- OPENSSL_free(dec);
- dec = NULL;
-
- SCT_set_timestamp(sct, timestamp);
-
- if (!SCT_set_log_entry_type(sct, entry_type))
- goto err;
-
- return sct;
+ SCT *sct = SCT_new();
+ unsigned char *dec = NULL;
+ const unsigned char* p = NULL;
+ int declen;
+
+ if (sct == NULL) {
+ CTerr(CT_F_SCT_NEW_FROM_BASE64, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ /*
+ * RFC6962 section 4.1 says we "MUST NOT expect this to be 0", but we
+ * can only construct SCT versions that have been defined.
+ */
+ if (!SCT_set_version(sct, version)) {
+ CTerr(CT_F_SCT_NEW_FROM_BASE64, CT_R_SCT_UNSUPPORTED_VERSION);
+ goto err;
+ }
+
+ declen = ct_base64_decode(logid_base64, &dec);
+ if (declen < 0) {
+ CTerr(CT_F_SCT_NEW_FROM_BASE64, X509_R_BASE64_DECODE_ERROR);
+ goto err;
+ }
+ if (!SCT_set0_log_id(sct, dec, declen))
+ goto err;
+ dec = NULL;
+
+ declen = ct_base64_decode(extensions_base64, &dec);
+ if (declen < 0) {
+ CTerr(CT_F_SCT_NEW_FROM_BASE64, X509_R_BASE64_DECODE_ERROR);
+ goto err;
+ }
+ SCT_set0_extensions(sct, dec, declen);
+ dec = NULL;
+
+ declen = ct_base64_decode(signature_base64, &dec);
+ if (declen < 0) {
+ CTerr(CT_F_SCT_NEW_FROM_BASE64, X509_R_BASE64_DECODE_ERROR);
+ goto err;
+ }
+
+ p = dec;
+ if (o2i_SCT_signature(sct, &p, declen) <= 0)
+ goto err;
+ OPENSSL_free(dec);
+ dec = NULL;
+
+ SCT_set_timestamp(sct, timestamp);
+
+ if (!SCT_set_log_entry_type(sct, entry_type))
+ goto err;
+
+ return sct;
err:
- OPENSSL_free(dec);
- SCT_free(sct);
- return NULL;
+ OPENSSL_free(dec);
+ SCT_free(sct);
+ return NULL;
}
/*
* 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(CTLOG **ct_log, const char *pkey_base64, const char *name)
{
- unsigned char *pkey_der = NULL;
- int pkey_der_len;
- const unsigned char *p;
- EVP_PKEY *pkey = NULL;
-
- if (ct_log == NULL) {
- CTerr(CT_F_CTLOG_NEW_FROM_BASE64, 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);
- return 0;
- }
-
- p = pkey_der;
- 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);
- return 0;
- }
-
- *ct_log = CTLOG_new(pkey, name);
- if (*ct_log == NULL) {
- EVP_PKEY_free(pkey);
- return 0;
- }
-
- return 1;
+ unsigned char *pkey_der = NULL;
+ int pkey_der_len;
+ const unsigned char *p;
+ EVP_PKEY *pkey = NULL;
+
+ if (ct_log == NULL) {
+ CTerr(CT_F_CTLOG_NEW_FROM_BASE64, 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);
+ return 0;
+ }
+
+ p = pkey_der;
+ 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);
+ return 0;
+ }
+
+ *ct_log = CTLOG_new(pkey, name);
+ if (*ct_log == NULL) {
+ EVP_PKEY_free(pkey);
+ return 0;
+ }
+
+ return 1;
}
#ifndef OPENSSL_NO_ERR
static const ERR_STRING_DATA CT_str_functs[] = {
- {ERR_PACK(ERR_LIB_CT, CT_F_CTLOG_NEW, 0), "CTLOG_new"},
- {ERR_PACK(ERR_LIB_CT, CT_F_CTLOG_NEW_FROM_BASE64, 0),
- "CTLOG_new_from_base64"},
- {ERR_PACK(ERR_LIB_CT, CT_F_CTLOG_NEW_FROM_CONF, 0), "ctlog_new_from_conf"},
- {ERR_PACK(ERR_LIB_CT, CT_F_CTLOG_STORE_LOAD_CTX_NEW, 0),
- "ctlog_store_load_ctx_new"},
- {ERR_PACK(ERR_LIB_CT, CT_F_CTLOG_STORE_LOAD_FILE, 0),
- "CTLOG_STORE_load_file"},
- {ERR_PACK(ERR_LIB_CT, CT_F_CTLOG_STORE_LOAD_LOG, 0),
- "ctlog_store_load_log"},
- {ERR_PACK(ERR_LIB_CT, CT_F_CTLOG_STORE_NEW, 0), "CTLOG_STORE_new"},
- {ERR_PACK(ERR_LIB_CT, CT_F_CT_BASE64_DECODE, 0), "ct_base64_decode"},
- {ERR_PACK(ERR_LIB_CT, CT_F_CT_POLICY_EVAL_CTX_NEW, 0),
- "CT_POLICY_EVAL_CTX_new"},
- {ERR_PACK(ERR_LIB_CT, CT_F_CT_V1_LOG_ID_FROM_PKEY, 0),
- "ct_v1_log_id_from_pkey"},
- {ERR_PACK(ERR_LIB_CT, CT_F_I2O_SCT, 0), "i2o_SCT"},
- {ERR_PACK(ERR_LIB_CT, CT_F_I2O_SCT_LIST, 0), "i2o_SCT_LIST"},
- {ERR_PACK(ERR_LIB_CT, CT_F_I2O_SCT_SIGNATURE, 0), "i2o_SCT_signature"},
- {ERR_PACK(ERR_LIB_CT, CT_F_O2I_SCT, 0), "o2i_SCT"},
- {ERR_PACK(ERR_LIB_CT, CT_F_O2I_SCT_LIST, 0), "o2i_SCT_LIST"},
- {ERR_PACK(ERR_LIB_CT, CT_F_O2I_SCT_SIGNATURE, 0), "o2i_SCT_signature"},
- {ERR_PACK(ERR_LIB_CT, CT_F_SCT_CTX_NEW, 0), "SCT_CTX_new"},
- {ERR_PACK(ERR_LIB_CT, CT_F_SCT_CTX_VERIFY, 0), "SCT_CTX_verify"},
- {ERR_PACK(ERR_LIB_CT, CT_F_SCT_NEW, 0), "SCT_new"},
- {ERR_PACK(ERR_LIB_CT, CT_F_SCT_NEW_FROM_BASE64, 0), "SCT_new_from_base64"},
- {ERR_PACK(ERR_LIB_CT, CT_F_SCT_SET0_LOG_ID, 0), "SCT_set0_log_id"},
- {ERR_PACK(ERR_LIB_CT, CT_F_SCT_SET1_EXTENSIONS, 0), "SCT_set1_extensions"},
- {ERR_PACK(ERR_LIB_CT, CT_F_SCT_SET1_LOG_ID, 0), "SCT_set1_log_id"},
- {ERR_PACK(ERR_LIB_CT, CT_F_SCT_SET1_SIGNATURE, 0), "SCT_set1_signature"},
- {ERR_PACK(ERR_LIB_CT, CT_F_SCT_SET_LOG_ENTRY_TYPE, 0),
- "SCT_set_log_entry_type"},
- {ERR_PACK(ERR_LIB_CT, CT_F_SCT_SET_SIGNATURE_NID, 0),
- "SCT_set_signature_nid"},
- {ERR_PACK(ERR_LIB_CT, CT_F_SCT_SET_VERSION, 0), "SCT_set_version"},
- {0, NULL}
+ {ERR_PACK(ERR_LIB_CT, CT_F_CTLOG_NEW, 0), "CTLOG_new"},
+ {ERR_PACK(ERR_LIB_CT, CT_F_CTLOG_NEW_FROM_BASE64, 0),
+ "CTLOG_new_from_base64"},
+ {ERR_PACK(ERR_LIB_CT, CT_F_CTLOG_NEW_FROM_CONF, 0), "ctlog_new_from_conf"},
+ {ERR_PACK(ERR_LIB_CT, CT_F_CTLOG_STORE_LOAD_CTX_NEW, 0),
+ "ctlog_store_load_ctx_new"},
+ {ERR_PACK(ERR_LIB_CT, CT_F_CTLOG_STORE_LOAD_FILE, 0),
+ "CTLOG_STORE_load_file"},
+ {ERR_PACK(ERR_LIB_CT, CT_F_CTLOG_STORE_LOAD_LOG, 0),
+ "ctlog_store_load_log"},
+ {ERR_PACK(ERR_LIB_CT, CT_F_CTLOG_STORE_NEW, 0), "CTLOG_STORE_new"},
+ {ERR_PACK(ERR_LIB_CT, CT_F_CT_BASE64_DECODE, 0), "ct_base64_decode"},
+ {ERR_PACK(ERR_LIB_CT, CT_F_CT_POLICY_EVAL_CTX_NEW, 0),
+ "CT_POLICY_EVAL_CTX_new"},
+ {ERR_PACK(ERR_LIB_CT, CT_F_CT_V1_LOG_ID_FROM_PKEY, 0),
+ "ct_v1_log_id_from_pkey"},
+ {ERR_PACK(ERR_LIB_CT, CT_F_I2O_SCT, 0), "i2o_SCT"},
+ {ERR_PACK(ERR_LIB_CT, CT_F_I2O_SCT_LIST, 0), "i2o_SCT_LIST"},
+ {ERR_PACK(ERR_LIB_CT, CT_F_I2O_SCT_SIGNATURE, 0), "i2o_SCT_signature"},
+ {ERR_PACK(ERR_LIB_CT, CT_F_O2I_SCT, 0), "o2i_SCT"},
+ {ERR_PACK(ERR_LIB_CT, CT_F_O2I_SCT_LIST, 0), "o2i_SCT_LIST"},
+ {ERR_PACK(ERR_LIB_CT, CT_F_O2I_SCT_SIGNATURE, 0), "o2i_SCT_signature"},
+ {ERR_PACK(ERR_LIB_CT, CT_F_SCT_CTX_NEW, 0), "SCT_CTX_new"},
+ {ERR_PACK(ERR_LIB_CT, CT_F_SCT_CTX_VERIFY, 0), "SCT_CTX_verify"},
+ {ERR_PACK(ERR_LIB_CT, CT_F_SCT_NEW, 0), "SCT_new"},
+ {ERR_PACK(ERR_LIB_CT, CT_F_SCT_NEW_FROM_BASE64, 0), "SCT_new_from_base64"},
+ {ERR_PACK(ERR_LIB_CT, CT_F_SCT_SET0_LOG_ID, 0), "SCT_set0_log_id"},
+ {ERR_PACK(ERR_LIB_CT, CT_F_SCT_SET1_EXTENSIONS, 0), "SCT_set1_extensions"},
+ {ERR_PACK(ERR_LIB_CT, CT_F_SCT_SET1_LOG_ID, 0), "SCT_set1_log_id"},
+ {ERR_PACK(ERR_LIB_CT, CT_F_SCT_SET1_SIGNATURE, 0), "SCT_set1_signature"},
+ {ERR_PACK(ERR_LIB_CT, CT_F_SCT_SET_LOG_ENTRY_TYPE, 0),
+ "SCT_set_log_entry_type"},
+ {ERR_PACK(ERR_LIB_CT, CT_F_SCT_SET_SIGNATURE_NID, 0),
+ "SCT_set_signature_nid"},
+ {ERR_PACK(ERR_LIB_CT, CT_F_SCT_SET_VERSION, 0), "SCT_set_version"},
+ {0, NULL}
};
static const ERR_STRING_DATA CT_str_reasons[] = {
- {ERR_PACK(ERR_LIB_CT, 0, CT_R_BASE64_DECODE_ERROR), "base64 decode error"},
- {ERR_PACK(ERR_LIB_CT, 0, CT_R_INVALID_LOG_ID_LENGTH),
- "invalid log id length"},
- {ERR_PACK(ERR_LIB_CT, 0, CT_R_LOG_CONF_INVALID), "log conf invalid"},
- {ERR_PACK(ERR_LIB_CT, 0, CT_R_LOG_CONF_INVALID_KEY),
- "log conf invalid key"},
- {ERR_PACK(ERR_LIB_CT, 0, CT_R_LOG_CONF_MISSING_DESCRIPTION),
- "log conf missing description"},
- {ERR_PACK(ERR_LIB_CT, 0, CT_R_LOG_CONF_MISSING_KEY),
- "log conf missing key"},
- {ERR_PACK(ERR_LIB_CT, 0, CT_R_LOG_KEY_INVALID), "log key invalid"},
- {ERR_PACK(ERR_LIB_CT, 0, CT_R_SCT_FUTURE_TIMESTAMP),
- "sct future timestamp"},
- {ERR_PACK(ERR_LIB_CT, 0, CT_R_SCT_INVALID), "sct invalid"},
- {ERR_PACK(ERR_LIB_CT, 0, CT_R_SCT_INVALID_SIGNATURE),
- "sct invalid signature"},
- {ERR_PACK(ERR_LIB_CT, 0, CT_R_SCT_LIST_INVALID), "sct list invalid"},
- {ERR_PACK(ERR_LIB_CT, 0, CT_R_SCT_LOG_ID_MISMATCH), "sct log id mismatch"},
- {ERR_PACK(ERR_LIB_CT, 0, CT_R_SCT_NOT_SET), "sct not set"},
- {ERR_PACK(ERR_LIB_CT, 0, CT_R_SCT_UNSUPPORTED_VERSION),
- "sct unsupported version"},
- {ERR_PACK(ERR_LIB_CT, 0, CT_R_UNRECOGNIZED_SIGNATURE_NID),
- "unrecognized signature nid"},
- {ERR_PACK(ERR_LIB_CT, 0, CT_R_UNSUPPORTED_ENTRY_TYPE),
- "unsupported entry type"},
- {ERR_PACK(ERR_LIB_CT, 0, CT_R_UNSUPPORTED_VERSION), "unsupported version"},
- {0, NULL}
+ {ERR_PACK(ERR_LIB_CT, 0, CT_R_BASE64_DECODE_ERROR), "base64 decode error"},
+ {ERR_PACK(ERR_LIB_CT, 0, CT_R_INVALID_LOG_ID_LENGTH),
+ "invalid log id length"},
+ {ERR_PACK(ERR_LIB_CT, 0, CT_R_LOG_CONF_INVALID), "log conf invalid"},
+ {ERR_PACK(ERR_LIB_CT, 0, CT_R_LOG_CONF_INVALID_KEY),
+ "log conf invalid key"},
+ {ERR_PACK(ERR_LIB_CT, 0, CT_R_LOG_CONF_MISSING_DESCRIPTION),
+ "log conf missing description"},
+ {ERR_PACK(ERR_LIB_CT, 0, CT_R_LOG_CONF_MISSING_KEY),
+ "log conf missing key"},
+ {ERR_PACK(ERR_LIB_CT, 0, CT_R_LOG_KEY_INVALID), "log key invalid"},
+ {ERR_PACK(ERR_LIB_CT, 0, CT_R_SCT_FUTURE_TIMESTAMP),
+ "sct future timestamp"},
+ {ERR_PACK(ERR_LIB_CT, 0, CT_R_SCT_INVALID), "sct invalid"},
+ {ERR_PACK(ERR_LIB_CT, 0, CT_R_SCT_INVALID_SIGNATURE),
+ "sct invalid signature"},
+ {ERR_PACK(ERR_LIB_CT, 0, CT_R_SCT_LIST_INVALID), "sct list invalid"},
+ {ERR_PACK(ERR_LIB_CT, 0, CT_R_SCT_LOG_ID_MISMATCH), "sct log id mismatch"},
+ {ERR_PACK(ERR_LIB_CT, 0, CT_R_SCT_NOT_SET), "sct not set"},
+ {ERR_PACK(ERR_LIB_CT, 0, CT_R_SCT_UNSUPPORTED_VERSION),
+ "sct unsupported version"},
+ {ERR_PACK(ERR_LIB_CT, 0, CT_R_UNRECOGNIZED_SIGNATURE_NID),
+ "unrecognized signature nid"},
+ {ERR_PACK(ERR_LIB_CT, 0, CT_R_UNSUPPORTED_ENTRY_TYPE),
+ "unsupported entry type"},
+ {ERR_PACK(ERR_LIB_CT, 0, CT_R_UNSUPPORTED_VERSION), "unsupported version"},
+ {0, NULL}
};
#endif
int ERR_load_CT_strings(void)
{
#ifndef OPENSSL_NO_ERR
- if (ERR_func_error_string(CT_str_functs[0].error) == NULL) {
- ERR_load_strings_const(CT_str_functs);
- ERR_load_strings_const(CT_str_reasons);
- }
+ if (ERR_func_error_string(CT_str_functs[0].error) == NULL) {
+ ERR_load_strings_const(CT_str_functs);
+ ERR_load_strings_const(CT_str_reasons);
+ }
#endif
- return 1;
+ return 1;
}
* From RFC6962: opaque SerializedSCT<1..2^16-1>; struct { SerializedSCT
* sct_list <1..2^16-1>; } SignedCertificateTimestampList;
*/
-# define MAX_SCT_SIZE 65535
-# define MAX_SCT_LIST_SIZE MAX_SCT_SIZE
+#define MAX_SCT_SIZE 65535
+#define MAX_SCT_LIST_SIZE MAX_SCT_SIZE
/*
* Macros to read and write integers in network-byte order.
/* Signed Certificate Timestamp */
struct sct_st {
- sct_version_t version;
- /* If version is not SCT_VERSION_V1, this contains the encoded SCT */
- unsigned char *sct;
- size_t sct_len;
- /* If version is SCT_VERSION_V1, fields below contain components of the SCT */
- unsigned char *log_id;
- size_t log_id_len;
- /*
- * Note, we cannot distinguish between an unset timestamp, and one
- * that is set to 0. However since CT didn't exist in 1970, no real
- * SCT should ever be set as such.
- */
- uint64_t timestamp;
- unsigned char *ext;
- size_t ext_len;
- unsigned char hash_alg;
- unsigned char sig_alg;
- unsigned char *sig;
- size_t sig_len;
- /* Log entry type */
- ct_log_entry_type_t entry_type;
- /* Where this SCT was found, e.g. certificate, OCSP response, etc. */
- sct_source_t source;
- /* The result of the last attempt to validate this SCT. */
- sct_validation_status_t validation_status;
+ sct_version_t version;
+ /* If version is not SCT_VERSION_V1, this contains the encoded SCT */
+ unsigned char *sct;
+ size_t sct_len;
+ /* If version is SCT_VERSION_V1, fields below contain components of the SCT */
+ unsigned char *log_id;
+ size_t log_id_len;
+ /*
+ * Note, we cannot distinguish between an unset timestamp, and one
+ * that is set to 0. However since CT didn't exist in 1970, no real
+ * SCT should ever be set as such.
+ */
+ uint64_t timestamp;
+ unsigned char *ext;
+ size_t ext_len;
+ unsigned char hash_alg;
+ unsigned char sig_alg;
+ unsigned char *sig;
+ size_t sig_len;
+ /* Log entry type */
+ ct_log_entry_type_t entry_type;
+ /* Where this SCT was found, e.g. certificate, OCSP response, etc. */
+ sct_source_t source;
+ /* The result of the last attempt to validate this SCT. */
+ sct_validation_status_t validation_status;
};
/* Miscellaneous data that is useful when verifying an SCT */
struct sct_ctx_st {
- /* Public key */
- EVP_PKEY *pkey;
- /* Hash of public key */
- unsigned char *pkeyhash;
- size_t pkeyhashlen;
- /* For pre-certificate: issuer public key hash */
- unsigned char *ihash;
- size_t ihashlen;
- /* certificate encoding */
- unsigned char *certder;
- size_t certderlen;
- /* pre-certificate encoding */
- unsigned char *preder;
- size_t prederlen;
- /* milliseconds since epoch (to check that the SCT isn't from the future) */
- uint64_t epoch_time_in_ms;
+ /* Public key */
+ EVP_PKEY *pkey;
+ /* Hash of public key */
+ unsigned char *pkeyhash;
+ size_t pkeyhashlen;
+ /* For pre-certificate: issuer public key hash */
+ unsigned char *ihash;
+ size_t ihashlen;
+ /* certificate encoding */
+ unsigned char *certder;
+ size_t certderlen;
+ /* pre-certificate encoding */
+ unsigned char *preder;
+ size_t prederlen;
+ /* milliseconds since epoch (to check that the SCT isn't from the future) */
+ uint64_t epoch_time_in_ms;
};
/* Context when evaluating whether a Certificate Transparency policy is met */
struct ct_policy_eval_ctx_st {
- X509 *cert;
- X509 *issuer;
- CTLOG_STORE *log_store;
- /* milliseconds since epoch (to check that SCTs aren't from the future) */
- uint64_t epoch_time_in_ms;
+ X509 *cert;
+ X509 *issuer;
+ CTLOG_STORE *log_store;
+ /* milliseconds since epoch (to check that SCTs aren't from the future) */
+ uint64_t epoch_time_in_ms;
};
/*
* Information about a CT log server.
*/
struct ctlog_st {
- char *name;
- uint8_t log_id[CT_V1_HASHLEN];
- EVP_PKEY *public_key;
+ 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 {
- STACK_OF(CTLOG) *logs;
+ STACK_OF(CTLOG) *logs;
};
/* The context when loading a CT log list from a CONF file. */
typedef struct ctlog_store_load_ctx_st {
- CTLOG_STORE *log_store;
- CONF *conf;
- size_t invalid_log_entries;
+ CTLOG_STORE *log_store;
+ CONF *conf;
+ size_t invalid_log_entries;
} CTLOG_STORE_LOAD_CTX;
/*
*/
static void ctlog_store_load_ctx_free(CTLOG_STORE_LOAD_CTX* ctx);
-static CTLOG_STORE_LOAD_CTX *ctlog_store_load_ctx_new(void)
+static CTLOG_STORE_LOAD_CTX *
+ctlog_store_load_ctx_new(void)
{
- CTLOG_STORE_LOAD_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
+ CTLOG_STORE_LOAD_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
- if (ctx == NULL)
- CTerr(CT_F_CTLOG_STORE_LOAD_CTX_NEW, ERR_R_MALLOC_FAILURE);
+ if (ctx == NULL)
+ CTerr(CT_F_CTLOG_STORE_LOAD_CTX_NEW, ERR_R_MALLOC_FAILURE);
- return ctx;
+ return ctx;
}
-static void ctlog_store_load_ctx_free(CTLOG_STORE_LOAD_CTX* ctx)
+static void
+ctlog_store_load_ctx_free(CTLOG_STORE_LOAD_CTX* ctx)
{
- OPENSSL_free(ctx);
+ OPENSSL_free(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(EVP_PKEY *pkey, unsigned char log_id[CT_V1_HASHLEN])
{
- int ret = 0;
- unsigned char *pkey_der = NULL;
- int pkey_der_len = i2d_PUBKEY(pkey, &pkey_der);
-
- if (pkey_der_len <= 0) {
- CTerr(CT_F_CT_V1_LOG_ID_FROM_PKEY, CT_R_LOG_KEY_INVALID);
- goto err;
- }
-
- SHA256(pkey_der, pkey_der_len, log_id);
- ret = 1;
-err:
- OPENSSL_free(pkey_der);
- return ret;
+ int ret = 0;
+ unsigned char *pkey_der = NULL;
+ int pkey_der_len = i2d_PUBKEY(pkey, &pkey_der);
+
+ if (pkey_der_len <= 0) {
+ CTerr(CT_F_CT_V1_LOG_ID_FROM_PKEY, CT_R_LOG_KEY_INVALID);
+ goto err;
+ }
+
+ SHA256(pkey_der, pkey_der_len, log_id);
+ ret = 1;
+ err:
+ OPENSSL_free(pkey_der);
+ return ret;
}
-CTLOG_STORE *CTLOG_STORE_new(void)
+CTLOG_STORE *
+CTLOG_STORE_new(void)
{
- CTLOG_STORE *ret = OPENSSL_zalloc(sizeof(*ret));
+ CTLOG_STORE *ret = OPENSSL_zalloc(sizeof(*ret));
- if (ret == NULL) {
- CTerr(CT_F_CTLOG_STORE_NEW, ERR_R_MALLOC_FAILURE);
- return NULL;
- }
+ if (ret == NULL) {
+ CTerr(CT_F_CTLOG_STORE_NEW, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
- ret->logs = sk_CTLOG_new_null();
- if (ret->logs == NULL)
- goto err;
+ ret->logs = sk_CTLOG_new_null();
+ if (ret->logs == NULL)
+ goto err;
- return ret;
+ return ret;
err:
- OPENSSL_free(ret);
- return NULL;
+ OPENSSL_free(ret);
+ return NULL;
}
-void CTLOG_STORE_free(CTLOG_STORE *store)
+void
+CTLOG_STORE_free(CTLOG_STORE *store)
{
- if (store != NULL) {
- sk_CTLOG_pop_free(store->logs, CTLOG_free);
- OPENSSL_free(store);
- }
+ if (store != NULL) {
+ 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 **ct_log, const CONF *conf, const char *section)
{
- const char *description = NCONF_get_string(conf, section, "description");
- char *pkey_base64;
+ const char *description = NCONF_get_string(conf, section, "description");
+ char *pkey_base64;
- if (description == NULL) {
- CTerr(CT_F_CTLOG_NEW_FROM_CONF, CT_R_LOG_CONF_MISSING_DESCRIPTION);
- return 0;
- }
+ if (description == NULL) {
+ CTerr(CT_F_CTLOG_NEW_FROM_CONF, CT_R_LOG_CONF_MISSING_DESCRIPTION);
+ return 0;
+ }
- pkey_base64 = NCONF_get_string(conf, section, "key");
- if (pkey_base64 == NULL) {
- CTerr(CT_F_CTLOG_NEW_FROM_CONF, CT_R_LOG_CONF_MISSING_KEY);
- return 0;
- }
+ pkey_base64 = NCONF_get_string(conf, section, "key");
+ if (pkey_base64 == NULL) {
+ CTerr(CT_F_CTLOG_NEW_FROM_CONF, CT_R_LOG_CONF_MISSING_KEY);
+ return 0;
+ }
- return CTLOG_new_from_base64(ct_log, pkey_base64, description);
+ return CTLOG_new_from_base64(ct_log, pkey_base64, description);
}
-int CTLOG_STORE_load_default_file(CTLOG_STORE *store)
+int
+CTLOG_STORE_load_default_file(CTLOG_STORE *store)
{
- const char *fpath = ossl_safe_getenv(CTLOG_FILE_EVP);
+ const char *fpath = ossl_safe_getenv(CTLOG_FILE_EVP);
- if (fpath == NULL)
- fpath = CTLOG_FILE;
+ if (fpath == NULL)
+ fpath = CTLOG_FILE;
- return CTLOG_STORE_load_file(store, fpath);
+ return CTLOG_STORE_load_file(store, fpath);
}
/*
* the following log entries.
* It may stop parsing and returns -1 on any internal (malloc) error.
*/
-static int ctlog_store_load_log(const char *log_name, int log_name_len,
- void *arg)
+static int
+ctlog_store_load_log(const char *log_name, int log_name_len, void *arg)
{
- CTLOG_STORE_LOAD_CTX *load_ctx = arg;
- CTLOG *ct_log = NULL;
- /* log_name may not be null-terminated, so fix that before using it */
- char *tmp;
- int ret = 0;
-
- /* log_name will be NULL for empty list entries */
- if (log_name == NULL)
- return 1;
-
- tmp = OPENSSL_strndup(log_name, log_name_len);
- if (tmp == NULL)
- goto mem_err;
-
- ret = ctlog_new_from_conf(&ct_log, load_ctx->conf, tmp);
- OPENSSL_free(tmp);
-
- if (ret < 0) {
- /* Propagate any internal error */
- return ret;
- }
- if (ret == 0) {
- /* If we can't load this log, record that fact and skip it */
- ++load_ctx->invalid_log_entries;
- return 1;
- }
-
- if (!sk_CTLOG_push(load_ctx->log_store->logs, ct_log)) {
- goto mem_err;
- }
- return 1;
+ CTLOG_STORE_LOAD_CTX *load_ctx = arg;
+ CTLOG *ct_log = NULL;
+ /* log_name may not be null-terminated, so fix that before using it */
+ char *tmp;
+ int ret = 0;
+
+ /* log_name will be NULL for empty list entries */
+ if (log_name == NULL)
+ return 1;
+
+ tmp = OPENSSL_strndup(log_name, log_name_len);
+ if (tmp == NULL)
+ goto mem_err;
+
+ ret = ctlog_new_from_conf(&ct_log, load_ctx->conf, tmp);
+ OPENSSL_free(tmp);
+
+ if (ret < 0) {
+ /* Propagate any internal error */
+ return ret;
+ }
+ if (ret == 0) {
+ /* If we can't load this log, record that fact and skip it */
+ ++load_ctx->invalid_log_entries;
+ return 1;
+ }
+
+ if (!sk_CTLOG_push(load_ctx->log_store->logs, ct_log)) {
+ goto mem_err;
+ }
+ return 1;
mem_err:
- CTLOG_free(ct_log);
- CTerr(CT_F_CTLOG_STORE_LOAD_LOG, ERR_R_MALLOC_FAILURE);
- return -1;
+ CTLOG_free(ct_log);
+ CTerr(CT_F_CTLOG_STORE_LOAD_LOG, ERR_R_MALLOC_FAILURE);
+ return -1;
}
-int CTLOG_STORE_load_file(CTLOG_STORE *store, const char *file)
+int
+CTLOG_STORE_load_file(CTLOG_STORE *store, const char *file)
{
- int ret = 0;
- char *enabled_logs;
- CTLOG_STORE_LOAD_CTX* load_ctx = ctlog_store_load_ctx_new();
-
- if (load_ctx == NULL)
- return 0;
- load_ctx->log_store = store;
- load_ctx->conf = NCONF_new(NULL);
- if (load_ctx->conf == NULL)
- goto end;
-
- if (NCONF_load(load_ctx->conf, file, NULL) <= 0) {
- CTerr(CT_F_CTLOG_STORE_LOAD_FILE, CT_R_LOG_CONF_INVALID);
- goto end;
- }
-
- enabled_logs = NCONF_get_string(load_ctx->conf, NULL, "enabled_logs");
- if (enabled_logs == NULL) {
- CTerr(CT_F_CTLOG_STORE_LOAD_FILE, CT_R_LOG_CONF_INVALID);
- goto end;
- }
-
- if (!CONF_parse_list(enabled_logs, ',', 1, ctlog_store_load_log, load_ctx) ||
- load_ctx->invalid_log_entries > 0) {
- CTerr(CT_F_CTLOG_STORE_LOAD_FILE, CT_R_LOG_CONF_INVALID);
- goto end;
- }
-
- ret = 1;
+ int ret = 0;
+ char *enabled_logs;
+ CTLOG_STORE_LOAD_CTX* load_ctx = ctlog_store_load_ctx_new();
+
+ if (load_ctx == NULL)
+ return 0;
+ load_ctx->log_store = store;
+ load_ctx->conf = NCONF_new(NULL);
+ if (load_ctx->conf == NULL)
+ goto end;
+
+ if (NCONF_load(load_ctx->conf, file, NULL) <= 0) {
+ CTerr(CT_F_CTLOG_STORE_LOAD_FILE, CT_R_LOG_CONF_INVALID);
+ goto end;
+ }
+
+ enabled_logs = NCONF_get_string(load_ctx->conf, NULL, "enabled_logs");
+ if (enabled_logs == NULL) {
+ CTerr(CT_F_CTLOG_STORE_LOAD_FILE, CT_R_LOG_CONF_INVALID);
+ goto end;
+ }
+
+ if (!CONF_parse_list(enabled_logs, ',', 1, ctlog_store_load_log, load_ctx) ||
+ load_ctx->invalid_log_entries > 0) {
+ CTerr(CT_F_CTLOG_STORE_LOAD_FILE, CT_R_LOG_CONF_INVALID);
+ goto end;
+ }
+
+ ret = 1;
end:
- NCONF_free(load_ctx->conf);
- ctlog_store_load_ctx_free(load_ctx);
- return ret;
+ NCONF_free(load_ctx->conf);
+ ctlog_store_load_ctx_free(load_ctx);
+ return ret;
}
/*
* Takes ownership of the public key.
* Copies the name.
*/
-CTLOG *CTLOG_new(EVP_PKEY *public_key, const char *name)
+CTLOG *
+CTLOG_new(EVP_PKEY *public_key, const char *name)
{
- CTLOG *ret = OPENSSL_zalloc(sizeof(*ret));
-
- if (ret == NULL) {
- CTerr(CT_F_CTLOG_NEW, ERR_R_MALLOC_FAILURE);
- return NULL;
- }
-
- ret->name = OPENSSL_strdup(name);
- if (ret->name == NULL) {
- CTerr(CT_F_CTLOG_NEW, ERR_R_MALLOC_FAILURE);
- goto err;
- }
-
- if (ct_v1_log_id_from_pkey(public_key, ret->log_id) != 1)
- goto err;
-
- ret->public_key = public_key;
- return ret;
-err:
- CTLOG_free(ret);
- return NULL;
+ CTLOG *ret = OPENSSL_zalloc(sizeof(*ret));
+
+ if (ret == NULL) {
+ CTerr(CT_F_CTLOG_NEW, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ ret->name = OPENSSL_strdup(name);
+ if (ret->name == NULL) {
+ CTerr(CT_F_CTLOG_NEW, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if (ct_v1_log_id_from_pkey(public_key, ret->log_id) != 1)
+ goto err;
+
+ ret->public_key = public_key;
+ return ret;
+ err:
+ CTLOG_free(ret);
+ return NULL;
}
/* Frees CT log and associated structures */
-void CTLOG_free(CTLOG *log)
+void
+CTLOG_free(CTLOG *log)
{
- if (log != NULL) {
- OPENSSL_free(log->name);
- EVP_PKEY_free(log->public_key);
- OPENSSL_free(log);
- }
+ if (log != NULL) {
+ OPENSSL_free(log->name);
+ EVP_PKEY_free(log->public_key);
+ OPENSSL_free(log);
+ }
}
-const char *CTLOG_get0_name(const CTLOG *log)
+const char *
+CTLOG_get0_name(const CTLOG *log)
{
- return log->name;
+ return log->name;
}
-void CTLOG_get0_log_id(const CTLOG *log, const uint8_t **log_id,
- size_t *log_id_len)
+void
+CTLOG_get0_log_id(const CTLOG *log, const uint8_t **log_id, size_t *log_id_len)
{
- *log_id = log->log_id;
- *log_id_len = CT_V1_HASHLEN;
+ *log_id = log->log_id;
+ *log_id_len = CT_V1_HASHLEN;
}
-EVP_PKEY *CTLOG_get0_public_key(const CTLOG *log)
+EVP_PKEY *
+CTLOG_get0_public_key(const CTLOG *log)
{
- return log->public_key;
+ return log->public_key;
}
/*
* Given a log ID, finds the matching log.
* Returns NULL if no match found.
*/
-const CTLOG *CTLOG_STORE_get0_log_by_id(const CTLOG_STORE *store,
- const uint8_t *log_id,
- size_t log_id_len)
+const CTLOG
+*CTLOG_STORE_get0_log_by_id(const CTLOG_STORE *store, const uint8_t *log_id,
+ size_t log_id_len)
{
- int i;
+ int i;
- for (i = 0; i < sk_CTLOG_num(store->logs); ++i) {
- const CTLOG *log = sk_CTLOG_value(store->logs, i);
- if (memcmp(log->log_id, log_id, log_id_len) == 0)
- return log;
- }
+ for (i = 0; i < sk_CTLOG_num(store->logs); ++i) {
+ const CTLOG *log = sk_CTLOG_value(store->logs, i);
+ if (memcmp(log->log_id, log_id, log_id_len) == 0)
+ return log;
+ }
- return NULL;
+ return NULL;
}
#include "ct_local.h"
-int o2i_SCT_signature(SCT *sct, const unsigned char **in, size_t len)
+int
+o2i_SCT_signature(SCT *sct, const unsigned char **in, size_t len)
{
- size_t siglen;
- size_t len_remaining = len;
- const unsigned char *p;
-
- if (sct->version != SCT_VERSION_V1) {
- CTerr(CT_F_O2I_SCT_SIGNATURE, CT_R_UNSUPPORTED_VERSION);
- return -1;
- }
- /*
- * digitally-signed struct header: (1 byte) Hash algorithm (1 byte)
- * Signature algorithm (2 bytes + ?) Signature
- *
- * This explicitly rejects empty signatures: they're invalid for
- * all supported algorithms.
- */
- if (len <= 4) {
- CTerr(CT_F_O2I_SCT_SIGNATURE, CT_R_SCT_INVALID_SIGNATURE);
- return -1;
- }
-
- p = *in;
- /* Get hash and signature algorithm */
- sct->hash_alg = *p++;
- sct->sig_alg = *p++;
- if (SCT_get_signature_nid(sct) == NID_undef) {
- CTerr(CT_F_O2I_SCT_SIGNATURE, CT_R_SCT_INVALID_SIGNATURE);
- return -1;
- }
- /* Retrieve signature and check it is consistent with the buffer length */
- n2s(p, siglen);
- len_remaining -= (p - *in);
- if (siglen > len_remaining) {
- CTerr(CT_F_O2I_SCT_SIGNATURE, CT_R_SCT_INVALID_SIGNATURE);
- return -1;
- }
-
- if (SCT_set1_signature(sct, p, siglen) != 1)
- return -1;
- len_remaining -= siglen;
- *in = p + siglen;
-
- return len - len_remaining;
+ size_t siglen;
+ size_t len_remaining = len;
+ const unsigned char *p;
+
+ if (sct->version != SCT_VERSION_V1) {
+ CTerr(CT_F_O2I_SCT_SIGNATURE, CT_R_UNSUPPORTED_VERSION);
+ return -1;
+ }
+ /*
+ * digitally-signed struct header: (1 byte) Hash algorithm (1 byte)
+ * Signature algorithm (2 bytes + ?) Signature
+ *
+ * This explicitly rejects empty signatures: they're invalid for
+ * all supported algorithms.
+ */
+ if (len <= 4) {
+ CTerr(CT_F_O2I_SCT_SIGNATURE, CT_R_SCT_INVALID_SIGNATURE);
+ return -1;
+ }
+
+ p = *in;
+ /* Get hash and signature algorithm */
+ sct->hash_alg = *p++;
+ sct->sig_alg = *p++;
+ if (SCT_get_signature_nid(sct) == NID_undef) {
+ CTerr(CT_F_O2I_SCT_SIGNATURE, CT_R_SCT_INVALID_SIGNATURE);
+ return -1;
+ }
+ /* Retrieve signature and check it is consistent with the buffer length */
+ n2s(p, siglen);
+ len_remaining -= (p - *in);
+ if (siglen > len_remaining) {
+ CTerr(CT_F_O2I_SCT_SIGNATURE, CT_R_SCT_INVALID_SIGNATURE);
+ return -1;
+ }
+
+ if (SCT_set1_signature(sct, p, siglen) != 1)
+ return -1;
+ len_remaining -= siglen;
+ *in = p + siglen;
+
+ return len - len_remaining;
}
SCT *o2i_SCT(SCT **psct, const unsigned char **in, size_t len)
{
- SCT *sct = NULL;
- const unsigned char *p;
-
- if (len == 0 || len > MAX_SCT_SIZE) {
- CTerr(CT_F_O2I_SCT, CT_R_SCT_INVALID);
- goto err;
- }
-
- if ((sct = SCT_new()) == NULL)
- goto err;
-
- p = *in;
-
- sct->version = *p;
- if (sct->version == SCT_VERSION_V1) {
- int sig_len;
- size_t len2;
- /*-
- * Fixed-length header:
- * struct {
- * Version sct_version; (1 byte)
- * log_id id; (32 bytes)
- * uint64 timestamp; (8 bytes)
- * CtExtensions extensions; (2 bytes + ?)
- * }
- */
- if (len < 43) {
- CTerr(CT_F_O2I_SCT, CT_R_SCT_INVALID);
- goto err;
- }
- len -= 43;
- p++;
- sct->log_id = BUF_memdup(p, CT_V1_HASHLEN);
- if (sct->log_id == NULL)
- goto err;
- sct->log_id_len = CT_V1_HASHLEN;
- p += CT_V1_HASHLEN;
-
- n2l8(p, sct->timestamp);
-
- n2s(p, len2);
- if (len < len2) {
- CTerr(CT_F_O2I_SCT, CT_R_SCT_INVALID);
- goto err;
- }
- if (len2 > 0) {
- sct->ext = BUF_memdup(p, len2);
- if (sct->ext == NULL)
- goto err;
- }
- sct->ext_len = len2;
- p += len2;
- len -= len2;
-
- sig_len = o2i_SCT_signature(sct, &p, len);
- if (sig_len <= 0) {
- CTerr(CT_F_O2I_SCT, CT_R_SCT_INVALID);
- goto err;
- }
- len -= sig_len;
- *in = p + len;
- } else {
- /* If not V1 just cache encoding */
- sct->sct = BUF_memdup(p, len);
- if (sct->sct == NULL)
- goto err;
- sct->sct_len = len;
- *in = p + len;
- }
-
- if (psct != NULL) {
- SCT_free(*psct);
- *psct = sct;
- }
-
- return sct;
-err:
- SCT_free(sct);
- return NULL;
+ SCT *sct = NULL;
+ const unsigned char *p;
+
+ if (len == 0 || len > MAX_SCT_SIZE) {
+ CTerr(CT_F_O2I_SCT, CT_R_SCT_INVALID);
+ goto err;
+ }
+
+ if ((sct = SCT_new()) == NULL)
+ goto err;
+
+ p = *in;
+
+ sct->version = *p;
+ if (sct->version == SCT_VERSION_V1) {
+ int sig_len;
+ size_t len2;
+ /*-
+ * Fixed-length header:
+ * struct {
+ * Version sct_version; (1 byte)
+ * log_id id; (32 bytes)
+ * uint64 timestamp; (8 bytes)
+ * CtExtensions extensions; (2 bytes + ?)
+ * }
+ */
+ if (len < 43) {
+ CTerr(CT_F_O2I_SCT, CT_R_SCT_INVALID);
+ goto err;
+ }
+ len -= 43;
+ p++;
+ sct->log_id = BUF_memdup(p, CT_V1_HASHLEN);
+ if (sct->log_id == NULL)
+ goto err;
+ sct->log_id_len = CT_V1_HASHLEN;
+ p += CT_V1_HASHLEN;
+
+ n2l8(p, sct->timestamp);
+
+ n2s(p, len2);
+ if (len < len2) {
+ CTerr(CT_F_O2I_SCT, CT_R_SCT_INVALID);
+ goto err;
+ }
+ if (len2 > 0) {
+ sct->ext = BUF_memdup(p, len2);
+ if (sct->ext == NULL)
+ goto err;
+ }
+ sct->ext_len = len2;
+ p += len2;
+ len -= len2;
+
+ sig_len = o2i_SCT_signature(sct, &p, len);
+ if (sig_len <= 0) {
+ CTerr(CT_F_O2I_SCT, CT_R_SCT_INVALID);
+ goto err;
+ }
+ len -= sig_len;
+ *in = p + len;
+ } else {
+ /* If not V1 just cache encoding */
+ sct->sct = BUF_memdup(p, len);
+ if (sct->sct == NULL)
+ goto err;
+ sct->sct_len = len;
+ *in = p + len;
+ }
+
+ if (psct != NULL) {
+ SCT_free(*psct);
+ *psct = sct;
+ }
+
+ return sct;
+ err:
+ SCT_free(sct);
+ return NULL;
}
-int i2o_SCT_signature(const SCT *sct, unsigned char **out)
+int
+i2o_SCT_signature(const SCT *sct, unsigned char **out)
{
- size_t len;
- unsigned char *p = NULL, *pstart = NULL;
-
- if (!SCT_signature_is_complete(sct)) {
- CTerr(CT_F_I2O_SCT_SIGNATURE, CT_R_SCT_INVALID_SIGNATURE);
- goto err;
- }
-
- if (sct->version != SCT_VERSION_V1) {
- CTerr(CT_F_I2O_SCT_SIGNATURE, CT_R_UNSUPPORTED_VERSION);
- goto err;
- }
-
- /*
- * (1 byte) Hash algorithm
- * (1 byte) Signature algorithm
- * (2 bytes + ?) Signature
- */
- len = 4 + sct->sig_len;
-
- if (out != NULL) {
- if (*out != NULL) {
- p = *out;
- *out += len;
- } else {
- pstart = p = OPENSSL_malloc(len);
- if (p == NULL) {
- CTerr(CT_F_I2O_SCT_SIGNATURE, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- *out = p;
- }
-
- *p++ = sct->hash_alg;
- *p++ = sct->sig_alg;
- s2n(sct->sig_len, p);
- memcpy(p, sct->sig, sct->sig_len);
- }
-
- return len;
-err:
- OPENSSL_free(pstart);
- return -1;
+ size_t len;
+ unsigned char *p = NULL, *pstart = NULL;
+
+ if (!SCT_signature_is_complete(sct)) {
+ CTerr(CT_F_I2O_SCT_SIGNATURE, CT_R_SCT_INVALID_SIGNATURE);
+ goto err;
+ }
+
+ if (sct->version != SCT_VERSION_V1) {
+ CTerr(CT_F_I2O_SCT_SIGNATURE, CT_R_UNSUPPORTED_VERSION);
+ goto err;
+ }
+
+ /*
+ * (1 byte) Hash algorithm
+ * (1 byte) Signature algorithm
+ * (2 bytes + ?) Signature
+ */
+ len = 4 + sct->sig_len;
+
+ if (out != NULL) {
+ if (*out != NULL) {
+ p = *out;
+ *out += len;
+ } else {
+ pstart = p = OPENSSL_malloc(len);
+ if (p == NULL) {
+ CTerr(CT_F_I2O_SCT_SIGNATURE, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ *out = p;
+ }
+
+ *p++ = sct->hash_alg;
+ *p++ = sct->sig_alg;
+ s2n(sct->sig_len, p);
+ memcpy(p, sct->sig, sct->sig_len);
+ }
+
+ return len;
+ err:
+ OPENSSL_free(pstart);
+ return -1;
}
-int i2o_SCT(const SCT *sct, unsigned char **out)
+int
+i2o_SCT(const SCT *sct, unsigned char **out)
{
- size_t len;
- unsigned char *p = NULL, *pstart = NULL;
-
- if (!SCT_is_complete(sct)) {
- CTerr(CT_F_I2O_SCT, CT_R_SCT_NOT_SET);
- goto err;
- }
- /*
- * Fixed-length header: struct { (1 byte) Version sct_version; (32 bytes)
- * log_id id; (8 bytes) uint64 timestamp; (2 bytes + ?) CtExtensions
- * extensions; (1 byte) Hash algorithm (1 byte) Signature algorithm (2
- * bytes + ?) Signature
- */
- if (sct->version == SCT_VERSION_V1)
- len = 43 + sct->ext_len + 4 + sct->sig_len;
- else
- len = sct->sct_len;
-
- if (out == NULL)
- return len;
-
- if (*out != NULL) {
- p = *out;
- *out += len;
- } else {
- pstart = p = OPENSSL_malloc(len);
- if (p == NULL) {
- CTerr(CT_F_I2O_SCT, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- *out = p;
- }
-
- if (sct->version == SCT_VERSION_V1) {
- *p++ = sct->version;
- memcpy(p, sct->log_id, CT_V1_HASHLEN);
- p += CT_V1_HASHLEN;
- l2n8(sct->timestamp, p);
- s2n(sct->ext_len, p);
- if (sct->ext_len > 0) {
- memcpy(p, sct->ext, sct->ext_len);
- p += sct->ext_len;
- }
- if (i2o_SCT_signature(sct, &p) <= 0)
- goto err;
- } else {
- memcpy(p, sct->sct, len);
- }
-
- return len;
-err:
- OPENSSL_free(pstart);
- return -1;
+ size_t len;
+ unsigned char *p = NULL, *pstart = NULL;
+
+ if (!SCT_is_complete(sct)) {
+ CTerr(CT_F_I2O_SCT, CT_R_SCT_NOT_SET);
+ goto err;
+ }
+ /*
+ * Fixed-length header: struct { (1 byte) Version sct_version; (32 bytes)
+ * log_id id; (8 bytes) uint64 timestamp; (2 bytes + ?) CtExtensions
+ * extensions; (1 byte) Hash algorithm (1 byte) Signature algorithm (2
+ * bytes + ?) Signature
+ */
+ if (sct->version == SCT_VERSION_V1)
+ len = 43 + sct->ext_len + 4 + sct->sig_len;
+ else
+ len = sct->sct_len;
+
+ if (out == NULL)
+ return len;
+
+ if (*out != NULL) {
+ p = *out;
+ *out += len;
+ } else {
+ pstart = p = OPENSSL_malloc(len);
+ if (p == NULL) {
+ CTerr(CT_F_I2O_SCT, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ *out = p;
+ }
+
+ if (sct->version == SCT_VERSION_V1) {
+ *p++ = sct->version;
+ memcpy(p, sct->log_id, CT_V1_HASHLEN);
+ p += CT_V1_HASHLEN;
+ l2n8(sct->timestamp, p);
+ s2n(sct->ext_len, p);
+ if (sct->ext_len > 0) {
+ memcpy(p, sct->ext, sct->ext_len);
+ p += sct->ext_len;
+ }
+ if (i2o_SCT_signature(sct, &p) <= 0)
+ goto err;
+ } else {
+ memcpy(p, sct->sct, len);
+ }
+
+ return len;
+ err:
+ OPENSSL_free(pstart);
+ return -1;
}
-STACK_OF(SCT) *o2i_SCT_LIST(STACK_OF(SCT) **a, const unsigned char **pp,
- size_t len)
+STACK_OF(SCT) *
+o2i_SCT_LIST(STACK_OF(SCT) **a, const unsigned char **pp, size_t len)
{
- STACK_OF(SCT) *sk = NULL;
- size_t list_len, sct_len;
-
- if (len < 2 || len > MAX_SCT_LIST_SIZE) {
- CTerr(CT_F_O2I_SCT_LIST, CT_R_SCT_LIST_INVALID);
- return NULL;
- }
-
- n2s(*pp, list_len);
- if (list_len != len - 2) {
- CTerr(CT_F_O2I_SCT_LIST, CT_R_SCT_LIST_INVALID);
- return NULL;
- }
-
- if (a == NULL || *a == NULL) {
- sk = sk_SCT_new_null();
- if (sk == NULL)
- return NULL;
- } else {
- SCT *sct;
-
- /* Use the given stack, but empty it first. */
- sk = *a;
- while ((sct = sk_SCT_pop(sk)) != NULL)
- SCT_free(sct);
- }
-
- while (list_len > 0) {
- SCT *sct;
-
- if (list_len < 2) {
- CTerr(CT_F_O2I_SCT_LIST, CT_R_SCT_LIST_INVALID);
- goto err;
- }
- n2s(*pp, sct_len);
- list_len -= 2;
-
- if (sct_len == 0 || sct_len > list_len) {
- CTerr(CT_F_O2I_SCT_LIST, CT_R_SCT_LIST_INVALID);
- goto err;
- }
- list_len -= sct_len;
-
- if ((sct = o2i_SCT(NULL, pp, sct_len)) == NULL)
- goto err;
- if (!sk_SCT_push(sk, sct)) {
- SCT_free(sct);
- goto err;
- }
- }
-
- if (a != NULL && *a == NULL)
- *a = sk;
- return sk;
+ STACK_OF(SCT) *sk = NULL;
+ size_t list_len, sct_len;
+
+ if (len < 2 || len > MAX_SCT_LIST_SIZE) {
+ CTerr(CT_F_O2I_SCT_LIST, CT_R_SCT_LIST_INVALID);
+ return NULL;
+ }
+
+ n2s(*pp, list_len);
+ if (list_len != len - 2) {
+ CTerr(CT_F_O2I_SCT_LIST, CT_R_SCT_LIST_INVALID);
+ return NULL;
+ }
+
+ if (a == NULL || *a == NULL) {
+ sk = sk_SCT_new_null();
+ if (sk == NULL)
+ return NULL;
+ } else {
+ SCT *sct;
+
+ /* Use the given stack, but empty it first. */
+ sk = *a;
+ while ((sct = sk_SCT_pop(sk)) != NULL)
+ SCT_free(sct);
+ }
+
+ while (list_len > 0) {
+ SCT *sct;
+
+ if (list_len < 2) {
+ CTerr(CT_F_O2I_SCT_LIST, CT_R_SCT_LIST_INVALID);
+ goto err;
+ }
+ n2s(*pp, sct_len);
+ list_len -= 2;
+
+ if (sct_len == 0 || sct_len > list_len) {
+ CTerr(CT_F_O2I_SCT_LIST, CT_R_SCT_LIST_INVALID);
+ goto err;
+ }
+ list_len -= sct_len;
+
+ if ((sct = o2i_SCT(NULL, pp, sct_len)) == NULL)
+ goto err;
+ if (!sk_SCT_push(sk, sct)) {
+ SCT_free(sct);
+ goto err;
+ }
+ }
+
+ if (a != NULL && *a == NULL)
+ *a = sk;
+ return sk;
err:
- if (a == NULL || *a == NULL)
- SCT_LIST_free(sk);
- return NULL;
+ if (a == NULL || *a == NULL)
+ SCT_LIST_free(sk);
+ return NULL;
}
-int i2o_SCT_LIST(const STACK_OF(SCT) *a, unsigned char **pp)
+int
+i2o_SCT_LIST(const STACK_OF(SCT) *a, unsigned char **pp)
{
- int len, sct_len, i, is_pp_new = 0;
- size_t len2;
- unsigned char *p = NULL, *p2;
-
- if (pp != NULL) {
- if (*pp == NULL) {
- if ((len = i2o_SCT_LIST(a, NULL)) == -1) {
- CTerr(CT_F_I2O_SCT_LIST, CT_R_SCT_LIST_INVALID);
- return -1;
- }
- if ((*pp = OPENSSL_malloc(len)) == NULL) {
- CTerr(CT_F_I2O_SCT_LIST, ERR_R_MALLOC_FAILURE);
- return -1;
- }
- is_pp_new = 1;
- }
- p = *pp + 2;
- }
-
- len2 = 2;
- for (i = 0; i < sk_SCT_num(a); i++) {
- if (pp != NULL) {
- p2 = p;
- p += 2;
- if ((sct_len = i2o_SCT(sk_SCT_value(a, i), &p)) == -1)
- goto err;
- s2n(sct_len, p2);
- } else {
- if ((sct_len = i2o_SCT(sk_SCT_value(a, i), NULL)) == -1)
- goto err;
- }
- len2 += 2 + sct_len;
- }
-
- if (len2 > MAX_SCT_LIST_SIZE)
- goto err;
-
- if (pp != NULL) {
- p = *pp;
- s2n(len2 - 2, p);
- if (!is_pp_new)
- *pp += len2;
- }
- return len2;
+ int len, sct_len, i, is_pp_new = 0;
+ size_t len2;
+ unsigned char *p = NULL, *p2;
+
+ if (pp != NULL) {
+ if (*pp == NULL) {
+ if ((len = i2o_SCT_LIST(a, NULL)) == -1) {
+ CTerr(CT_F_I2O_SCT_LIST, CT_R_SCT_LIST_INVALID);
+ return -1;
+ }
+ if ((*pp = OPENSSL_malloc(len)) == NULL) {
+ CTerr(CT_F_I2O_SCT_LIST, ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+ is_pp_new = 1;
+ }
+ p = *pp + 2;
+ }
+
+ len2 = 2;
+ for (i = 0; i < sk_SCT_num(a); i++) {
+ if (pp != NULL) {
+ p2 = p;
+ p += 2;
+ if ((sct_len = i2o_SCT(sk_SCT_value(a, i), &p)) == -1)
+ goto err;
+ s2n(sct_len, p2);
+ } else {
+ if ((sct_len = i2o_SCT(sk_SCT_value(a, i), NULL)) == -1)
+ goto err;
+ }
+ len2 += 2 + sct_len;
+ }
+
+ if (len2 > MAX_SCT_LIST_SIZE)
+ goto err;
+
+ if (pp != NULL) {
+ p = *pp;
+ s2n(len2 - 2, p);
+ if (!is_pp_new)
+ *pp += len2;
+ }
+ return len2;
err:
- if (is_pp_new) {
- OPENSSL_free(*pp);
- *pp = NULL;
- }
- return -1;
+ if (is_pp_new) {
+ OPENSSL_free(*pp);
+ *pp = NULL;
+ }
+ return -1;
}
-STACK_OF(SCT) *d2i_SCT_LIST(STACK_OF(SCT) **a, const unsigned char **pp,
- long len)
+STACK_OF(SCT) *
+d2i_SCT_LIST(STACK_OF(SCT) **a, const unsigned char **pp, long len)
{
- ASN1_OCTET_STRING *oct = NULL;
- STACK_OF(SCT) *sk = NULL;
- const unsigned char *p;
+ ASN1_OCTET_STRING *oct = NULL;
+ STACK_OF(SCT) *sk = NULL;
+ const unsigned char *p;
- p = *pp;
- if (d2i_ASN1_OCTET_STRING(&oct, &p, len) == NULL)
- return NULL;
+ p = *pp;
+ if (d2i_ASN1_OCTET_STRING(&oct, &p, len) == NULL)
+ return NULL;
- p = oct->data;
- if ((sk = o2i_SCT_LIST(a, &p, oct->length)) != NULL)
- *pp += len;
+ p = oct->data;
+ if ((sk = o2i_SCT_LIST(a, &p, oct->length)) != NULL)
+ *pp += len;
- ASN1_OCTET_STRING_free(oct);
- return sk;
+ ASN1_OCTET_STRING_free(oct);
+ return sk;
}
-int i2d_SCT_LIST(const STACK_OF(SCT) *a, unsigned char **out)
+int
+i2d_SCT_LIST(const STACK_OF(SCT) *a, unsigned char **out)
{
- ASN1_OCTET_STRING oct;
- int len;
+ ASN1_OCTET_STRING oct;
+ int len;
- oct.data = NULL;
- if ((oct.length = i2o_SCT_LIST(a, &oct.data)) == -1)
- return -1;
+ oct.data = NULL;
+ if ((oct.length = i2o_SCT_LIST(a, &oct.data)) == -1)
+ return -1;
- len = i2d_ASN1_OCTET_STRING(&oct, out);
- OPENSSL_free(oct.data);
- return len;
+ len = i2d_ASN1_OCTET_STRING(&oct, out);
+ OPENSSL_free(oct.data);
+ return len;
}
*/
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(void)
{
- CT_POLICY_EVAL_CTX *ctx = OPENSSL_zalloc(sizeof(CT_POLICY_EVAL_CTX));
+ 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);
- return NULL;
- }
+ if (ctx == NULL) {
+ CTerr(CT_F_CT_POLICY_EVAL_CTX_NEW, 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) *
+ /* 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;
+ return ctx;
}
-void CT_POLICY_EVAL_CTX_free(CT_POLICY_EVAL_CTX *ctx)
+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);
+ if (ctx == NULL)
+ return;
+ X509_free(ctx->cert);
+ X509_free(ctx->issuer);
+ OPENSSL_free(ctx);
}
-int CT_POLICY_EVAL_CTX_set1_cert(CT_POLICY_EVAL_CTX *ctx, X509 *cert)
+int
+CT_POLICY_EVAL_CTX_set1_cert(CT_POLICY_EVAL_CTX *ctx, X509 *cert)
{
- if (!X509_up_ref(cert))
- return 0;
- ctx->cert = cert;
- return 1;
+ if (!X509_up_ref(cert))
+ return 0;
+ ctx->cert = cert;
+ return 1;
}
-int CT_POLICY_EVAL_CTX_set1_issuer(CT_POLICY_EVAL_CTX *ctx, X509 *issuer)
+int
+CT_POLICY_EVAL_CTX_set1_issuer(CT_POLICY_EVAL_CTX *ctx, X509 *issuer)
{
- if (!X509_up_ref(issuer))
- return 0;
- ctx->issuer = issuer;
- return 1;
+ if (!X509_up_ref(issuer))
+ return 0;
+ ctx->issuer = issuer;
+ return 1;
}
-void CT_POLICY_EVAL_CTX_set_shared_CTLOG_STORE(CT_POLICY_EVAL_CTX *ctx,
- CTLOG_STORE *log_store)
+void
+CT_POLICY_EVAL_CTX_set_shared_CTLOG_STORE(CT_POLICY_EVAL_CTX *ctx,
+ CTLOG_STORE *log_store)
{
- ctx->log_store = log_store;
+ ctx->log_store = log_store;
}
-void CT_POLICY_EVAL_CTX_set_time(CT_POLICY_EVAL_CTX *ctx, uint64_t time_in_ms)
+void
+CT_POLICY_EVAL_CTX_set_time(CT_POLICY_EVAL_CTX *ctx, uint64_t time_in_ms)
{
- ctx->epoch_time_in_ms = time_in_ms;
+ ctx->epoch_time_in_ms = time_in_ms;
}
-X509* CT_POLICY_EVAL_CTX_get0_cert(const CT_POLICY_EVAL_CTX *ctx)
+X509*
+CT_POLICY_EVAL_CTX_get0_cert(const CT_POLICY_EVAL_CTX *ctx)
{
- return ctx->cert;
+ return ctx->cert;
}
-X509* CT_POLICY_EVAL_CTX_get0_issuer(const CT_POLICY_EVAL_CTX *ctx)
+X509*
+CT_POLICY_EVAL_CTX_get0_issuer(const CT_POLICY_EVAL_CTX *ctx)
{
- return ctx->issuer;
+ return ctx->issuer;
}
-const CTLOG_STORE *CT_POLICY_EVAL_CTX_get0_log_store(const CT_POLICY_EVAL_CTX *ctx)
+const CTLOG_STORE *
+CT_POLICY_EVAL_CTX_get0_log_store(const CT_POLICY_EVAL_CTX *ctx)
{
return ctx->log_store;
}
-uint64_t CT_POLICY_EVAL_CTX_get_time(const CT_POLICY_EVAL_CTX *ctx)
+uint64_t
+CT_POLICY_EVAL_CTX_get_time(const CT_POLICY_EVAL_CTX *ctx)
{
- return ctx->epoch_time_in_ms;
+ return ctx->epoch_time_in_ms;
}
#include "ct_local.h"
-static void SCT_signature_algorithms_print(const SCT *sct, BIO *out)
+static void
+SCT_signature_algorithms_print(const SCT *sct, BIO *out)
{
- int nid = SCT_get_signature_nid(sct);
+ int nid = SCT_get_signature_nid(sct);
- if (nid == NID_undef)
- BIO_printf(out, "%02X%02X", sct->hash_alg, sct->sig_alg);
- else
- BIO_printf(out, "%s", OBJ_nid2ln(nid));
+ if (nid == NID_undef)
+ BIO_printf(out, "%02X%02X", sct->hash_alg, sct->sig_alg);
+ else
+ BIO_printf(out, "%s", OBJ_nid2ln(nid));
}
-static void timestamp_print(uint64_t timestamp, BIO *out)
+static void
+timestamp_print(uint64_t timestamp, BIO *out)
{
- ASN1_GENERALIZEDTIME *gen = ASN1_GENERALIZEDTIME_new();
- char genstr[20];
-
- if (gen == NULL)
- return;
- ASN1_GENERALIZEDTIME_adj(gen, (time_t)0,
- (int)(timestamp / 86400000),
- (timestamp % 86400000) / 1000);
- /*
- * Note GeneralizedTime from ASN1_GENERALIZETIME_adj is always 15
- * characters long with a final Z. Update it with fractional seconds.
- */
- BIO_snprintf(genstr, sizeof(genstr), "%.14s.%03dZ",
- ASN1_STRING_get0_data(gen), (unsigned int)(timestamp % 1000));
- if (ASN1_GENERALIZEDTIME_set_string(gen, genstr))
- ASN1_GENERALIZEDTIME_print(out, gen);
- ASN1_GENERALIZEDTIME_free(gen);
+ ASN1_GENERALIZEDTIME *gen = ASN1_GENERALIZEDTIME_new();
+ char genstr[20];
+
+ if (gen == NULL)
+ return;
+ ASN1_GENERALIZEDTIME_adj(gen, (time_t)0,(int)(timestamp / 86400000),
+ (timestamp % 86400000) / 1000);
+ /*
+ * Note GeneralizedTime from ASN1_GENERALIZETIME_adj is always 15
+ * characters long with a final Z. Update it with fractional seconds.
+ */
+ BIO_snprintf(genstr, sizeof(genstr), "%.14s.%03dZ",
+ ASN1_STRING_get0_data(gen), (unsigned int)(timestamp % 1000));
+ if (ASN1_GENERALIZEDTIME_set_string(gen, genstr))
+ ASN1_GENERALIZEDTIME_print(out, gen);
+ ASN1_GENERALIZEDTIME_free(gen);
}
-const char *SCT_validation_status_string(const SCT *sct)
+const char *
+SCT_validation_status_string(const SCT *sct)
{
-
- switch (SCT_get_validation_status(sct)) {
- case SCT_VALIDATION_STATUS_NOT_SET:
- return "not set";
- case SCT_VALIDATION_STATUS_UNKNOWN_VERSION:
- return "unknown version";
- case SCT_VALIDATION_STATUS_UNKNOWN_LOG:
- return "unknown log";
- case SCT_VALIDATION_STATUS_UNVERIFIED:
- return "unverified";
- case SCT_VALIDATION_STATUS_INVALID:
- return "invalid";
- case SCT_VALIDATION_STATUS_VALID:
- return "valid";
- }
- return "unknown status";
+ switch (SCT_get_validation_status(sct)) {
+ case SCT_VALIDATION_STATUS_NOT_SET:
+ return "not set";
+ case SCT_VALIDATION_STATUS_UNKNOWN_VERSION:
+ return "unknown version";
+ case SCT_VALIDATION_STATUS_UNKNOWN_LOG:
+ return "unknown log";
+ case SCT_VALIDATION_STATUS_UNVERIFIED:
+ return "unverified";
+ case SCT_VALIDATION_STATUS_INVALID:
+ return "invalid";
+ case SCT_VALIDATION_STATUS_VALID:
+ return "valid";
+ }
+ return "unknown status";
}
-void SCT_print(const SCT *sct, BIO *out, int indent,
- const CTLOG_STORE *log_store)
+void
+SCT_print(const SCT *sct, BIO *out, int indent, const CTLOG_STORE *log_store)
{
- const CTLOG *log = NULL;
+ const CTLOG *log = NULL;
- if (log_store != NULL) {
- log = CTLOG_STORE_get0_log_by_id(log_store, sct->log_id,
- sct->log_id_len);
- }
+ if (log_store != NULL) {
+ log = CTLOG_STORE_get0_log_by_id(log_store, sct->log_id,
+ sct->log_id_len);
+ }
- BIO_printf(out, "%*sSigned Certificate Timestamp:", indent, "");
- BIO_printf(out, "\n%*sVersion : ", indent + 4, "");
+ BIO_printf(out, "%*sSigned Certificate Timestamp:", indent, "");
+ BIO_printf(out, "\n%*sVersion : ", indent + 4, "");
- if (sct->version != SCT_VERSION_V1) {
- BIO_printf(out, "unknown\n%*s", indent + 16, "");
- BIO_hex_string(out, indent + 16, 16, sct->sct, sct->sct_len);
- return;
- }
+ if (sct->version != SCT_VERSION_V1) {
+ BIO_printf(out, "unknown\n%*s", indent + 16, "");
+ BIO_hex_string(out, indent + 16, 16, sct->sct, sct->sct_len);
+ return;
+ }
- BIO_printf(out, "v1 (0x0)");
+ BIO_printf(out, "v1 (0x0)");
- if (log != NULL) {
- BIO_printf(out, "\n%*sLog : %s", indent + 4, "",
- CTLOG_get0_name(log));
- }
+ if (log != NULL) {
+ BIO_printf(out, "\n%*sLog : %s", indent + 4, "",
+ CTLOG_get0_name(log));
+ }
- BIO_printf(out, "\n%*sLog ID : ", indent + 4, "");
- BIO_hex_string(out, indent + 16, 16, sct->log_id, sct->log_id_len);
+ BIO_printf(out, "\n%*sLog ID : ", indent + 4, "");
+ BIO_hex_string(out, indent + 16, 16, sct->log_id, sct->log_id_len);
- BIO_printf(out, "\n%*sTimestamp : ", indent + 4, "");
- timestamp_print(sct->timestamp, out);
+ BIO_printf(out, "\n%*sTimestamp : ", indent + 4, "");
+ timestamp_print(sct->timestamp, out);
- BIO_printf(out, "\n%*sExtensions: ", indent + 4, "");
- if (sct->ext_len == 0)
- BIO_printf(out, "none");
- else
- BIO_hex_string(out, indent + 16, 16, sct->ext, sct->ext_len);
+ BIO_printf(out, "\n%*sExtensions: ", indent + 4, "");
+ if (sct->ext_len == 0)
+ BIO_printf(out, "none");
+ else
+ BIO_hex_string(out, indent + 16, 16, sct->ext, sct->ext_len);
- BIO_printf(out, "\n%*sSignature : ", indent + 4, "");
- SCT_signature_algorithms_print(sct, out);
- BIO_printf(out, "\n%*s ", indent + 4, "");
- BIO_hex_string(out, indent + 16, 16, sct->sig, sct->sig_len);
+ BIO_printf(out, "\n%*sSignature : ", indent + 4, "");
+ SCT_signature_algorithms_print(sct, out);
+ BIO_printf(out, "\n%*s ", indent + 4, "");
+ BIO_hex_string(out, indent + 16, 16, sct->sig, sct->sig_len);
}
-void SCT_LIST_print(const STACK_OF(SCT) *sct_list, BIO *out, int indent,
- const char *separator, const CTLOG_STORE *log_store)
+void
+SCT_LIST_print(const STACK_OF(SCT) *sct_list, BIO *out, int indent,
+ const char *separator, const CTLOG_STORE *log_store)
{
- int sct_count = sk_SCT_num(sct_list);
- int i;
+ int sct_count = sk_SCT_num(sct_list);
+ int i;
- for (i = 0; i < sct_count; ++i) {
- SCT *sct = sk_SCT_value(sct_list, i);
+ for (i = 0; i < sct_count; ++i) {
+ SCT *sct = sk_SCT_value(sct_list, i);
- SCT_print(sct, out, indent, log_store);
- if (i < sk_SCT_num(sct_list) - 1)
- BIO_printf(out, "%s", separator);
- }
+ SCT_print(sct, out, indent, log_store);
+ if (i < sk_SCT_num(sct_list) - 1)
+ BIO_printf(out, "%s", separator);
+ }
}
#include "ct_local.h"
-SCT *SCT_new(void)
+SCT *
+SCT_new(void)
{
- SCT *sct = OPENSSL_zalloc(sizeof(*sct));
+ SCT *sct = OPENSSL_zalloc(sizeof(*sct));
- if (sct == NULL) {
- CTerr(CT_F_SCT_NEW, ERR_R_MALLOC_FAILURE);
- return NULL;
- }
+ if (sct == NULL) {
+ CTerr(CT_F_SCT_NEW, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
- sct->entry_type = CT_LOG_ENTRY_TYPE_NOT_SET;
- sct->version = SCT_VERSION_NOT_SET;
- return sct;
+ sct->entry_type = CT_LOG_ENTRY_TYPE_NOT_SET;
+ sct->version = SCT_VERSION_NOT_SET;
+ return sct;
}
-void SCT_free(SCT *sct)
+void
+SCT_free(SCT *sct)
{
- if (sct == NULL)
- return;
-
- OPENSSL_free(sct->log_id);
- OPENSSL_free(sct->ext);
- OPENSSL_free(sct->sig);
- OPENSSL_free(sct->sct);
- OPENSSL_free(sct);
+ if (sct == NULL)
+ return;
+
+ OPENSSL_free(sct->log_id);
+ OPENSSL_free(sct->ext);
+ OPENSSL_free(sct->sig);
+ OPENSSL_free(sct->sct);
+ OPENSSL_free(sct);
}
-void SCT_LIST_free(STACK_OF(SCT) *a)
+void
+SCT_LIST_free(STACK_OF(SCT) *a)
{
- sk_SCT_pop_free(a, SCT_free);
+ sk_SCT_pop_free(a, SCT_free);
}
-int SCT_set_version(SCT *sct, sct_version_t version)
+int
+SCT_set_version(SCT *sct, sct_version_t version)
{
- if (version != SCT_VERSION_V1) {
- CTerr(CT_F_SCT_SET_VERSION, CT_R_UNSUPPORTED_VERSION);
- return 0;
- }
- sct->version = version;
- sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
- return 1;
+ if (version != SCT_VERSION_V1) {
+ CTerr(CT_F_SCT_SET_VERSION, CT_R_UNSUPPORTED_VERSION);
+ return 0;
+ }
+ sct->version = version;
+ sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
+ return 1;
}
-int SCT_set_log_entry_type(SCT *sct, ct_log_entry_type_t entry_type)
+int
+SCT_set_log_entry_type(SCT *sct, ct_log_entry_type_t entry_type)
{
- sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
-
- switch (entry_type) {
- case CT_LOG_ENTRY_TYPE_X509:
- case CT_LOG_ENTRY_TYPE_PRECERT:
- sct->entry_type = entry_type;
- return 1;
- case CT_LOG_ENTRY_TYPE_NOT_SET:
- break;
- }
- CTerr(CT_F_SCT_SET_LOG_ENTRY_TYPE, CT_R_UNSUPPORTED_ENTRY_TYPE);
- return 0;
+ sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
+
+ switch (entry_type) {
+ case CT_LOG_ENTRY_TYPE_X509:
+ case CT_LOG_ENTRY_TYPE_PRECERT:
+ sct->entry_type = entry_type;
+ return 1;
+ case CT_LOG_ENTRY_TYPE_NOT_SET:
+ break;
+ }
+ CTerr(CT_F_SCT_SET_LOG_ENTRY_TYPE, CT_R_UNSUPPORTED_ENTRY_TYPE);
+ return 0;
}
-int SCT_set0_log_id(SCT *sct, unsigned char *log_id, size_t log_id_len)
+int
+SCT_set0_log_id(SCT *sct, unsigned char *log_id, size_t log_id_len)
{
- if (sct->version == SCT_VERSION_V1 && log_id_len != CT_V1_HASHLEN) {
- CTerr(CT_F_SCT_SET0_LOG_ID, CT_R_INVALID_LOG_ID_LENGTH);
- return 0;
- }
-
- OPENSSL_free(sct->log_id);
- sct->log_id = log_id;
- sct->log_id_len = log_id_len;
- sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
- return 1;
+ if (sct->version == SCT_VERSION_V1 && log_id_len != CT_V1_HASHLEN) {
+ CTerr(CT_F_SCT_SET0_LOG_ID, CT_R_INVALID_LOG_ID_LENGTH);
+ return 0;
+ }
+
+ OPENSSL_free(sct->log_id);
+ sct->log_id = log_id;
+ sct->log_id_len = log_id_len;
+ sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
+ return 1;
}
-int SCT_set1_log_id(SCT *sct, const unsigned char *log_id, size_t log_id_len)
+int
+SCT_set1_log_id(SCT *sct, const unsigned char *log_id, size_t log_id_len)
{
- if (sct->version == SCT_VERSION_V1 && log_id_len != CT_V1_HASHLEN) {
- CTerr(CT_F_SCT_SET1_LOG_ID, CT_R_INVALID_LOG_ID_LENGTH);
- return 0;
- }
-
- OPENSSL_free(sct->log_id);
- sct->log_id = NULL;
- sct->log_id_len = 0;
- sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
-
- if (log_id != NULL && log_id_len > 0) {
- sct->log_id = OPENSSL_memdup(log_id, log_id_len);
- if (sct->log_id == NULL) {
- CTerr(CT_F_SCT_SET1_LOG_ID, ERR_R_MALLOC_FAILURE);
- return 0;
- }
- sct->log_id_len = log_id_len;
- }
- return 1;
+ if (sct->version == SCT_VERSION_V1 && log_id_len != CT_V1_HASHLEN) {
+ CTerr(CT_F_SCT_SET1_LOG_ID, CT_R_INVALID_LOG_ID_LENGTH);
+ return 0;
+ }
+
+ OPENSSL_free(sct->log_id);
+ sct->log_id = NULL;
+ sct->log_id_len = 0;
+ sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
+
+ if (log_id != NULL && log_id_len > 0) {
+ sct->log_id = OPENSSL_memdup(log_id, log_id_len);
+ if (sct->log_id == NULL) {
+ CTerr(CT_F_SCT_SET1_LOG_ID, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ sct->log_id_len = log_id_len;
+ }
+ return 1;
}
-void SCT_set_timestamp(SCT *sct, uint64_t timestamp)
+void
+SCT_set_timestamp(SCT *sct, uint64_t timestamp)
{
- sct->timestamp = timestamp;
- sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
+ sct->timestamp = timestamp;
+ sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
}
-int SCT_set_signature_nid(SCT *sct, int nid)
+int
+SCT_set_signature_nid(SCT *sct, int nid)
{
- switch (nid) {
- case NID_sha256WithRSAEncryption:
- sct->hash_alg = TLSEXT_hash_sha256;
- sct->sig_alg = TLSEXT_signature_rsa;
- sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
- return 1;
- case NID_ecdsa_with_SHA256:
- sct->hash_alg = TLSEXT_hash_sha256;
- sct->sig_alg = TLSEXT_signature_ecdsa;
- sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
- return 1;
- default:
- CTerr(CT_F_SCT_SET_SIGNATURE_NID, CT_R_UNRECOGNIZED_SIGNATURE_NID);
- return 0;
- }
+ switch (nid) {
+ case NID_sha256WithRSAEncryption:
+ sct->hash_alg = TLSEXT_hash_sha256;
+ sct->sig_alg = TLSEXT_signature_rsa;
+ sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
+ return 1;
+ case NID_ecdsa_with_SHA256:
+ sct->hash_alg = TLSEXT_hash_sha256;
+ sct->sig_alg = TLSEXT_signature_ecdsa;
+ sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
+ return 1;
+ default:
+ CTerr(CT_F_SCT_SET_SIGNATURE_NID, CT_R_UNRECOGNIZED_SIGNATURE_NID);
+ return 0;
+ }
}
-void SCT_set0_extensions(SCT *sct, unsigned char *ext, size_t ext_len)
+void
+SCT_set0_extensions(SCT *sct, unsigned char *ext, size_t ext_len)
{
- OPENSSL_free(sct->ext);
- sct->ext = ext;
- sct->ext_len = ext_len;
- sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
+ OPENSSL_free(sct->ext);
+ sct->ext = ext;
+ sct->ext_len = ext_len;
+ sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
}
-int SCT_set1_extensions(SCT *sct, const unsigned char *ext, size_t ext_len)
+int
+SCT_set1_extensions(SCT *sct, const unsigned char *ext, size_t ext_len)
{
- OPENSSL_free(sct->ext);
- sct->ext = NULL;
- sct->ext_len = 0;
- sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
-
- if (ext != NULL && ext_len > 0) {
- sct->ext = OPENSSL_memdup(ext, ext_len);
- if (sct->ext == NULL) {
- CTerr(CT_F_SCT_SET1_EXTENSIONS, ERR_R_MALLOC_FAILURE);
- return 0;
- }
- sct->ext_len = ext_len;
- }
- return 1;
+ OPENSSL_free(sct->ext);
+ sct->ext = NULL;
+ sct->ext_len = 0;
+ sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
+
+ if (ext != NULL && ext_len > 0) {
+ sct->ext = OPENSSL_memdup(ext, ext_len);
+ if (sct->ext == NULL) {
+ CTerr(CT_F_SCT_SET1_EXTENSIONS, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ sct->ext_len = ext_len;
+ }
+ return 1;
}
-void SCT_set0_signature(SCT *sct, unsigned char *sig, size_t sig_len)
+void
+SCT_set0_signature(SCT *sct, unsigned char *sig, size_t sig_len)
{
- OPENSSL_free(sct->sig);
- sct->sig = sig;
- sct->sig_len = sig_len;
- sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
+ OPENSSL_free(sct->sig);
+ sct->sig = sig;
+ sct->sig_len = sig_len;
+ sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
}
-int SCT_set1_signature(SCT *sct, const unsigned char *sig, size_t sig_len)
+int
+SCT_set1_signature(SCT *sct, const unsigned char *sig, size_t sig_len)
{
- OPENSSL_free(sct->sig);
- sct->sig = NULL;
- sct->sig_len = 0;
- sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
-
- if (sig != NULL && sig_len > 0) {
- sct->sig = OPENSSL_memdup(sig, sig_len);
- if (sct->sig == NULL) {
- CTerr(CT_F_SCT_SET1_SIGNATURE, ERR_R_MALLOC_FAILURE);
- return 0;
- }
- sct->sig_len = sig_len;
- }
- return 1;
+ OPENSSL_free(sct->sig);
+ sct->sig = NULL;
+ sct->sig_len = 0;
+ sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
+
+ if (sig != NULL && sig_len > 0) {
+ sct->sig = OPENSSL_memdup(sig, sig_len);
+ if (sct->sig == NULL) {
+ CTerr(CT_F_SCT_SET1_SIGNATURE, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ sct->sig_len = sig_len;
+ }
+ return 1;
}
-sct_version_t SCT_get_version(const SCT *sct)
+sct_version_t
+SCT_get_version(const SCT *sct)
{
- return sct->version;
+ return sct->version;
}
-ct_log_entry_type_t SCT_get_log_entry_type(const SCT *sct)
+ct_log_entry_type_t
+SCT_get_log_entry_type(const SCT *sct)
{
- return sct->entry_type;
+ return sct->entry_type;
}
-size_t SCT_get0_log_id(const SCT *sct, unsigned char **log_id)
+size_t
+SCT_get0_log_id(const SCT *sct, unsigned char **log_id)
{
- *log_id = sct->log_id;
- return sct->log_id_len;
+ *log_id = sct->log_id;
+ return sct->log_id_len;
}
-uint64_t SCT_get_timestamp(const SCT *sct)
+uint64_t
+SCT_get_timestamp(const SCT *sct)
{
- return sct->timestamp;
+ return sct->timestamp;
}
-int SCT_get_signature_nid(const SCT *sct)
+int
+SCT_get_signature_nid(const SCT *sct)
{
- if (sct->version == SCT_VERSION_V1) {
- if (sct->hash_alg == TLSEXT_hash_sha256) {
- switch (sct->sig_alg) {
- case TLSEXT_signature_ecdsa:
- return NID_ecdsa_with_SHA256;
- case TLSEXT_signature_rsa:
- return NID_sha256WithRSAEncryption;
- default:
- return NID_undef;
- }
- }
- }
- return NID_undef;
+ if (sct->version == SCT_VERSION_V1) {
+ if (sct->hash_alg == TLSEXT_hash_sha256) {
+ switch (sct->sig_alg) {
+ case TLSEXT_signature_ecdsa:
+ return NID_ecdsa_with_SHA256;
+ case TLSEXT_signature_rsa:
+ return NID_sha256WithRSAEncryption;
+ default:
+ return NID_undef;
+ }
+ }
+ }
+ return NID_undef;
}
-size_t SCT_get0_extensions(const SCT *sct, unsigned char **ext)
+size_t
+SCT_get0_extensions(const SCT *sct, unsigned char **ext)
{
- *ext = sct->ext;
- return sct->ext_len;
+ *ext = sct->ext;
+ return sct->ext_len;
}
-size_t SCT_get0_signature(const SCT *sct, unsigned char **sig)
+size_t
+SCT_get0_signature(const SCT *sct, unsigned char **sig)
{
- *sig = sct->sig;
- return sct->sig_len;
+ *sig = sct->sig;
+ return sct->sig_len;
}
-int SCT_is_complete(const SCT *sct)
+int
+SCT_is_complete(const SCT *sct)
{
- switch (sct->version) {
- case SCT_VERSION_NOT_SET:
- return 0;
- case SCT_VERSION_V1:
- return sct->log_id != NULL && SCT_signature_is_complete(sct);
- default:
- return sct->sct != NULL; /* Just need cached encoding */
- }
+ switch (sct->version) {
+ case SCT_VERSION_NOT_SET:
+ return 0;
+ case SCT_VERSION_V1:
+ return sct->log_id != NULL && SCT_signature_is_complete(sct);
+ default:
+ return sct->sct != NULL; /* Just need cached encoding */
+ }
}
-int SCT_signature_is_complete(const SCT *sct)
+int
+SCT_signature_is_complete(const SCT *sct)
{
- return SCT_get_signature_nid(sct) != NID_undef &&
- sct->sig != NULL && sct->sig_len > 0;
+ return SCT_get_signature_nid(sct) != NID_undef && sct->sig != NULL &&
+ sct->sig_len > 0;
}
-sct_source_t SCT_get_source(const SCT *sct)
+sct_source_t
+SCT_get_source(const SCT *sct)
{
- return sct->source;
+ return sct->source;
}
-int SCT_set_source(SCT *sct, sct_source_t source)
+int
+SCT_set_source(SCT *sct, sct_source_t source)
{
- sct->source = source;
- sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
- switch (source) {
- case SCT_SOURCE_TLS_EXTENSION:
- case SCT_SOURCE_OCSP_STAPLED_RESPONSE:
- return SCT_set_log_entry_type(sct, CT_LOG_ENTRY_TYPE_X509);
- case SCT_SOURCE_X509V3_EXTENSION:
- return SCT_set_log_entry_type(sct, CT_LOG_ENTRY_TYPE_PRECERT);
- case SCT_SOURCE_UNKNOWN:
- break;
- }
- /* if we aren't sure, leave the log entry type alone */
- return 1;
+ sct->source = source;
+ sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
+ switch (source) {
+ case SCT_SOURCE_TLS_EXTENSION:
+ case SCT_SOURCE_OCSP_STAPLED_RESPONSE:
+ return SCT_set_log_entry_type(sct, CT_LOG_ENTRY_TYPE_X509);
+ case SCT_SOURCE_X509V3_EXTENSION:
+ return SCT_set_log_entry_type(sct, CT_LOG_ENTRY_TYPE_PRECERT);
+ case SCT_SOURCE_UNKNOWN:
+ break;
+ }
+ /* if we aren't sure, leave the log entry type alone */
+ return 1;
}
-sct_validation_status_t SCT_get_validation_status(const SCT *sct)
+sct_validation_status_t
+SCT_get_validation_status(const SCT *sct)
{
- return sct->validation_status;
+ return sct->validation_status;
}
-int SCT_validate(SCT *sct, const CT_POLICY_EVAL_CTX *ctx)
+int
+SCT_validate(SCT *sct, const CT_POLICY_EVAL_CTX *ctx)
{
- int is_sct_valid = -1;
- SCT_CTX *sctx = NULL;
- X509_PUBKEY *pub = NULL, *log_pkey = NULL;
- const CTLOG *log;
-
- /*
- * With an unrecognized SCT version we don't know what such an SCT means,
- * let alone validate one. So we return validation failure (0).
- */
- if (sct->version != SCT_VERSION_V1) {
- sct->validation_status = SCT_VALIDATION_STATUS_UNKNOWN_VERSION;
- return 0;
- }
-
- log = CTLOG_STORE_get0_log_by_id(ctx->log_store,
- sct->log_id, sct->log_id_len);
-
- /* Similarly, an SCT from an unknown log also cannot be validated. */
- if (log == NULL) {
- sct->validation_status = SCT_VALIDATION_STATUS_UNKNOWN_LOG;
- return 0;
- }
-
- sctx = SCT_CTX_new();
- if (sctx == NULL)
- goto err;
-
- if (X509_PUBKEY_set(&log_pkey, CTLOG_get0_public_key(log)) != 1)
- goto err;
- if (SCT_CTX_set1_pubkey(sctx, log_pkey) != 1)
- goto err;
-
- if (SCT_get_log_entry_type(sct) == CT_LOG_ENTRY_TYPE_PRECERT) {
- EVP_PKEY *issuer_pkey;
-
- if (ctx->issuer == NULL) {
- sct->validation_status = SCT_VALIDATION_STATUS_UNVERIFIED;
- goto end;
- }
-
- issuer_pkey = X509_get0_pubkey(ctx->issuer);
-
- if (X509_PUBKEY_set(&pub, issuer_pkey) != 1)
- goto err;
- if (SCT_CTX_set1_issuer_pubkey(sctx, pub) != 1)
- goto err;
- }
-
- SCT_CTX_set_time(sctx, ctx->epoch_time_in_ms);
-
- /*
- * XXX: Potential for optimization. This repeats some idempotent heavy
- * lifting on the certificate for each candidate SCT, and appears to not
- * use any information in the SCT itself, only the certificate is
- * processed. So it may make more sense to to do this just once, perhaps
- * associated with the shared (by all SCTs) policy eval ctx.
- *
- * XXX: Failure here is global (SCT independent) and represents either an
- * issue with the certificate (e.g. duplicate extensions) or an out of
- * memory condition. When the certificate is incompatible with CT, we just
- * mark the SCTs invalid, rather than report a failure to determine the
- * validation status. That way, callbacks that want to do "soft" SCT
- * processing will not abort handshakes with false positive internal
- * errors. Since the function does not distinguish between certificate
- * issues (peer's fault) and internal problems (out fault) the safe thing
- * to do is to report a validation failure and let the callback or
- * application decide what to do.
- */
- if (SCT_CTX_set1_cert(sctx, ctx->cert, NULL) != 1)
- sct->validation_status = SCT_VALIDATION_STATUS_UNVERIFIED;
- else
- sct->validation_status = SCT_CTX_verify(sctx, sct) == 1 ?
- SCT_VALIDATION_STATUS_VALID : SCT_VALIDATION_STATUS_INVALID;
-
-end:
- is_sct_valid = sct->validation_status == SCT_VALIDATION_STATUS_VALID;
-err:
- X509_PUBKEY_free(pub);
- X509_PUBKEY_free(log_pkey);
- SCT_CTX_free(sctx);
-
- return is_sct_valid;
+ int is_sct_valid = -1;
+ SCT_CTX *sctx = NULL;
+ X509_PUBKEY *pub = NULL, *log_pkey = NULL;
+ const CTLOG *log;
+
+ /*
+ * With an unrecognized SCT version we don't know what such an SCT means,
+ * let alone validate one. So we return validation failure (0).
+ */
+ if (sct->version != SCT_VERSION_V1) {
+ sct->validation_status = SCT_VALIDATION_STATUS_UNKNOWN_VERSION;
+ return 0;
+ }
+
+ log = CTLOG_STORE_get0_log_by_id(ctx->log_store, sct->log_id,
+ sct->log_id_len);
+
+ /* Similarly, an SCT from an unknown log also cannot be validated. */
+ if (log == NULL) {
+ sct->validation_status = SCT_VALIDATION_STATUS_UNKNOWN_LOG;
+ return 0;
+ }
+
+ sctx = SCT_CTX_new();
+ if (sctx == NULL)
+ goto err;
+
+ if (X509_PUBKEY_set(&log_pkey, CTLOG_get0_public_key(log)) != 1)
+ goto err;
+ if (SCT_CTX_set1_pubkey(sctx, log_pkey) != 1)
+ goto err;
+
+ if (SCT_get_log_entry_type(sct) == CT_LOG_ENTRY_TYPE_PRECERT) {
+ EVP_PKEY *issuer_pkey;
+
+ if (ctx->issuer == NULL) {
+ sct->validation_status = SCT_VALIDATION_STATUS_UNVERIFIED;
+ goto end;
+ }
+
+ issuer_pkey = X509_get0_pubkey(ctx->issuer);
+
+ if (X509_PUBKEY_set(&pub, issuer_pkey) != 1)
+ goto err;
+ if (SCT_CTX_set1_issuer_pubkey(sctx, pub) != 1)
+ goto err;
+ }
+
+ SCT_CTX_set_time(sctx, ctx->epoch_time_in_ms);
+
+ /*
+ * XXX: Potential for optimization. This repeats some idempotent heavy
+ * lifting on the certificate for each candidate SCT, and appears to not
+ * use any information in the SCT itself, only the certificate is
+ * processed. So it may make more sense to to do this just once, perhaps
+ * associated with the shared (by all SCTs) policy eval ctx.
+ *
+ * XXX: Failure here is global (SCT independent) and represents either an
+ * issue with the certificate (e.g. duplicate extensions) or an out of
+ * memory condition. When the certificate is incompatible with CT, we just
+ * mark the SCTs invalid, rather than report a failure to determine the
+ * validation status. That way, callbacks that want to do "soft" SCT
+ * processing will not abort handshakes with false positive internal
+ * errors. Since the function does not distinguish between certificate
+ * issues (peer's fault) and internal problems (out fault) the safe thing
+ * to do is to report a validation failure and let the callback or
+ * application decide what to do.
+ */
+ if (SCT_CTX_set1_cert(sctx, ctx->cert, NULL) != 1)
+ sct->validation_status = SCT_VALIDATION_STATUS_UNVERIFIED;
+ else
+ sct->validation_status = SCT_CTX_verify(sctx, sct) == 1 ?
+ SCT_VALIDATION_STATUS_VALID : SCT_VALIDATION_STATUS_INVALID;
+
+ end:
+ is_sct_valid = sct->validation_status == SCT_VALIDATION_STATUS_VALID;
+ err:
+ X509_PUBKEY_free(pub);
+ X509_PUBKEY_free(log_pkey);
+ SCT_CTX_free(sctx);
+
+ return is_sct_valid;
}
-int SCT_LIST_validate(const STACK_OF(SCT) *scts, CT_POLICY_EVAL_CTX *ctx)
+int
+SCT_LIST_validate(const STACK_OF(SCT) *scts, CT_POLICY_EVAL_CTX *ctx)
{
- int are_scts_valid = 1;
- int sct_count = scts != NULL ? sk_SCT_num(scts) : 0;
- int i;
+ int are_scts_valid = 1;
+ int sct_count = scts != NULL ? sk_SCT_num(scts) : 0;
+ int i;
- for (i = 0; i < sct_count; ++i) {
- int is_sct_valid = -1;
- SCT *sct = sk_SCT_value(scts, i);
+ for (i = 0; i < sct_count; ++i) {
+ int is_sct_valid = -1;
+ SCT *sct = sk_SCT_value(scts, i);
- if (sct == NULL)
- continue;
+ if (sct == NULL)
+ continue;
- is_sct_valid = SCT_validate(sct, ctx);
- if (is_sct_valid < 0)
- return is_sct_valid;
- are_scts_valid &= is_sct_valid;
- }
+ is_sct_valid = SCT_validate(sct, ctx);
+ if (is_sct_valid < 0)
+ return is_sct_valid;
+ are_scts_valid &= is_sct_valid;
+ }
- return are_scts_valid;
+ return are_scts_valid;
}
#include "ct_local.h"
-SCT_CTX *SCT_CTX_new(void)
+SCT_CTX *
+SCT_CTX_new(void)
{
- SCT_CTX *sctx = OPENSSL_zalloc(sizeof(*sctx));
+ SCT_CTX *sctx = OPENSSL_zalloc(sizeof(*sctx));
- if (sctx == NULL)
- CTerr(CT_F_SCT_CTX_NEW, ERR_R_MALLOC_FAILURE);
+ if (sctx == NULL)
+ CTerr(CT_F_SCT_CTX_NEW, ERR_R_MALLOC_FAILURE);
- return sctx;
+ return sctx;
}
-void SCT_CTX_free(SCT_CTX *sctx)
+void
+SCT_CTX_free(SCT_CTX *sctx)
{
- if (sctx == NULL)
- return;
- EVP_PKEY_free(sctx->pkey);
- OPENSSL_free(sctx->pkeyhash);
- OPENSSL_free(sctx->ihash);
- OPENSSL_free(sctx->certder);
- OPENSSL_free(sctx->preder);
- OPENSSL_free(sctx);
+ if (sctx == NULL)
+ return;
+ EVP_PKEY_free(sctx->pkey);
+ OPENSSL_free(sctx->pkeyhash);
+ OPENSSL_free(sctx->ihash);
+ OPENSSL_free(sctx->certder);
+ OPENSSL_free(sctx->preder);
+ OPENSSL_free(sctx);
}
/*
* If there is more than one extension with that NID, *is_duplicated is set to
* 1, otherwise 0 (unless it is NULL).
*/
-static int ct_x509_get_ext(X509 *cert, int nid, int *is_duplicated)
+static int
+ct_x509_get_ext(X509 *cert, int nid, int *is_duplicated)
{
- int ret = X509_get_ext_by_NID(cert, nid, -1);
+ int ret = X509_get_ext_by_NID(cert, nid, -1);
- if (is_duplicated != NULL)
- *is_duplicated = ret >= 0 && X509_get_ext_by_NID(cert, nid, ret) >= 0;
+ if (is_duplicated != NULL)
+ *is_duplicated = ret >= 0 &&
+ X509_get_ext_by_NID(cert, nid, ret) >= 0;
- return ret;
+ return ret;
}
/*
* AKID from the presigner certificate, if necessary.
* Returns 1 on success, 0 otherwise.
*/
-__owur static int ct_x509_cert_fixup(X509 *cert, X509 *presigner)
+__owur static int
+ct_x509_cert_fixup(X509 *cert, X509 *presigner)
{
- int preidx, certidx;
- int pre_akid_ext_is_dup, cert_akid_ext_is_dup;
-
- if (presigner == NULL)
- return 1;
-
- preidx = ct_x509_get_ext(presigner, NID_authority_key_identifier,
- &pre_akid_ext_is_dup);
- certidx = ct_x509_get_ext(cert, NID_authority_key_identifier,
- &cert_akid_ext_is_dup);
-
- /* An error occurred whilst searching for the extension */
- if (preidx < -1 || certidx < -1)
- return 0;
- /* Invalid certificate if they contain duplicate extensions */
- if (pre_akid_ext_is_dup || cert_akid_ext_is_dup)
- return 0;
- /* AKID must be present in both certificate or absent in both */
- if (preidx >= 0 && certidx == -1)
- return 0;
- if (preidx == -1 && certidx >= 0)
- return 0;
- /* Copy issuer name */
- if (!X509_set_issuer_name(cert, X509_get_issuer_name(presigner)))
- return 0;
- if (preidx != -1) {
- /* Retrieve and copy AKID encoding */
- X509_EXTENSION *preext = X509_get_ext(presigner, preidx);
- X509_EXTENSION *certext = X509_get_ext(cert, certidx);
- ASN1_OCTET_STRING *preextdata;
-
- /* Should never happen */
- if (preext == NULL || certext == NULL)
- return 0;
- preextdata = X509_EXTENSION_get_data(preext);
- if (preextdata == NULL ||
- !X509_EXTENSION_set_data(certext, preextdata))
- return 0;
- }
- return 1;
+ int preidx, certidx;
+ int pre_akid_ext_is_dup, cert_akid_ext_is_dup;
+
+ if (presigner == NULL)
+ return 1;
+
+ preidx = ct_x509_get_ext(presigner, NID_authority_key_identifier,
+ &pre_akid_ext_is_dup);
+ certidx = ct_x509_get_ext(cert, NID_authority_key_identifier,
+ &cert_akid_ext_is_dup);
+
+ /* An error occurred whilst searching for the extension */
+ if (preidx < -1 || certidx < -1)
+ return 0;
+ /* Invalid certificate if they contain duplicate extensions */
+ if (pre_akid_ext_is_dup || cert_akid_ext_is_dup)
+ return 0;
+ /* AKID must be present in both certificate or absent in both */
+ if (preidx >= 0 && certidx == -1)
+ return 0;
+ if (preidx == -1 && certidx >= 0)
+ return 0;
+ /* Copy issuer name */
+ if (!X509_set_issuer_name(cert, X509_get_issuer_name(presigner)))
+ return 0;
+ if (preidx != -1) {
+ /* Retrieve and copy AKID encoding */
+ X509_EXTENSION *preext = X509_get_ext(presigner, preidx);
+ X509_EXTENSION *certext = X509_get_ext(cert, certidx);
+ ASN1_OCTET_STRING *preextdata;
+
+ /* Should never happen */
+ if (preext == NULL || certext == NULL)
+ return 0;
+ preextdata = X509_EXTENSION_get_data(preext);
+ if (preextdata == NULL ||
+ !X509_EXTENSION_set_data(certext, preextdata))
+ return 0;
+ }
+ return 1;
}
-int SCT_CTX_set1_cert(SCT_CTX *sctx, X509 *cert, X509 *presigner)
+int
+SCT_CTX_set1_cert(SCT_CTX *sctx, X509 *cert, X509 *presigner)
{
- unsigned char *certder = NULL, *preder = NULL;
- X509 *pretmp = NULL;
- int certderlen = 0, prederlen = 0;
- int idx = -1;
- int poison_ext_is_dup, sct_ext_is_dup;
- int poison_idx = ct_x509_get_ext(cert, NID_ct_precert_poison, &poison_ext_is_dup);
-
- /* Duplicate poison extensions are present - error */
- if (poison_ext_is_dup)
- goto err;
-
- /* If *cert doesn't have a poison extension, it isn't a precert */
- if (poison_idx == -1) {
- /* cert isn't a precert, so we shouldn't have a presigner */
- if (presigner != NULL)
- goto err;
-
- certderlen = i2d_X509(cert, &certder);
- if (certderlen < 0)
- goto err;
- }
-
- /* See if cert has a precert SCTs extension */
- idx = ct_x509_get_ext(cert, NID_ct_precert_scts, &sct_ext_is_dup);
- /* Duplicate SCT extensions are present - error */
- if (sct_ext_is_dup)
- goto err;
-
- if (idx >= 0 && poison_idx >= 0) {
- /*
- * cert can't both contain SCTs (i.e. have an SCT extension) and be a
- * precert (i.e. have a poison extension).
- */
- goto err;
- }
-
- if (idx == -1) {
- idx = poison_idx;
- }
-
- /*
- * If either a poison or SCT extension is present, remove it before encoding
- * cert. This, along with ct_x509_cert_fixup(), gets a TBSCertificate (see
- * RFC5280) from cert, which is what the CT log signed when it produced the
- * SCT.
- */
- if (idx >= 0) {
- X509_EXTENSION *ext;
-
- /* Take a copy of certificate so we don't modify passed version */
- pretmp = X509_dup(cert);
- if (pretmp == NULL)
- goto err;
-
- ext = X509_delete_ext(pretmp, idx);
- X509_EXTENSION_free(ext);
-
- if (!ct_x509_cert_fixup(pretmp, presigner))
- goto err;
-
- prederlen = i2d_re_X509_tbs(pretmp, &preder);
- if (prederlen <= 0)
- goto err;
- }
-
- X509_free(pretmp);
-
- OPENSSL_free(sctx->certder);
- sctx->certder = certder;
- sctx->certderlen = certderlen;
-
- OPENSSL_free(sctx->preder);
- sctx->preder = preder;
- sctx->prederlen = prederlen;
-
- return 1;
-err:
- OPENSSL_free(certder);
- OPENSSL_free(preder);
- X509_free(pretmp);
- return 0;
+ unsigned char *certder = NULL, *preder = NULL;
+ X509 *pretmp = NULL;
+ int certderlen = 0, prederlen = 0;
+ int idx = -1;
+ int poison_ext_is_dup, sct_ext_is_dup;
+ int poison_idx = ct_x509_get_ext(cert, NID_ct_precert_poison, &poison_ext_is_dup);
+
+ /* Duplicate poison extensions are present - error */
+ if (poison_ext_is_dup)
+ goto err;
+
+ /* If *cert doesn't have a poison extension, it isn't a precert */
+ if (poison_idx == -1) {
+ /* cert isn't a precert, so we shouldn't have a presigner */
+ if (presigner != NULL)
+ goto err;
+
+ certderlen = i2d_X509(cert, &certder);
+ if (certderlen < 0)
+ goto err;
+ }
+
+ /* See if cert has a precert SCTs extension */
+ idx = ct_x509_get_ext(cert, NID_ct_precert_scts, &sct_ext_is_dup);
+ /* Duplicate SCT extensions are present - error */
+ if (sct_ext_is_dup)
+ goto err;
+
+ if (idx >= 0 && poison_idx >= 0) {
+ /*
+ * cert can't both contain SCTs (i.e. have an SCT extension) and be a
+ * precert (i.e. have a poison extension).
+ */
+ goto err;
+ }
+
+ if (idx == -1) {
+ idx = poison_idx;
+ }
+
+ /*
+ * If either a poison or SCT extension is present, remove it before encoding
+ * cert. This, along with ct_x509_cert_fixup(), gets a TBSCertificate (see
+ * RFC5280) from cert, which is what the CT log signed when it produced the
+ * SCT.
+ */
+ if (idx >= 0) {
+ X509_EXTENSION *ext;
+
+ /* Take a copy of certificate so we don't modify passed version */
+ pretmp = X509_dup(cert);
+ if (pretmp == NULL)
+ goto err;
+
+ ext = X509_delete_ext(pretmp, idx);
+ X509_EXTENSION_free(ext);
+
+ if (!ct_x509_cert_fixup(pretmp, presigner))
+ goto err;
+
+ prederlen = i2d_re_X509_tbs(pretmp, &preder);
+ if (prederlen <= 0)
+ goto err;
+ }
+
+ X509_free(pretmp);
+
+ OPENSSL_free(sctx->certder);
+ sctx->certder = certder;
+ sctx->certderlen = certderlen;
+
+ OPENSSL_free(sctx->preder);
+ sctx->preder = preder;
+ sctx->prederlen = prederlen;
+
+ return 1;
+ err:
+ OPENSSL_free(certder);
+ OPENSSL_free(preder);
+ X509_free(pretmp);
+ 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(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;
-
- /* Reuse buffer if possible */
- if (*hash != NULL && *hash_len >= SHA256_DIGEST_LENGTH) {
- md = *hash;
- } else {
- md = OPENSSL_malloc(SHA256_DIGEST_LENGTH);
- if (md == NULL)
- goto err;
- }
-
- /* Calculate key hash */
- der_len = i2d_X509_PUBKEY(pkey, &der);
- if (der_len <= 0)
- goto err;
-
- if (!EVP_Digest(der, der_len, md, &md_len, EVP_sha256(), NULL))
- goto err;
-
- if (md != *hash) {
- OPENSSL_free(*hash);
- *hash = md;
- *hash_len = SHA256_DIGEST_LENGTH;
- }
-
- md = NULL;
- ret = 1;
+ int ret = 0;
+ unsigned char *md = NULL, *der = NULL;
+ int der_len;
+ unsigned int md_len;
+
+ /* Reuse buffer if possible */
+ if (*hash != NULL && *hash_len >= SHA256_DIGEST_LENGTH) {
+ md = *hash;
+ } else {
+ md = OPENSSL_malloc(SHA256_DIGEST_LENGTH);
+ if (md == NULL)
+ goto err;
+ }
+
+ /* Calculate key hash */
+ der_len = i2d_X509_PUBKEY(pkey, &der);
+ if (der_len <= 0)
+ goto err;
+
+ if (!EVP_Digest(der, der_len, md, &md_len, EVP_sha256(), NULL))
+ goto err;
+
+ if (md != *hash) {
+ OPENSSL_free(*hash);
+ *hash = md;
+ *hash_len = SHA256_DIGEST_LENGTH;
+ }
+
+ md = NULL;
+ ret = 1;
err:
- OPENSSL_free(md);
- OPENSSL_free(der);
- return ret;
+ OPENSSL_free(md);
+ OPENSSL_free(der);
+ return ret;
}
-int SCT_CTX_set1_issuer(SCT_CTX *sctx, const X509 *issuer)
+int
+SCT_CTX_set1_issuer(SCT_CTX *sctx, const X509 *issuer)
{
- return SCT_CTX_set1_issuer_pubkey(sctx, X509_get_X509_PUBKEY(issuer));
+ return SCT_CTX_set1_issuer_pubkey(sctx, X509_get_X509_PUBKEY(issuer));
}
-int SCT_CTX_set1_issuer_pubkey(SCT_CTX *sctx, X509_PUBKEY *pubkey)
+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(pubkey, &sctx->ihash, &sctx->ihashlen);
}
-int SCT_CTX_set1_pubkey(SCT_CTX *sctx, X509_PUBKEY *pubkey)
+int
+SCT_CTX_set1_pubkey(SCT_CTX *sctx, X509_PUBKEY *pubkey)
{
- EVP_PKEY *pkey = X509_PUBKEY_get(pubkey);
+ EVP_PKEY *pkey = X509_PUBKEY_get(pubkey);
- if (pkey == NULL)
- return 0;
+ if (pkey == NULL)
+ return 0;
- if (!ct_public_key_hash(pubkey, &sctx->pkeyhash, &sctx->pkeyhashlen)) {
- EVP_PKEY_free(pkey);
- return 0;
- }
+ if (!ct_public_key_hash(pubkey, &sctx->pkeyhash, &sctx->pkeyhashlen)) {
+ EVP_PKEY_free(pkey);
+ return 0;
+ }
- EVP_PKEY_free(sctx->pkey);
- sctx->pkey = pkey;
- return 1;
+ EVP_PKEY_free(sctx->pkey);
+ sctx->pkey = pkey;
+ return 1;
}
-void SCT_CTX_set_time(SCT_CTX *sctx, uint64_t time_in_ms)
+void
+SCT_CTX_set_time(SCT_CTX *sctx, uint64_t time_in_ms)
{
- sctx->epoch_time_in_ms = time_in_ms;
+ sctx->epoch_time_in_ms = time_in_ms;
}
#include "ct_local.h"
typedef enum sct_signature_type_t {
- SIGNATURE_TYPE_NOT_SET = -1,
- SIGNATURE_TYPE_CERT_TIMESTAMP,
- SIGNATURE_TYPE_TREE_HASH
+ SIGNATURE_TYPE_NOT_SET = -1,
+ SIGNATURE_TYPE_CERT_TIMESTAMP,
+ SIGNATURE_TYPE_TREE_HASH
} SCT_SIGNATURE_TYPE;
/*
* Update encoding for SCT signature verification/generation to supplied
* EVP_MD_CTX.
*/
-static int sct_ctx_update(EVP_MD_CTX *ctx, const SCT_CTX *sctx, const SCT *sct)
+static int
+sct_ctx_update(EVP_MD_CTX *ctx, const SCT_CTX *sctx, const SCT *sct)
{
- unsigned char tmpbuf[12];
- unsigned char *p, *der;
- size_t derlen;
- /*+
- * digitally-signed struct {
- * (1 byte) Version sct_version;
- * (1 byte) SignatureType signature_type = certificate_timestamp;
- * (8 bytes) uint64 timestamp;
- * (2 bytes) LogEntryType entry_type;
- * (? bytes) select(entry_type) {
- * case x509_entry: ASN.1Cert;
- * case precert_entry: PreCert;
- * } signed_entry;
- * (2 bytes + sct->ext_len) CtExtensions extensions;
- * }
- */
- if (sct->entry_type == CT_LOG_ENTRY_TYPE_NOT_SET)
- return 0;
- if (sct->entry_type == CT_LOG_ENTRY_TYPE_PRECERT && sctx->ihash == NULL)
- return 0;
-
- p = tmpbuf;
- *p++ = sct->version;
- *p++ = SIGNATURE_TYPE_CERT_TIMESTAMP;
- l2n8(sct->timestamp, p);
- s2n(sct->entry_type, p);
-
- if (!EVP_DigestUpdate(ctx, tmpbuf, p - tmpbuf))
- return 0;
-
- if (sct->entry_type == CT_LOG_ENTRY_TYPE_X509) {
- der = sctx->certder;
- derlen = sctx->certderlen;
- } else {
- if (!EVP_DigestUpdate(ctx, sctx->ihash, sctx->ihashlen))
- return 0;
- der = sctx->preder;
- derlen = sctx->prederlen;
- }
-
- /* If no encoding available, fatal error */
- if (der == NULL)
- return 0;
-
- /* Include length first */
- p = tmpbuf;
- l2n3(derlen, p);
-
- if (!EVP_DigestUpdate(ctx, tmpbuf, 3))
- return 0;
- if (!EVP_DigestUpdate(ctx, der, derlen))
- return 0;
-
- /* Add any extensions */
- p = tmpbuf;
- s2n(sct->ext_len, p);
- if (!EVP_DigestUpdate(ctx, tmpbuf, 2))
- return 0;
-
- if (sct->ext_len && !EVP_DigestUpdate(ctx, sct->ext, sct->ext_len))
- return 0;
-
- return 1;
+ unsigned char tmpbuf[12];
+ unsigned char *p, *der;
+ size_t derlen;
+ /*+
+ * digitally-signed struct {
+ * (1 byte) Version sct_version;
+ * (1 byte) SignatureType signature_type = certificate_timestamp;
+ * (8 bytes) uint64 timestamp;
+ * (2 bytes) LogEntryType entry_type;
+ * (? bytes) select(entry_type) {
+ * case x509_entry: ASN.1Cert;
+ * case precert_entry: PreCert;
+ * } signed_entry;
+ * (2 bytes + sct->ext_len) CtExtensions extensions;
+ * }
+ */
+ if (sct->entry_type == CT_LOG_ENTRY_TYPE_NOT_SET)
+ return 0;
+ if (sct->entry_type == CT_LOG_ENTRY_TYPE_PRECERT && sctx->ihash == NULL)
+ return 0;
+
+ p = tmpbuf;
+ *p++ = sct->version;
+ *p++ = SIGNATURE_TYPE_CERT_TIMESTAMP;
+ l2n8(sct->timestamp, p);
+ s2n(sct->entry_type, p);
+
+ if (!EVP_DigestUpdate(ctx, tmpbuf, p - tmpbuf))
+ return 0;
+
+ if (sct->entry_type == CT_LOG_ENTRY_TYPE_X509) {
+ der = sctx->certder;
+ derlen = sctx->certderlen;
+ } else {
+ if (!EVP_DigestUpdate(ctx, sctx->ihash, sctx->ihashlen))
+ return 0;
+ der = sctx->preder;
+ derlen = sctx->prederlen;
+ }
+
+ /* If no encoding available, fatal error */
+ if (der == NULL)
+ return 0;
+
+ /* Include length first */
+ p = tmpbuf;
+ l2n3(derlen, p);
+
+ if (!EVP_DigestUpdate(ctx, tmpbuf, 3))
+ return 0;
+ if (!EVP_DigestUpdate(ctx, der, derlen))
+ return 0;
+
+ /* Add any extensions */
+ p = tmpbuf;
+ s2n(sct->ext_len, p);
+ if (!EVP_DigestUpdate(ctx, tmpbuf, 2))
+ return 0;
+
+ if (sct->ext_len && !EVP_DigestUpdate(ctx, sct->ext, sct->ext_len))
+ return 0;
+
+ return 1;
}
-int SCT_CTX_verify(const SCT_CTX *sctx, const SCT *sct)
+int
+SCT_CTX_verify(const SCT_CTX *sctx, const SCT *sct)
{
- EVP_MD_CTX *ctx = NULL;
- int ret = 0;
-
- if (!SCT_is_complete(sct) || sctx->pkey == NULL ||
- sct->entry_type == CT_LOG_ENTRY_TYPE_NOT_SET ||
- (sct->entry_type == CT_LOG_ENTRY_TYPE_PRECERT && sctx->ihash == NULL)) {
- CTerr(CT_F_SCT_CTX_VERIFY, CT_R_SCT_NOT_SET);
- return 0;
- }
- if (sct->version != SCT_VERSION_V1) {
- CTerr(CT_F_SCT_CTX_VERIFY, CT_R_SCT_UNSUPPORTED_VERSION);
- return 0;
- }
- if (sct->log_id_len != sctx->pkeyhashlen ||
- memcmp(sct->log_id, sctx->pkeyhash, sctx->pkeyhashlen) != 0) {
- CTerr(CT_F_SCT_CTX_VERIFY, CT_R_SCT_LOG_ID_MISMATCH);
- return 0;
- }
- if (sct->timestamp > sctx->epoch_time_in_ms) {
- CTerr(CT_F_SCT_CTX_VERIFY, CT_R_SCT_FUTURE_TIMESTAMP);
- return 0;
- }
-
- ctx = EVP_MD_CTX_new();
- if (ctx == NULL)
- goto end;
-
- if (!EVP_DigestVerifyInit(ctx, NULL, EVP_sha256(), NULL, sctx->pkey))
- goto end;
-
- if (!sct_ctx_update(ctx, sctx, sct))
- goto end;
-
- /* Verify signature */
- ret = EVP_DigestVerifyFinal(ctx, sct->sig, sct->sig_len);
- /* If ret < 0 some other error: fall through without setting error */
- if (ret == 0)
- CTerr(CT_F_SCT_CTX_VERIFY, CT_R_SCT_INVALID_SIGNATURE);
-
-end:
- EVP_MD_CTX_free(ctx);
- return ret;
+ EVP_MD_CTX *ctx = NULL;
+ int ret = 0;
+
+ if (!SCT_is_complete(sct) || sctx->pkey == NULL ||
+ sct->entry_type == CT_LOG_ENTRY_TYPE_NOT_SET ||
+ (sct->entry_type == CT_LOG_ENTRY_TYPE_PRECERT && sctx->ihash == NULL)) {
+ CTerr(CT_F_SCT_CTX_VERIFY, CT_R_SCT_NOT_SET);
+ return 0;
+ }
+ if (sct->version != SCT_VERSION_V1) {
+ CTerr(CT_F_SCT_CTX_VERIFY, CT_R_SCT_UNSUPPORTED_VERSION);
+ return 0;
+ }
+ if (sct->log_id_len != sctx->pkeyhashlen ||
+ memcmp(sct->log_id, sctx->pkeyhash, sctx->pkeyhashlen) != 0) {
+ CTerr(CT_F_SCT_CTX_VERIFY, CT_R_SCT_LOG_ID_MISMATCH);
+ return 0;
+ }
+ if (sct->timestamp > sctx->epoch_time_in_ms) {
+ CTerr(CT_F_SCT_CTX_VERIFY, CT_R_SCT_FUTURE_TIMESTAMP);
+ return 0;
+ }
+
+ ctx = EVP_MD_CTX_new();
+ if (ctx == NULL)
+ goto end;
+
+ if (!EVP_DigestVerifyInit(ctx, NULL, EVP_sha256(), NULL, sctx->pkey))
+ goto end;
+
+ if (!sct_ctx_update(ctx, sctx, sct))
+ goto end;
+
+ /* Verify signature */
+ ret = EVP_DigestVerifyFinal(ctx, sct->sig, sct->sig_len);
+ /* If ret < 0 some other error: fall through without setting error */
+ if (ret == 0)
+ CTerr(CT_F_SCT_CTX_VERIFY, CT_R_SCT_INVALID_SIGNATURE);
+
+ end:
+ EVP_MD_CTX_free(ctx);
+ return ret;
}
#include "ct_local.h"
-static char *i2s_poison(const X509V3_EXT_METHOD *method, void *val)
+static char *
+i2s_poison(const X509V3_EXT_METHOD *method, void *val)
{
- return OPENSSL_strdup("NULL");
+ return OPENSSL_strdup("NULL");
}
-static void *s2i_poison(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, const char *str)
+static void *
+s2i_poison(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, const char *str)
{
- return ASN1_NULL_new();
+ return ASN1_NULL_new();
}
-static int i2r_SCT_LIST(X509V3_EXT_METHOD *method, STACK_OF(SCT) *sct_list,
- BIO *out, int indent)
+static int
+i2r_SCT_LIST(X509V3_EXT_METHOD *method, STACK_OF(SCT) *sct_list, BIO *out,
+ int indent)
{
- SCT_LIST_print(sct_list, out, indent, "\n", NULL);
- return 1;
+ SCT_LIST_print(sct_list, out, indent, "\n", NULL);
+ return 1;
}
-static int set_sct_list_source(STACK_OF(SCT) *s, sct_source_t source)
+static int
+set_sct_list_source(STACK_OF(SCT) *s, sct_source_t source)
{
- if (s != NULL) {
- int i;
+ if (s != NULL) {
+ int i;
- for (i = 0; i < sk_SCT_num(s); i++) {
- int res = SCT_set_source(sk_SCT_value(s, i), source);
+ for (i = 0; i < sk_SCT_num(s); i++) {
+ int res = SCT_set_source(sk_SCT_value(s, i), source);
- if (res != 1) {
- return 0;
- }
- }
- }
- return 1;
+ if (res != 1) {
+ return 0;
+ }
+ }
+ }
+ return 1;
}
-static STACK_OF(SCT) *x509_ext_d2i_SCT_LIST(STACK_OF(SCT) **a,
- const unsigned char **pp,
- long len)
+static STACK_OF(SCT) *
+x509_ext_d2i_SCT_LIST(STACK_OF(SCT) **a, const unsigned char **pp, long len)
{
- STACK_OF(SCT) *s = d2i_SCT_LIST(a, pp, len);
+ STACK_OF(SCT) *s = d2i_SCT_LIST(a, pp, len);
- if (set_sct_list_source(s, SCT_SOURCE_X509V3_EXTENSION) != 1) {
- SCT_LIST_free(s);
- *a = NULL;
- return NULL;
- }
- return s;
+ if (set_sct_list_source(s, SCT_SOURCE_X509V3_EXTENSION) != 1) {
+ SCT_LIST_free(s);
+ *a = NULL;
+ return NULL;
+ }
+ return s;
}
-static STACK_OF(SCT) *ocsp_ext_d2i_SCT_LIST(STACK_OF(SCT) **a,
- const unsigned char **pp,
- long len)
+static STACK_OF(SCT) *o
+csp_ext_d2i_SCT_LIST(STACK_OF(SCT) **a, const unsigned char **pp, long len)
{
- STACK_OF(SCT) *s = d2i_SCT_LIST(a, pp, len);
+ STACK_OF(SCT) *s = d2i_SCT_LIST(a, pp, len);
- if (set_sct_list_source(s, SCT_SOURCE_OCSP_STAPLED_RESPONSE) != 1) {
- SCT_LIST_free(s);
- *a = NULL;
- return NULL;
- }
- return s;
+ if (set_sct_list_source(s, SCT_SOURCE_OCSP_STAPLED_RESPONSE) != 1) {
+ SCT_LIST_free(s);
+ *a = NULL;
+ return NULL;
+ }
+ return s;
}
/* Handlers for X509v3/OCSP Certificate Transparency extensions */
const X509V3_EXT_METHOD v3_ct_scts[3] = {
- /* X509v3 extension in certificates that contains SCTs */
- { NID_ct_precert_scts, 0, NULL,
- NULL, (X509V3_EXT_FREE)SCT_LIST_free,
- (X509V3_EXT_D2I)x509_ext_d2i_SCT_LIST, (X509V3_EXT_I2D)i2d_SCT_LIST,
- NULL, NULL,
- NULL, NULL,
- (X509V3_EXT_I2R)i2r_SCT_LIST, NULL,
- NULL },
+ /* X509v3 extension in certificates that contains SCTs */
+ { NID_ct_precert_scts, 0, NULL,
+ NULL, (X509V3_EXT_FREE)SCT_LIST_free,
+ (X509V3_EXT_D2I)x509_ext_d2i_SCT_LIST, (X509V3_EXT_I2D)i2d_SCT_LIST,
+ NULL, NULL,
+ NULL, NULL,
+ (X509V3_EXT_I2R)i2r_SCT_LIST, NULL,
+ NULL },
- /* X509v3 extension to mark a certificate as a pre-certificate */
- { NID_ct_precert_poison, 0, ASN1_ITEM_ref(ASN1_NULL),
- NULL, NULL, NULL, NULL,
- i2s_poison, s2i_poison,
- NULL, NULL,
- NULL, NULL,
- NULL },
+ /* X509v3 extension to mark a certificate as a pre-certificate */
+ { NID_ct_precert_poison, 0, ASN1_ITEM_ref(ASN1_NULL),
+ NULL, NULL, NULL, NULL,
+ i2s_poison, s2i_poison,
+ NULL, NULL,
+ NULL, NULL,
+ NULL },
- /* OCSP extension that contains SCTs */
- { NID_ct_cert_scts, 0, NULL,
- 0, (X509V3_EXT_FREE)SCT_LIST_free,
- (X509V3_EXT_D2I)ocsp_ext_d2i_SCT_LIST, (X509V3_EXT_I2D)i2d_SCT_LIST,
- NULL, NULL,
- NULL, NULL,
- (X509V3_EXT_I2R)i2r_SCT_LIST, NULL,
- NULL },
+ /* OCSP extension that contains SCTs */
+ { NID_ct_cert_scts, 0, NULL,
+ 0, (X509V3_EXT_FREE)SCT_LIST_free,
+ (X509V3_EXT_D2I)ocsp_ext_d2i_SCT_LIST, (X509V3_EXT_I2D)i2d_SCT_LIST,
+ NULL, NULL,
+ NULL, NULL,
+ (X509V3_EXT_I2R)i2r_SCT_LIST, NULL,
+ NULL },
};