mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
Upgrade openssl from 1.1.0e to 1.1.1b, with source code. 4.0.78
This commit is contained in:
parent
8f1c992379
commit
96dbd7bced
1476 changed files with 616554 additions and 4 deletions
3
trunk/3rdparty/openssl-1.1-fit/crypto/ct/build.info
vendored
Normal file
3
trunk/3rdparty/openssl-1.1-fit/crypto/ct/build.info
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
LIBS=../../libcrypto
|
||||
SOURCE[../../libcrypto]= ct_b64.c ct_err.c ct_log.c ct_oct.c ct_policy.c \
|
||||
ct_prn.c ct_sct.c ct_sct_ctx.c ct_vfy.c ct_x509v3.c
|
168
trunk/3rdparty/openssl-1.1-fit/crypto/ct/ct_b64.c
vendored
Normal file
168
trunk/3rdparty/openssl-1.1-fit/crypto/ct/ct_b64.c
vendored
Normal file
|
@ -0,0 +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>
|
||||
|
||||
#include "ct_locl.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;
|
||||
}
|
96
trunk/3rdparty/openssl-1.1-fit/crypto/ct/ct_err.c
vendored
Normal file
96
trunk/3rdparty/openssl-1.1-fit/crypto/ct/ct_err.c
vendored
Normal file
|
@ -0,0 +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;
|
||||
}
|
216
trunk/3rdparty/openssl-1.1-fit/crypto/ct/ct_locl.h
vendored
Normal file
216
trunk/3rdparty/openssl-1.1-fit/crypto/ct/ct_locl.h
vendored
Normal file
|
@ -0,0 +1,216 @@
|
|||
/*
|
||||
* Copyright 2015-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 <stddef.h>
|
||||
#include <openssl/ct.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/x509v3.h>
|
||||
#include <openssl/safestack.h>
|
||||
|
||||
/*
|
||||
* From RFC6962: opaque SerializedSCT<1..2^16-1>; struct { SerializedSCT
|
||||
* sct_list <1..2^16-1>; } SignedCertificateTimestampList;
|
||||
*/
|
||||
# define MAX_SCT_SIZE 65535
|
||||
# define MAX_SCT_LIST_SIZE MAX_SCT_SIZE
|
||||
|
||||
/*
|
||||
* Macros to read and write integers in network-byte order.
|
||||
*/
|
||||
|
||||
#define n2s(c,s) ((s=(((unsigned int)((c)[0]))<< 8)| \
|
||||
(((unsigned int)((c)[1])) )),c+=2)
|
||||
|
||||
#define s2n(s,c) ((c[0]=(unsigned char)(((s)>> 8)&0xff), \
|
||||
c[1]=(unsigned char)(((s) )&0xff)),c+=2)
|
||||
|
||||
#define l2n3(l,c) ((c[0]=(unsigned char)(((l)>>16)&0xff), \
|
||||
c[1]=(unsigned char)(((l)>> 8)&0xff), \
|
||||
c[2]=(unsigned char)(((l) )&0xff)),c+=3)
|
||||
|
||||
#define n2l8(c,l) (l =((uint64_t)(*((c)++)))<<56, \
|
||||
l|=((uint64_t)(*((c)++)))<<48, \
|
||||
l|=((uint64_t)(*((c)++)))<<40, \
|
||||
l|=((uint64_t)(*((c)++)))<<32, \
|
||||
l|=((uint64_t)(*((c)++)))<<24, \
|
||||
l|=((uint64_t)(*((c)++)))<<16, \
|
||||
l|=((uint64_t)(*((c)++)))<< 8, \
|
||||
l|=((uint64_t)(*((c)++))))
|
||||
|
||||
#define l2n8(l,c) (*((c)++)=(unsigned char)(((l)>>56)&0xff), \
|
||||
*((c)++)=(unsigned char)(((l)>>48)&0xff), \
|
||||
*((c)++)=(unsigned char)(((l)>>40)&0xff), \
|
||||
*((c)++)=(unsigned char)(((l)>>32)&0xff), \
|
||||
*((c)++)=(unsigned char)(((l)>>24)&0xff), \
|
||||
*((c)++)=(unsigned char)(((l)>>16)&0xff), \
|
||||
*((c)++)=(unsigned char)(((l)>> 8)&0xff), \
|
||||
*((c)++)=(unsigned char)(((l) )&0xff))
|
||||
|
||||
/* Signed Certificate Timestamp */
|
||||
struct sct_st {
|
||||
sct_version_t version;
|
||||
/* If version is not SCT_VERSION_V1, this contains the encoded SCT */
|
||||
unsigned char *sct;
|
||||
size_t sct_len;
|
||||
/* If version is SCT_VERSION_V1, fields below contain components of the SCT */
|
||||
unsigned char *log_id;
|
||||
size_t log_id_len;
|
||||
/*
|
||||
* Note, we cannot distinguish between an unset timestamp, and one
|
||||
* that is set to 0. However since CT didn't exist in 1970, no real
|
||||
* SCT should ever be set as such.
|
||||
*/
|
||||
uint64_t timestamp;
|
||||
unsigned char *ext;
|
||||
size_t ext_len;
|
||||
unsigned char hash_alg;
|
||||
unsigned char sig_alg;
|
||||
unsigned char *sig;
|
||||
size_t sig_len;
|
||||
/* Log entry type */
|
||||
ct_log_entry_type_t entry_type;
|
||||
/* Where this SCT was found, e.g. certificate, OCSP response, etc. */
|
||||
sct_source_t source;
|
||||
/* The result of the last attempt to validate this SCT. */
|
||||
sct_validation_status_t validation_status;
|
||||
};
|
||||
|
||||
/* Miscellaneous data that is useful when verifying an SCT */
|
||||
struct sct_ctx_st {
|
||||
/* Public key */
|
||||
EVP_PKEY *pkey;
|
||||
/* Hash of public key */
|
||||
unsigned char *pkeyhash;
|
||||
size_t pkeyhashlen;
|
||||
/* For pre-certificate: issuer public key hash */
|
||||
unsigned char *ihash;
|
||||
size_t ihashlen;
|
||||
/* certificate encoding */
|
||||
unsigned char *certder;
|
||||
size_t certderlen;
|
||||
/* pre-certificate encoding */
|
||||
unsigned char *preder;
|
||||
size_t prederlen;
|
||||
/* milliseconds since epoch (to check that the SCT isn't from the future) */
|
||||
uint64_t epoch_time_in_ms;
|
||||
};
|
||||
|
||||
/* Context when evaluating whether a Certificate Transparency policy is met */
|
||||
struct ct_policy_eval_ctx_st {
|
||||
X509 *cert;
|
||||
X509 *issuer;
|
||||
CTLOG_STORE *log_store;
|
||||
/* milliseconds since epoch (to check that SCTs aren't from the future) */
|
||||
uint64_t epoch_time_in_ms;
|
||||
};
|
||||
|
||||
/*
|
||||
* Creates a new context for verifying an SCT.
|
||||
*/
|
||||
SCT_CTX *SCT_CTX_new(void);
|
||||
/*
|
||||
* Deletes an SCT verification context.
|
||||
*/
|
||||
void SCT_CTX_free(SCT_CTX *sctx);
|
||||
|
||||
/*
|
||||
* Sets the certificate that the SCT was created for.
|
||||
* If *cert does not have a poison extension, presigner must be NULL.
|
||||
* If *cert does not have a poison extension, it may have a single SCT
|
||||
* (NID_ct_precert_scts) extension.
|
||||
* If either *cert or *presigner have an AKID (NID_authority_key_identifier)
|
||||
* extension, both must have one.
|
||||
* Returns 1 on success, 0 on failure.
|
||||
*/
|
||||
__owur int SCT_CTX_set1_cert(SCT_CTX *sctx, X509 *cert, X509 *presigner);
|
||||
|
||||
/*
|
||||
* Sets the issuer of the certificate that the SCT was created for.
|
||||
* This is just a convenience method to save extracting the public key and
|
||||
* calling SCT_CTX_set1_issuer_pubkey().
|
||||
* Issuer must not be NULL.
|
||||
* Returns 1 on success, 0 on failure.
|
||||
*/
|
||||
__owur int SCT_CTX_set1_issuer(SCT_CTX *sctx, const X509 *issuer);
|
||||
|
||||
/*
|
||||
* Sets the public key of the issuer of the certificate that the SCT was created
|
||||
* for.
|
||||
* The public key must not be NULL.
|
||||
* Returns 1 on success, 0 on failure.
|
||||
*/
|
||||
__owur int SCT_CTX_set1_issuer_pubkey(SCT_CTX *sctx, X509_PUBKEY *pubkey);
|
||||
|
||||
/*
|
||||
* Sets the public key of the CT log that the SCT is from.
|
||||
* Returns 1 on success, 0 on failure.
|
||||
*/
|
||||
__owur int SCT_CTX_set1_pubkey(SCT_CTX *sctx, X509_PUBKEY *pubkey);
|
||||
|
||||
/*
|
||||
* Sets the time to evaluate the SCT against, in milliseconds since the Unix
|
||||
* epoch. If the SCT's timestamp is after this time, it will be interpreted as
|
||||
* having been issued in the future. RFC6962 states that "TLS clients MUST
|
||||
* reject SCTs whose timestamp is in the future", so an SCT will not validate
|
||||
* in this case.
|
||||
*/
|
||||
void SCT_CTX_set_time(SCT_CTX *sctx, uint64_t time_in_ms);
|
||||
|
||||
/*
|
||||
* Verifies an SCT with the given context.
|
||||
* Returns 1 if the SCT verifies successfully; any other value indicates
|
||||
* failure. See EVP_DigestVerifyFinal() for the meaning of those values.
|
||||
*/
|
||||
__owur int SCT_CTX_verify(const SCT_CTX *sctx, const SCT *sct);
|
||||
|
||||
/*
|
||||
* Does this SCT have the minimum fields populated to be usable?
|
||||
* Returns 1 if so, 0 otherwise.
|
||||
*/
|
||||
__owur int SCT_is_complete(const SCT *sct);
|
||||
|
||||
/*
|
||||
* Does this SCT have the signature-related fields populated?
|
||||
* Returns 1 if so, 0 otherwise.
|
||||
* This checks that the signature and hash algorithms are set to supported
|
||||
* values and that the signature field is set.
|
||||
*/
|
||||
__owur int SCT_signature_is_complete(const SCT *sct);
|
||||
|
||||
/*
|
||||
* TODO(RJPercival): Create an SCT_signature struct and make i2o_SCT_signature
|
||||
* and o2i_SCT_signature conform to the i2d/d2i conventions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Serialize (to TLS format) an |sct| signature and write it to |out|.
|
||||
* If |out| is null, no signature will be output but the length will be returned.
|
||||
* If |out| points to a null pointer, a string will be allocated to hold the
|
||||
* TLS-format signature. It is the responsibility of the caller to free it.
|
||||
* If |out| points to an allocated string, the signature will be written to it.
|
||||
* The length of the signature in TLS format will be returned.
|
||||
*/
|
||||
__owur int i2o_SCT_signature(const SCT *sct, unsigned char **out);
|
||||
|
||||
/*
|
||||
* Parses an SCT signature in TLS format and populates the |sct| with it.
|
||||
* |in| should be a pointer to a string containing the TLS-format signature.
|
||||
* |in| will be advanced to the end of the signature if parsing succeeds.
|
||||
* |len| should be the length of the signature in |in|.
|
||||
* Returns the number of bytes parsed, or a negative integer if an error occurs.
|
||||
* If an error occurs, the SCT's signature NID may be updated whilst the
|
||||
* signature field itself remains unset.
|
||||
*/
|
||||
__owur int o2i_SCT_signature(SCT *sct, const unsigned char **in, size_t len);
|
||||
|
||||
/*
|
||||
* Handlers for Certificate Transparency X509v3/OCSP extensions
|
||||
*/
|
||||
extern const X509V3_EXT_METHOD v3_ct_scts[3];
|
306
trunk/3rdparty/openssl-1.1-fit/crypto/ct/ct_log.c
vendored
Normal file
306
trunk/3rdparty/openssl-1.1-fit/crypto/ct/ct_log.c
vendored
Normal file
|
@ -0,0 +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;
|
||||
}
|
407
trunk/3rdparty/openssl-1.1-fit/crypto/ct/ct_oct.c
vendored
Normal file
407
trunk/3rdparty/openssl-1.1-fit/crypto/ct/ct_oct.c
vendored
Normal file
|
@ -0,0 +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>
|
||||
|
||||
#include "ct_locl.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;
|
||||
}
|
98
trunk/3rdparty/openssl-1.1-fit/crypto/ct/ct_policy.c
vendored
Normal file
98
trunk/3rdparty/openssl-1.1-fit/crypto/ct/ct_policy.c
vendored
Normal file
|
@ -0,0 +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>
|
||||
|
||||
#include "ct_locl.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;
|
||||
}
|
127
trunk/3rdparty/openssl-1.1-fit/crypto/ct/ct_prn.c
vendored
Normal file
127
trunk/3rdparty/openssl-1.1-fit/crypto/ct/ct_prn.c
vendored
Normal file
|
@ -0,0 +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>
|
||||
|
||||
#include "ct_locl.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);
|
||||
}
|
||||
}
|
396
trunk/3rdparty/openssl-1.1-fit/crypto/ct/ct_sct.c
vendored
Normal file
396
trunk/3rdparty/openssl-1.1-fit/crypto/ct/ct_sct.c
vendored
Normal file
|
@ -0,0 +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>
|
||||
|
||||
#include "ct_locl.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;
|
||||
}
|
263
trunk/3rdparty/openssl-1.1-fit/crypto/ct/ct_sct_ctx.c
vendored
Normal file
263
trunk/3rdparty/openssl-1.1-fit/crypto/ct/ct_sct_ctx.c
vendored
Normal file
|
@ -0,0 +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>
|
||||
|
||||
#include "ct_locl.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;
|
||||
}
|
140
trunk/3rdparty/openssl-1.1-fit/crypto/ct/ct_vfy.c
vendored
Normal file
140
trunk/3rdparty/openssl-1.1-fit/crypto/ct/ct_vfy.c
vendored
Normal file
|
@ -0,0 +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>
|
||||
|
||||
#include "ct_locl.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;
|
||||
}
|
104
trunk/3rdparty/openssl-1.1-fit/crypto/ct/ct_x509v3.c
vendored
Normal file
104
trunk/3rdparty/openssl-1.1-fit/crypto/ct/ct_x509v3.c
vendored
Normal file
|
@ -0,0 +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
|
||||
|
||||
#include "ct_locl.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 },
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue