diff options
author | deshevoy <deshevoy@yandex-team.ru> | 2022-02-10 16:46:56 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:46:56 +0300 |
commit | e988f30484abe5fdeedcc7a5d3c226c01a21800c (patch) | |
tree | 0a217b173aabb57b7e51f8a169989b1a3e0309fe /contrib/libs/openssl/crypto/ct | |
parent | 33ee501c05d3f24036ae89766a858930ae66c548 (diff) | |
download | ydb-e988f30484abe5fdeedcc7a5d3c226c01a21800c.tar.gz |
Restoring authorship annotation for <deshevoy@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/libs/openssl/crypto/ct')
-rw-r--r-- | contrib/libs/openssl/crypto/ct/ct_b64.c | 334 | ||||
-rw-r--r-- | contrib/libs/openssl/crypto/ct/ct_err.c | 192 | ||||
-rw-r--r-- | contrib/libs/openssl/crypto/ct/ct_log.c | 612 | ||||
-rw-r--r-- | contrib/libs/openssl/crypto/ct/ct_oct.c | 812 | ||||
-rw-r--r-- | contrib/libs/openssl/crypto/ct/ct_policy.c | 194 | ||||
-rw-r--r-- | contrib/libs/openssl/crypto/ct/ct_prn.c | 252 | ||||
-rw-r--r-- | contrib/libs/openssl/crypto/ct/ct_sct.c | 790 | ||||
-rw-r--r-- | contrib/libs/openssl/crypto/ct/ct_sct_ctx.c | 524 | ||||
-rw-r--r-- | contrib/libs/openssl/crypto/ct/ct_vfy.c | 278 | ||||
-rw-r--r-- | contrib/libs/openssl/crypto/ct/ct_x509v3.c | 206 |
10 files changed, 2097 insertions, 2097 deletions
diff --git a/contrib/libs/openssl/crypto/ct/ct_b64.c b/contrib/libs/openssl/crypto/ct/ct_b64.c index 4abe11ca29..36eb219f6d 100644 --- a/contrib/libs/openssl/crypto/ct/ct_b64.c +++ b/contrib/libs/openssl/crypto/ct/ct_b64.c @@ -1,168 +1,168 @@ -/* - * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include <limits.h> -#include <string.h> - -#include <openssl/ct.h> -#include <openssl/err.h> -#include <openssl/evp.h> - +/* + * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include <limits.h> +#include <string.h> + +#include <openssl/ct.h> +#include <openssl/err.h> +#include <openssl/evp.h> + #include "ct_local.h" - -/* - * Decodes the base64 string |in| into |out|. - * 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) -{ - 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 = 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; -} - -/* - * Allocate, build and returns a new |ct_log| from input |pkey_base64| - * It returns 1 on success, - * 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) -{ - 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; -} + +/* + * Decodes the base64 string |in| into |out|. + * 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) +{ + 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 = 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; +} + +/* + * Allocate, build and returns a new |ct_log| from input |pkey_base64| + * It returns 1 on success, + * 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) +{ + 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; +} diff --git a/contrib/libs/openssl/crypto/ct/ct_err.c b/contrib/libs/openssl/crypto/ct/ct_err.c index c0c62fee6c..bdcf40cb2f 100644 --- a/contrib/libs/openssl/crypto/ct/ct_err.c +++ b/contrib/libs/openssl/crypto/ct/ct_err.c @@ -1,96 +1,96 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include <openssl/err.h> -#include <openssl/cterr.h> - -#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} -}; - -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} -}; - -#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); - } -#endif - return 1; -} +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include <openssl/err.h> +#include <openssl/cterr.h> + +#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} +}; + +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} +}; + +#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); + } +#endif + return 1; +} diff --git a/contrib/libs/openssl/crypto/ct/ct_log.c b/contrib/libs/openssl/crypto/ct/ct_log.c index c1bca3e141..652d4b5a47 100644 --- a/contrib/libs/openssl/crypto/ct/ct_log.c +++ b/contrib/libs/openssl/crypto/ct/ct_log.c @@ -1,306 +1,306 @@ -/* - * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include <stdlib.h> -#include <string.h> - -#include <openssl/conf.h> -#include <openssl/ct.h> -#include <openssl/err.h> -#include <openssl/evp.h> -#include <openssl/safestack.h> - -#include "internal/cryptlib.h" - -/* - * Information about a CT log server. - */ -struct ctlog_st { - char *name; - uint8_t log_id[CT_V1_HASHLEN]; - EVP_PKEY *public_key; -}; - -/* - * A store for multiple CTLOG instances. - * It takes ownership of any CTLOG instances added to it. - */ -struct ctlog_store_st { - 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_LOAD_CTX; - -/* - * Creates an empty context for loading a CT log store. - * It should be populated before use. - */ -static CTLOG_STORE_LOAD_CTX *ctlog_store_load_ctx_new(void); - -/* - * Deletes a CT log store load context. - * Does not delete any of the fields. - */ -static void ctlog_store_load_ctx_free(CTLOG_STORE_LOAD_CTX* ctx); - -static CTLOG_STORE_LOAD_CTX *ctlog_store_load_ctx_new(void) -{ - CTLOG_STORE_LOAD_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); - - if (ctx == NULL) - CTerr(CT_F_CTLOG_STORE_LOAD_CTX_NEW, ERR_R_MALLOC_FAILURE); - - return ctx; -} - -static void ctlog_store_load_ctx_free(CTLOG_STORE_LOAD_CTX* 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]) -{ - 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 *ret = OPENSSL_zalloc(sizeof(*ret)); - - 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; - - return ret; -err: - OPENSSL_free(ret); - return NULL; -} - -void CTLOG_STORE_free(CTLOG_STORE *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) -{ - 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; - } - - 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); -} - -int CTLOG_STORE_load_default_file(CTLOG_STORE *store) -{ - const char *fpath = ossl_safe_getenv(CTLOG_FILE_EVP); - - if (fpath == NULL) - fpath = CTLOG_FILE; - - return CTLOG_STORE_load_file(store, fpath); -} - -/* - * Called by CONF_parse_list, which stops if this returns <= 0, - * Otherwise, one bad log entry would stop loading of any of - * 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) -{ - 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; -} - -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; -end: - NCONF_free(load_ctx->conf); - ctlog_store_load_ctx_free(load_ctx); - return ret; -} - -/* - * Initialize a new CTLOG object. - * Takes ownership of the public key. - * Copies the 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; -} - -/* Frees CT log and associated structures */ -void CTLOG_free(CTLOG *log) -{ - if (log != NULL) { - OPENSSL_free(log->name); - EVP_PKEY_free(log->public_key); - OPENSSL_free(log); - } -} - -const char *CTLOG_get0_name(const CTLOG *log) -{ - return log->name; -} - -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; -} - -EVP_PKEY *CTLOG_get0_public_key(const CTLOG *log) -{ - 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) -{ - 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; - } - - return NULL; -} +/* + * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include <stdlib.h> +#include <string.h> + +#include <openssl/conf.h> +#include <openssl/ct.h> +#include <openssl/err.h> +#include <openssl/evp.h> +#include <openssl/safestack.h> + +#include "internal/cryptlib.h" + +/* + * Information about a CT log server. + */ +struct ctlog_st { + char *name; + uint8_t log_id[CT_V1_HASHLEN]; + EVP_PKEY *public_key; +}; + +/* + * A store for multiple CTLOG instances. + * It takes ownership of any CTLOG instances added to it. + */ +struct ctlog_store_st { + 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_LOAD_CTX; + +/* + * Creates an empty context for loading a CT log store. + * It should be populated before use. + */ +static CTLOG_STORE_LOAD_CTX *ctlog_store_load_ctx_new(void); + +/* + * Deletes a CT log store load context. + * Does not delete any of the fields. + */ +static void ctlog_store_load_ctx_free(CTLOG_STORE_LOAD_CTX* ctx); + +static CTLOG_STORE_LOAD_CTX *ctlog_store_load_ctx_new(void) +{ + CTLOG_STORE_LOAD_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); + + if (ctx == NULL) + CTerr(CT_F_CTLOG_STORE_LOAD_CTX_NEW, ERR_R_MALLOC_FAILURE); + + return ctx; +} + +static void ctlog_store_load_ctx_free(CTLOG_STORE_LOAD_CTX* 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]) +{ + 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 *ret = OPENSSL_zalloc(sizeof(*ret)); + + 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; + + return ret; +err: + OPENSSL_free(ret); + return NULL; +} + +void CTLOG_STORE_free(CTLOG_STORE *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) +{ + 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; + } + + 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); +} + +int CTLOG_STORE_load_default_file(CTLOG_STORE *store) +{ + const char *fpath = ossl_safe_getenv(CTLOG_FILE_EVP); + + if (fpath == NULL) + fpath = CTLOG_FILE; + + return CTLOG_STORE_load_file(store, fpath); +} + +/* + * Called by CONF_parse_list, which stops if this returns <= 0, + * Otherwise, one bad log entry would stop loading of any of + * 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) +{ + 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; +} + +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; +end: + NCONF_free(load_ctx->conf); + ctlog_store_load_ctx_free(load_ctx); + return ret; +} + +/* + * Initialize a new CTLOG object. + * Takes ownership of the public key. + * Copies the 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; +} + +/* Frees CT log and associated structures */ +void CTLOG_free(CTLOG *log) +{ + if (log != NULL) { + OPENSSL_free(log->name); + EVP_PKEY_free(log->public_key); + OPENSSL_free(log); + } +} + +const char *CTLOG_get0_name(const CTLOG *log) +{ + return log->name; +} + +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; +} + +EVP_PKEY *CTLOG_get0_public_key(const CTLOG *log) +{ + 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) +{ + 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; + } + + return NULL; +} diff --git a/contrib/libs/openssl/crypto/ct/ct_oct.c b/contrib/libs/openssl/crypto/ct/ct_oct.c index d4b6645af4..9364031691 100644 --- a/contrib/libs/openssl/crypto/ct/ct_oct.c +++ b/contrib/libs/openssl/crypto/ct/ct_oct.c @@ -1,407 +1,407 @@ -/* - * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifdef OPENSSL_NO_CT -# error "CT is disabled" -#endif - -#include <limits.h> -#include <string.h> - -#include <openssl/asn1.h> -#include <openssl/buffer.h> -#include <openssl/ct.h> -#include <openssl/err.h> - +/* + * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifdef OPENSSL_NO_CT +# error "CT is disabled" +#endif + +#include <limits.h> +#include <string.h> + +#include <openssl/asn1.h> +#include <openssl/buffer.h> +#include <openssl/ct.h> +#include <openssl/err.h> + #include "ct_local.h" - -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; -} - -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; -} - -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; -} - -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; -} - -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; - - err: - if (a == NULL || *a == NULL) - SCT_LIST_free(sk); - return NULL; -} - -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; - - err: - 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) -{ - 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 = oct->data; - if ((sk = o2i_SCT_LIST(a, &p, oct->length)) != NULL) - *pp += len; - - ASN1_OCTET_STRING_free(oct); - return sk; -} - -int i2d_SCT_LIST(const STACK_OF(SCT) *a, unsigned char **out) -{ - ASN1_OCTET_STRING oct; - int len; - - 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; -} + +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; +} + +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; +} + +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; +} + +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; +} + +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; + + err: + if (a == NULL || *a == NULL) + SCT_LIST_free(sk); + return NULL; +} + +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; + + err: + 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) +{ + 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 = oct->data; + if ((sk = o2i_SCT_LIST(a, &p, oct->length)) != NULL) + *pp += len; + + ASN1_OCTET_STRING_free(oct); + return sk; +} + +int i2d_SCT_LIST(const STACK_OF(SCT) *a, unsigned char **out) +{ + ASN1_OCTET_STRING oct; + int len; + + 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; +} diff --git a/contrib/libs/openssl/crypto/ct/ct_policy.c b/contrib/libs/openssl/crypto/ct/ct_policy.c index df66e8a494..75b9e59411 100644 --- a/contrib/libs/openssl/crypto/ct/ct_policy.c +++ b/contrib/libs/openssl/crypto/ct/ct_policy.c @@ -1,98 +1,98 @@ -/* - * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifdef OPENSSL_NO_CT -# error "CT is disabled" -#endif - -#include <openssl/ct.h> -#include <openssl/err.h> -#include <time.h> - +/* + * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifdef OPENSSL_NO_CT +# error "CT is disabled" +#endif + +#include <openssl/ct.h> +#include <openssl/err.h> +#include <time.h> + #include "ct_local.h" - -/* - * Number of seconds in the future that an SCT timestamp can be, by default, - * without being considered invalid. This is added to time() when setting a - * default value for CT_POLICY_EVAL_CTX.epoch_time_in_ms. - * It can be overridden by calling CT_POLICY_EVAL_CTX_set_time(). - */ -static const time_t SCT_CLOCK_DRIFT_TOLERANCE = 300; - -CT_POLICY_EVAL_CTX *CT_POLICY_EVAL_CTX_new(void) -{ - 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; - } - - /* 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; -} - -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); -} - -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; -} - -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; -} - -void CT_POLICY_EVAL_CTX_set_shared_CTLOG_STORE(CT_POLICY_EVAL_CTX *ctx, - CTLOG_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) -{ - ctx->epoch_time_in_ms = time_in_ms; -} - -X509* CT_POLICY_EVAL_CTX_get0_cert(const CT_POLICY_EVAL_CTX *ctx) -{ - return ctx->cert; -} - -X509* CT_POLICY_EVAL_CTX_get0_issuer(const CT_POLICY_EVAL_CTX *ctx) -{ - return ctx->issuer; -} - -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) -{ - return ctx->epoch_time_in_ms; -} + +/* + * Number of seconds in the future that an SCT timestamp can be, by default, + * without being considered invalid. This is added to time() when setting a + * default value for CT_POLICY_EVAL_CTX.epoch_time_in_ms. + * It can be overridden by calling CT_POLICY_EVAL_CTX_set_time(). + */ +static const time_t SCT_CLOCK_DRIFT_TOLERANCE = 300; + +CT_POLICY_EVAL_CTX *CT_POLICY_EVAL_CTX_new(void) +{ + 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; + } + + /* 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; +} + +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); +} + +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; +} + +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; +} + +void CT_POLICY_EVAL_CTX_set_shared_CTLOG_STORE(CT_POLICY_EVAL_CTX *ctx, + CTLOG_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) +{ + ctx->epoch_time_in_ms = time_in_ms; +} + +X509* CT_POLICY_EVAL_CTX_get0_cert(const CT_POLICY_EVAL_CTX *ctx) +{ + return ctx->cert; +} + +X509* CT_POLICY_EVAL_CTX_get0_issuer(const CT_POLICY_EVAL_CTX *ctx) +{ + return ctx->issuer; +} + +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) +{ + return ctx->epoch_time_in_ms; +} diff --git a/contrib/libs/openssl/crypto/ct/ct_prn.c b/contrib/libs/openssl/crypto/ct/ct_prn.c index e6584b57f3..756de984af 100644 --- a/contrib/libs/openssl/crypto/ct/ct_prn.c +++ b/contrib/libs/openssl/crypto/ct/ct_prn.c @@ -1,127 +1,127 @@ -/* - * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifdef OPENSSL_NO_CT -# error "CT is disabled" -#endif - -#include <openssl/asn1.h> -#include <openssl/bio.h> - +/* + * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifdef OPENSSL_NO_CT +# error "CT is disabled" +#endif + +#include <openssl/asn1.h> +#include <openssl/bio.h> + #include "ct_local.h" - -static void SCT_signature_algorithms_print(const SCT *sct, BIO *out) -{ - 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)); -} - -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); -} - -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"; -} - -void SCT_print(const SCT *sct, BIO *out, int indent, - const CTLOG_STORE *log_store) -{ - const CTLOG *log = NULL; - - 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, ""); - - 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)"); - - 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%*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%*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) -{ - 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); - - SCT_print(sct, out, indent, log_store); - if (i < sk_SCT_num(sct_list) - 1) - BIO_printf(out, "%s", separator); - } -} + +static void SCT_signature_algorithms_print(const SCT *sct, BIO *out) +{ + 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)); +} + +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); +} + +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"; +} + +void SCT_print(const SCT *sct, BIO *out, int indent, + const CTLOG_STORE *log_store) +{ + const CTLOG *log = NULL; + + 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, ""); + + 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)"); + + 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%*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%*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) +{ + 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); + + SCT_print(sct, out, indent, log_store); + if (i < sk_SCT_num(sct_list) - 1) + BIO_printf(out, "%s", separator); + } +} diff --git a/contrib/libs/openssl/crypto/ct/ct_sct.c b/contrib/libs/openssl/crypto/ct/ct_sct.c index 4ff36e2fbd..34d3e017e8 100644 --- a/contrib/libs/openssl/crypto/ct/ct_sct.c +++ b/contrib/libs/openssl/crypto/ct/ct_sct.c @@ -1,396 +1,396 @@ -/* - * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifdef OPENSSL_NO_CT -# error "CT disabled" -#endif - -#include <openssl/ct.h> -#include <openssl/err.h> -#include <openssl/evp.h> -#include <openssl/tls1.h> -#include <openssl/x509.h> - +/* + * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifdef OPENSSL_NO_CT +# error "CT disabled" +#endif + +#include <openssl/ct.h> +#include <openssl/err.h> +#include <openssl/evp.h> +#include <openssl/tls1.h> +#include <openssl/x509.h> + #include "ct_local.h" - -SCT *SCT_new(void) -{ - SCT *sct = OPENSSL_zalloc(sizeof(*sct)); - - 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; -} - -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); -} - -void SCT_LIST_free(STACK_OF(SCT) *a) -{ - sk_SCT_pop_free(a, SCT_free); -} - -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; -} - -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; -} - -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; -} - -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; -} - - -void SCT_set_timestamp(SCT *sct, uint64_t timestamp) -{ - sct->timestamp = timestamp; - sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET; -} - -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; - } -} - -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; -} - -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; -} - -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; -} - -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; -} - -sct_version_t SCT_get_version(const SCT *sct) -{ - return sct->version; -} - -ct_log_entry_type_t SCT_get_log_entry_type(const SCT *sct) -{ - return sct->entry_type; -} - -size_t SCT_get0_log_id(const SCT *sct, unsigned char **log_id) -{ - *log_id = sct->log_id; - return sct->log_id_len; -} - -uint64_t SCT_get_timestamp(const SCT *sct) -{ - return sct->timestamp; -} - -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; -} - -size_t SCT_get0_extensions(const SCT *sct, unsigned char **ext) -{ - *ext = sct->ext; - return sct->ext_len; -} - -size_t SCT_get0_signature(const SCT *sct, unsigned char **sig) -{ - *sig = sct->sig; - return sct->sig_len; -} - -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 */ - } -} - -int SCT_signature_is_complete(const SCT *sct) -{ - return SCT_get_signature_nid(sct) != NID_undef && - sct->sig != NULL && sct->sig_len > 0; -} - -sct_source_t SCT_get_source(const SCT *sct) -{ - return sct->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_validation_status_t SCT_get_validation_status(const SCT *sct) -{ - return sct->validation_status; -} - -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 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; - - for (i = 0; i < sct_count; ++i) { - int is_sct_valid = -1; - SCT *sct = sk_SCT_value(scts, i); - - 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; - } - - return are_scts_valid; -} + +SCT *SCT_new(void) +{ + SCT *sct = OPENSSL_zalloc(sizeof(*sct)); + + 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; +} + +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); +} + +void SCT_LIST_free(STACK_OF(SCT) *a) +{ + sk_SCT_pop_free(a, SCT_free); +} + +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; +} + +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; +} + +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; +} + +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; +} + + +void SCT_set_timestamp(SCT *sct, uint64_t timestamp) +{ + sct->timestamp = timestamp; + sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET; +} + +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; + } +} + +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; +} + +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; +} + +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; +} + +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; +} + +sct_version_t SCT_get_version(const SCT *sct) +{ + return sct->version; +} + +ct_log_entry_type_t SCT_get_log_entry_type(const SCT *sct) +{ + return sct->entry_type; +} + +size_t SCT_get0_log_id(const SCT *sct, unsigned char **log_id) +{ + *log_id = sct->log_id; + return sct->log_id_len; +} + +uint64_t SCT_get_timestamp(const SCT *sct) +{ + return sct->timestamp; +} + +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; +} + +size_t SCT_get0_extensions(const SCT *sct, unsigned char **ext) +{ + *ext = sct->ext; + return sct->ext_len; +} + +size_t SCT_get0_signature(const SCT *sct, unsigned char **sig) +{ + *sig = sct->sig; + return sct->sig_len; +} + +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 */ + } +} + +int SCT_signature_is_complete(const SCT *sct) +{ + return SCT_get_signature_nid(sct) != NID_undef && + sct->sig != NULL && sct->sig_len > 0; +} + +sct_source_t SCT_get_source(const SCT *sct) +{ + return sct->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_validation_status_t SCT_get_validation_status(const SCT *sct) +{ + return sct->validation_status; +} + +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 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; + + for (i = 0; i < sct_count; ++i) { + int is_sct_valid = -1; + SCT *sct = sk_SCT_value(scts, i); + + 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; + } + + return are_scts_valid; +} diff --git a/contrib/libs/openssl/crypto/ct/ct_sct_ctx.c b/contrib/libs/openssl/crypto/ct/ct_sct_ctx.c index 841e768033..f38358f468 100644 --- a/contrib/libs/openssl/crypto/ct/ct_sct_ctx.c +++ b/contrib/libs/openssl/crypto/ct/ct_sct_ctx.c @@ -1,263 +1,263 @@ -/* - * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifdef OPENSSL_NO_CT -# error "CT is disabled" -#endif - -#include <stddef.h> -#include <string.h> - -#include <openssl/err.h> -#include <openssl/obj_mac.h> -#include <openssl/x509.h> - +/* + * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifdef OPENSSL_NO_CT +# error "CT is disabled" +#endif + +#include <stddef.h> +#include <string.h> + +#include <openssl/err.h> +#include <openssl/obj_mac.h> +#include <openssl/x509.h> + #include "ct_local.h" - -SCT_CTX *SCT_CTX_new(void) -{ - SCT_CTX *sctx = OPENSSL_zalloc(sizeof(*sctx)); - - if (sctx == NULL) - CTerr(CT_F_SCT_CTX_NEW, ERR_R_MALLOC_FAILURE); - - return 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); -} - -/* - * Finds the index of the first extension with the given NID in cert. - * 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) -{ - 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; - - return ret; -} - -/* - * Modifies a certificate by deleting extensions and copying the issuer and - * AKID from the presigner certificate, if necessary. - * Returns 1 on success, 0 otherwise. - */ -__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 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; -} - -__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; - err: - OPENSSL_free(md); - OPENSSL_free(der); - return ret; -} - -int SCT_CTX_set1_issuer(SCT_CTX *sctx, const X509 *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) -{ - return ct_public_key_hash(pubkey, &sctx->ihash, &sctx->ihashlen); -} - -int SCT_CTX_set1_pubkey(SCT_CTX *sctx, X509_PUBKEY *pubkey) -{ - EVP_PKEY *pkey = X509_PUBKEY_get(pubkey); - - if (pkey == NULL) - 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; -} - -void SCT_CTX_set_time(SCT_CTX *sctx, uint64_t time_in_ms) -{ - sctx->epoch_time_in_ms = time_in_ms; -} + +SCT_CTX *SCT_CTX_new(void) +{ + SCT_CTX *sctx = OPENSSL_zalloc(sizeof(*sctx)); + + if (sctx == NULL) + CTerr(CT_F_SCT_CTX_NEW, ERR_R_MALLOC_FAILURE); + + return 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); +} + +/* + * Finds the index of the first extension with the given NID in cert. + * 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) +{ + 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; + + return ret; +} + +/* + * Modifies a certificate by deleting extensions and copying the issuer and + * AKID from the presigner certificate, if necessary. + * Returns 1 on success, 0 otherwise. + */ +__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 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; +} + +__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; + err: + OPENSSL_free(md); + OPENSSL_free(der); + return ret; +} + +int SCT_CTX_set1_issuer(SCT_CTX *sctx, const X509 *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) +{ + return ct_public_key_hash(pubkey, &sctx->ihash, &sctx->ihashlen); +} + +int SCT_CTX_set1_pubkey(SCT_CTX *sctx, X509_PUBKEY *pubkey) +{ + EVP_PKEY *pkey = X509_PUBKEY_get(pubkey); + + if (pkey == NULL) + 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; +} + +void SCT_CTX_set_time(SCT_CTX *sctx, uint64_t time_in_ms) +{ + sctx->epoch_time_in_ms = time_in_ms; +} diff --git a/contrib/libs/openssl/crypto/ct/ct_vfy.c b/contrib/libs/openssl/crypto/ct/ct_vfy.c index 74fd34f415..8cff22c8ee 100644 --- a/contrib/libs/openssl/crypto/ct/ct_vfy.c +++ b/contrib/libs/openssl/crypto/ct/ct_vfy.c @@ -1,140 +1,140 @@ -/* - * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include <string.h> - -#include <openssl/ct.h> -#include <openssl/err.h> -#include <openssl/evp.h> -#include <openssl/x509.h> - +/* + * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include <string.h> + +#include <openssl/ct.h> +#include <openssl/err.h> +#include <openssl/evp.h> +#include <openssl/x509.h> + #include "ct_local.h" - -typedef enum sct_signature_type_t { - 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) -{ - 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) -{ - 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; -} + +typedef enum sct_signature_type_t { + 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) +{ + 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) +{ + 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; +} diff --git a/contrib/libs/openssl/crypto/ct/ct_x509v3.c b/contrib/libs/openssl/crypto/ct/ct_x509v3.c index 19c2a852d2..a496dd6c5b 100644 --- a/contrib/libs/openssl/crypto/ct/ct_x509v3.c +++ b/contrib/libs/openssl/crypto/ct/ct_x509v3.c @@ -1,104 +1,104 @@ -/* - * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifdef OPENSSL_NO_CT -# error "CT is disabled" -#endif - +/* + * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifdef OPENSSL_NO_CT +# error "CT is disabled" +#endif + #include "ct_local.h" - -static char *i2s_poison(const X509V3_EXT_METHOD *method, void *val) -{ - return OPENSSL_strdup("NULL"); -} - -static void *s2i_poison(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, const char *str) -{ - return ASN1_NULL_new(); -} - -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; -} - -static int set_sct_list_source(STACK_OF(SCT) *s, sct_source_t source) -{ - 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); - - 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) -{ - 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; -} - -static STACK_OF(SCT) *ocsp_ext_d2i_SCT_LIST(STACK_OF(SCT) **a, - const unsigned char **pp, - long 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; -} - -/* 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 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 }, -}; + +static char *i2s_poison(const X509V3_EXT_METHOD *method, void *val) +{ + return OPENSSL_strdup("NULL"); +} + +static void *s2i_poison(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, const char *str) +{ + return ASN1_NULL_new(); +} + +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; +} + +static int set_sct_list_source(STACK_OF(SCT) *s, sct_source_t source) +{ + 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); + + 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) +{ + 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; +} + +static STACK_OF(SCT) *ocsp_ext_d2i_SCT_LIST(STACK_OF(SCT) **a, + const unsigned char **pp, + long 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; +} + +/* 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 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 }, +}; |