Merge pull request #2210 from JacobBarthelmeh/Compatibility-Layer-Part2

JSSE additions
pull/2222/head
toddouska 2019-04-24 11:04:05 -07:00 committed by GitHub
commit 547c09e1d7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 538 additions and 67 deletions

View File

@ -3317,6 +3317,16 @@ then
then
ENABLED_PSK="yes"
fi
if test "x$ENABLED_CERTEXT" = "xno"
then
ENABLED_CERTEXT="yes"
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_CERT_EXT"
fi
if test "x$ENABLED_CERTGEN" = "xno"
then
ENABLED_CERTGEN="yes"
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_CERT_GEN"
fi
fi
# lighty Support

View File

@ -2815,6 +2815,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
showPeerEx(ssl, lng_index);
#ifdef OPENSSL_EXTRA
printf("Session timeout set to %ld seconds\n", wolfSSL_get_timeout(ssl));
{
byte* rnd;
byte* pt;

View File

@ -16033,6 +16033,27 @@ void SetErrorString(int error, char* str)
static const CipherSuiteInfo cipher_names[] =
{
#ifdef BUILD_TLS_AES_128_GCM_SHA256
SUITE_INFO("TLS13-AES128-GCM-SHA256","TLS_AES_128_GCM_SHA256",TLS13_BYTE,TLS_AES_128_GCM_SHA256),
#endif
#ifdef BUILD_TLS_AES_256_GCM_SHA384
SUITE_INFO("TLS13-AES256-GCM-SHA384","TLS_AES_256_GCM_SHA384",TLS13_BYTE,TLS_AES_256_GCM_SHA384),
#endif
#ifdef BUILD_TLS_CHACHA20_POLY1305_SHA256
SUITE_INFO("TLS13-CHACHA20-POLY1305-SHA256","TLS_CHACHA20_POLY1305_SHA256",TLS13_BYTE,TLS_CHACHA20_POLY1305_SHA256),
#endif
#ifdef BUILD_TLS_AES_128_CCM_SHA256
SUITE_INFO("TLS13-AES128-CCM-SHA256","TLS_AES_128_CCM_SHA256",TLS13_BYTE,TLS_AES_128_CCM_SHA256),
#endif
#ifdef BUILD_TLS_AES_128_CCM_8_SHA256
SUITE_INFO("TLS13-AES128-CCM-8-SHA256","TLS_AES_128_CCM_8_SHA256",TLS13_BYTE,TLS_AES_128_CCM_8_SHA256),
#endif
#ifndef WOLFSSL_NO_TLS12
#ifdef BUILD_SSL_RSA_WITH_RC4_128_SHA
@ -16484,26 +16505,6 @@ static const CipherSuiteInfo cipher_names[] =
#endif
#endif /* WOLFSSL_NO_TLS12 */
#ifdef BUILD_TLS_AES_128_GCM_SHA256
SUITE_INFO("TLS13-AES128-GCM-SHA256","TLS_AES_128_GCM_SHA256",TLS13_BYTE,TLS_AES_128_GCM_SHA256),
#endif
#ifdef BUILD_TLS_AES_256_GCM_SHA384
SUITE_INFO("TLS13-AES256-GCM-SHA384","TLS_AES_256_GCM_SHA384",TLS13_BYTE,TLS_AES_256_GCM_SHA384),
#endif
#ifdef BUILD_TLS_CHACHA20_POLY1305_SHA256
SUITE_INFO("TLS13-CHACHA20-POLY1305-SHA256","TLS_CHACHA20_POLY1305_SHA256",TLS13_BYTE,TLS_CHACHA20_POLY1305_SHA256),
#endif
#ifdef BUILD_TLS_AES_128_CCM_SHA256
SUITE_INFO("TLS13-AES128-CCM-SHA256","TLS_AES_128_CCM_SHA256",TLS13_BYTE,TLS_AES_128_CCM_SHA256),
#endif
#ifdef BUILD_TLS_AES_128_CCM_8_SHA256
SUITE_INFO("TLS13-AES128-CCM-8-SHA256","TLS_AES_128_CCM_8_SHA256",TLS13_BYTE,TLS_AES_128_CCM_8_SHA256),
#endif
};
@ -16636,7 +16637,11 @@ int SetCipherList(WOLFSSL_CTX* ctx, Suites* suites, const char* list)
name[(length == sizeof(name)) ? length - 1 : length] = 0;
for (i = 0; i < suiteSz; i++) {
if (XSTRNCMP(name, cipher_names[i].name, sizeof(name)) == 0) {
if (XSTRNCMP(name, cipher_names[i].name, sizeof(name)) == 0
#ifndef NO_ERROR_STRINGS
|| XSTRNCMP(name, cipher_names[i].name_iana, sizeof(name)) == 0
#endif
) {
#ifdef WOLFSSL_DTLS
/* don't allow stream ciphers with DTLS */
if (ctx->method->version.major == DTLS_MAJOR) {
@ -16656,29 +16661,12 @@ int SetCipherList(WOLFSSL_CTX* ctx, Suites* suites, const char* list)
return 0; /* suites buffer not large enough, error out */
}
suites->suites[idx++] =
#ifdef WOLFSSL_TLS13
(XSTRSTR(name, "TLS13")) ? TLS13_BYTE :
#endif
#ifdef HAVE_CHACHA
(XSTRSTR(name, "CHACHA")) ? CHACHA_BYTE :
#endif
#ifdef HAVE_QSH
(XSTRSTR(name, "QSH")) ? QSH_BYTE :
#endif
#if defined(HAVE_ECC) || defined(HAVE_CURVE25519)
(XSTRSTR(name, "EC")) ? ECC_BYTE :
#endif
#ifdef HAVE_AESCCM
(XSTRSTR(name, "CCM")) ? ECC_BYTE :
#endif
CIPHER_BYTE; /* normal */
suites->suites[idx++] = cipher_names[i].cipherSuite0;
suites->suites[idx++] = cipher_names[i].cipherSuite;
/* The suites are either ECDSA, RSA, PSK, or Anon. The RSA
* suites don't necessarily have RSA in the name. */
#ifdef WOLFSSL_TLS13
if (XSTRSTR(name, "TLS13")) {
if (cipher_names[i].cipherSuite0 == TLS13_BYTE) {
#ifndef NO_RSA
haveRSAsig = 1;
#endif
@ -17869,6 +17857,30 @@ exit_dpk:
return ret;
}
#ifdef WOLFSSL_TLS13
/* returns 1 if able to do TLS 1.3 otherwise 0 */
static int TLSv1_3_Capable(WOLFSSL* ssl)
{
#ifndef WOLFSSL_TLS13
return 0;
#else
int ret = 0;
if (IsAtLeastTLSv1_3(ssl->ctx->method->version)) {
ret = 1;
}
#ifdef OPENSSL_EXTRA
if ((wolfSSL_get_options(ssl) & SSL_OP_NO_TLSv1_3)) {
/* option set at run time to disable TLS 1.3 */
ret = 0;
}
#endif
return ret;
#endif
}
#endif /* WOLFSSL_TLS13 */
int CompleteServerHello(WOLFSSL* ssl)
{
int ret;
@ -17878,7 +17890,7 @@ exit_dpk:
TLS13_DOWNGRADE_SZ - 1;
byte vers = ssl->arrays->serverRandom[RAN_LEN - 1];
#ifdef WOLFSSL_TLS13
if (IsAtLeastTLSv1_3(ssl->ctx->method->version)) {
if (TLSv1_3_Capable(ssl)) {
/* TLS v1.3 capable client not allowed to downgrade when
* connecting to TLS v1.3 capable server unless cipher suite
* demands it.

269
src/ssl.c
View File

@ -720,6 +720,41 @@ int wolfSSL_get_ciphers(char* buf, int len)
return WOLFSSL_SUCCESS;
}
#ifndef NO_ERROR_STRINGS
/* places a list of all supported cipher suites in TLS_* format into "buf"
* return WOLFSSL_SUCCESS on success */
int wolfSSL_get_ciphers_iana(char* buf, int len)
{
const CipherSuiteInfo* ciphers = GetCipherNames();
int ciphersSz = GetCipherNamesSize();
int i;
int cipherNameSz;
if (buf == NULL || len <= 0)
return BAD_FUNC_ARG;
/* Add each member to the buffer delimited by a : */
for (i = 0; i < ciphersSz; i++) {
cipherNameSz = (int)XSTRLEN(ciphers[i].name_iana);
if (cipherNameSz + 1 < len) {
XSTRNCPY(buf, ciphers[i].name_iana, len);
buf += cipherNameSz;
if (i < ciphersSz - 1)
*buf++ = ':';
*buf = 0;
len -= cipherNameSz + 1;
}
else
return BUFFER_E;
}
return WOLFSSL_SUCCESS;
}
#endif /* NO_ERROR_STRINGS */
const char* wolfSSL_get_shared_ciphers(WOLFSSL* ssl, char* buf, int len)
{
const char* cipher;
@ -15318,7 +15353,8 @@ WOLFSSL_X509* wolfSSL_X509_d2i(WOLFSSL_X509** x509, const byte* in, int len)
unsigned char* buf, int* bufSz)
{
WOLFSSL_ENTER("wolfSSL_X509_get_signature");
if (x509 == NULL || bufSz == NULL || *bufSz < (int)x509->sig.length)
if (x509 == NULL || bufSz == NULL || (*bufSz < (int)x509->sig.length &&
buf != NULL))
return WOLFSSL_FATAL_ERROR;
if (buf != NULL)
@ -15329,6 +15365,91 @@ WOLFSSL_X509* wolfSSL_X509_d2i(WOLFSSL_X509** x509, const byte* in, int len)
}
/* Getter function that copies over the DER public key buffer to "buf" and
* sets the size in bufSz. If "buf" is NULL then just bufSz is set to needed
* buffer size. "bufSz" passed in should initially be set by the user to be
* the size of "buf". This gets checked to make sure the buffer is large
* enough to hold the public key.
*
* Note: this is the X.509 form of key with "header" info.
* return WOLFSSL_SUCCESS on success
*/
int wolfSSL_X509_get_pubkey_buffer(WOLFSSL_X509* x509,
unsigned char* buf, int* bufSz)
{
#ifdef WOLFSSL_SMALL_STACK
DecodedCert* cert;
#else
DecodedCert cert[1];
#endif
word32 idx;
const byte* der;
int length = 0;
int ret, derSz = 0;
int badDate = 0;
const byte* pubKeyX509 = NULL;
int pubKeyX509Sz = 0;
WOLFSSL_ENTER("wolfSSL_X509_get_pubkey_buffer");
if (x509 == NULL || bufSz == NULL) {
WOLFSSL_LEAVE("wolfSSL_X509_get_pubkey_buffer", BAD_FUNC_ARG);
return WOLFSSL_FATAL_ERROR;
}
#ifdef WOLFSSL_SMALL_STACK
cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert),
x509->heap, DYNAMIC_TYPE_TMP_BUFFER);
if (cert == NULL) {
WOLFSSL_LEAVE("wolfSSL_X509_get_pubkey_buffer", MEMORY_E);
return WOLFSSL_FATAL_ERROR;
}
#endif
der = wolfSSL_X509_get_der(x509, &derSz);
InitDecodedCert(cert, der, derSz, NULL);
ret = wc_GetPubX509(cert, 0, &badDate);
if (ret >= 0) {
idx = cert->srcIdx;
pubKeyX509 = cert->source + cert->srcIdx;
ret = GetSequence(cert->source, &cert->srcIdx, &length,
cert->maxIdx);
pubKeyX509Sz = length + (cert->srcIdx - idx);
}
FreeDecodedCert(cert);
#ifdef WOLFSSL_SMALL_STACK
XFREE(cert, x509->heap, DYNAMIC_TYPE_TMP_BUFFER);
#endif
if (ret < 0) {
WOLFSSL_LEAVE("wolfSSL_X509_get_pubkey_buffer", ret);
return WOLFSSL_FATAL_ERROR;
}
if (buf != NULL) {
if (pubKeyX509Sz > *bufSz) {
WOLFSSL_LEAVE("wolfSSL_X509_get_pubkey_buffer", BUFFER_E);
return WOLFSSL_FATAL_ERROR;
}
XMEMCPY(buf, pubKeyX509, pubKeyX509Sz);
}
*bufSz = pubKeyX509Sz;
return WOLFSSL_SUCCESS;
}
/* Getter function for the public key OID value
* return public key OID stored in WOLFSSL_X509 structure */
int wolfSSL_X509_get_pubkey_type(WOLFSSL_X509* x509)
{
if (x509 == NULL)
return WOLFSSL_FAILURE;
return x509->pubKeyOID;
}
/* write X509 serial number in unsigned binary to buffer
buffer needs to be at least EXTERNAL_SERIAL_SIZE (32) for all cases
return WOLFSSL_SUCCESS on success */
@ -15359,6 +15480,40 @@ WOLFSSL_X509* wolfSSL_X509_d2i(WOLFSSL_X509** x509, const byte* in, int len)
}
/* get the buffer to be signed (tbs) from the WOLFSSL_X509 certificate
*
* outSz : gets set to the size of the buffer
* returns a pointer to the internal buffer at the location of TBS on
* on success and NULL on failure.
*/
const unsigned char* wolfSSL_X509_get_tbs(WOLFSSL_X509* x509, int* outSz)
{
int sz = 0, len;
unsigned int idx = 0, tmpIdx;
const unsigned char* der = NULL;
const unsigned char* tbs = NULL;
if (x509 == NULL || outSz == NULL) {
return NULL;
}
der = wolfSSL_X509_get_der(x509, &sz);
if (der == NULL) {
return NULL;
}
if (GetSequence(der, &idx, &len, sz) < 0) {
return NULL;
}
tbs = der + idx;
tmpIdx = idx;
if (GetSequence(der, &idx, &len, sz) < 0) {
return NULL;
}
*outSz = len + (idx - tmpIdx);
return tbs;
}
int wolfSSL_X509_version(WOLFSSL_X509* x509)
{
WOLFSSL_ENTER("wolfSSL_X509_version");
@ -16643,6 +16798,7 @@ WOLFSSL_EVP_PKEY* wolfSSL_X509_get_pubkey(WOLFSSL_X509* x509)
case AUTH_KEY_OID: isSet = x509->authKeyIdSet; break;
case SUBJ_KEY_OID: isSet = x509->subjKeyIdSet; break;
case KEY_USAGE_OID: isSet = x509->keyUsageSet; break;
case CRL_DIST_OID: isSet = x509->CRLdistSet; break;
#ifdef WOLFSSL_SEP
case CERT_POLICY_OID: isSet = x509->certPolicySet; break;
#endif /* WOLFSSL_SEP */
@ -16668,6 +16824,7 @@ WOLFSSL_EVP_PKEY* wolfSSL_X509_get_pubkey(WOLFSSL_X509* x509)
case AUTH_KEY_OID: crit = x509->authKeyIdCrit; break;
case SUBJ_KEY_OID: crit = x509->subjKeyIdCrit; break;
case KEY_USAGE_OID: crit = x509->keyUsageCrit; break;
case CRL_DIST_OID: crit= x509->CRLdistCrit; break;
#ifdef WOLFSSL_SEP
case CERT_POLICY_OID: crit = x509->certPolicyCrit; break;
#endif /* WOLFSSL_SEP */
@ -19113,6 +19270,53 @@ int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx)
}
return WOLFSSL_FATAL_ERROR;
}
/* Use the public key to verify the signature. Note: this only verifies
* the certificate signature.
* returns WOLFSSL_SUCCESS on successful signature verification */
int wolfSSL_X509_verify(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey)
{
int ret;
const byte* der;
int derSz = 0;
int type;
if (x509 == NULL || pkey == NULL) {
return WOLFSSL_FATAL_ERROR;
}
der = wolfSSL_X509_get_der(x509, &derSz);
if (der == NULL) {
WOLFSSL_MSG("Error getting WOLFSSL_X509 DER");
return WOLFSSL_FATAL_ERROR;
}
switch (pkey->type) {
case EVP_PKEY_RSA:
type = RSAk;
break;
case EVP_PKEY_EC:
type = ECDSAk;
break;
case EVP_PKEY_DSA:
type = DSAk;
break;
default:
WOLFSSL_MSG("Unknown pkey key type");
return WOLFSSL_FATAL_ERROR;
}
ret = CheckCertSignaturePubKey(der, derSz, x509->heap,
(unsigned char*)pkey->pkey.ptr, pkey->pkey_sz, type);
if (ret == 0) {
return WOLFSSL_SUCCESS;
}
return WOLFSSL_FAILURE;
}
#endif /* NO_CERTS */
#if !defined(NO_FILESYSTEM)
@ -31278,8 +31482,8 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl)
{ KEY_USAGE_OID, KEY_USAGE_OID, oidCertExtType, "X509 key usage" },
{ INHIBIT_ANY_OID, INHIBIT_ANY_OID, oidCertExtType,
"X509 inhibit any" },
{ NID_ext_key_usage, KEY_USAGE_OID, oidCertExtType,
"X509 ext key usage" },
{ NID_key_usage, KEY_USAGE_OID, oidCertExtType,
"X509 key usage" },
{ NID_name_constraints, NAME_CONS_OID, oidCertExtType,
"X509 name constraints" },
{ NID_certificate_policies, CERT_POLICY_OID, oidCertExtType,
@ -32016,7 +32220,7 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl)
case INHIBIT_ANY_OID:
return INHIBIT_ANY_OID;
case KEY_USAGE_OID:
return NID_ext_key_usage;
return NID_key_usage;
case NAME_CONS_OID:
return NID_name_constraints;
case CERT_POLICY_OID:
@ -32173,15 +32377,47 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl)
}
#endif
#ifndef NO_WOLFSSL_STUB
#ifdef WOLFSSL_CERT_EXT
/* Gets the NID value that is related to the OID string passed in. Example
* string would be "2.5.29.14" for subject key ID.
*
* @TODO does not handle short names yet
*
* returns NID value on success and NID_undef on error
*/
int wolfSSL_OBJ_txt2nid(const char* s)
{
(void)s;
WOLFSSL_STUB("OBJ_txt2nid");
int ret;
unsigned int outSz = MAX_OID_SZ;
unsigned char out[MAX_OID_SZ];
return 0;
WOLFSSL_ENTER("OBJ_txt2nid");
if (s == NULL) {
return NID_undef;
}
ret = EncodePolicyOID(out, &outSz, s, NULL);
if (ret == 0) {
unsigned int i, sum = 0;
/* sum OID */
for (i = 0; i < outSz; i++) {
sum += out[i];
}
/* get the group that the OID's sum is in
* @TODO possible conflict with multiples */
for (i = 0; i < WOLFSSL_OBJECT_INFO_SZ; i++) {
if (wolfssl_object_info[i].id == (int)sum) {
return wolfssl_object_info[i].nid;
}
}
}
return NID_undef;
}
#endif
#endif /* WOLFSSL_CERT_EXT */
/* compatibility function. It's intended use is to remove OID's from an
* internal table that have been added with OBJ_create. wolfSSL manages it's
@ -33878,8 +34114,8 @@ WOLFSSL_CTX* wolfSSL_get_SSL_CTX(WOLFSSL* ssl)
}
#if defined(OPENSSL_ALL) || \
(defined(OPENSSL_EXTRA) && (defined(HAVE_STUNNEL) || \
defined(WOLFSSL_NGINX)) || defined(WOLFSSL_HAPROXY))
defined(OPENSSL_EXTRA) || defined(HAVE_STUNNEL) || \
defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
const byte* wolfSSL_SESSION_get_id(WOLFSSL_SESSION* sess, unsigned int* idLen)
{
@ -34450,6 +34686,17 @@ long wolfSSL_SSL_CTX_get_timeout(const WOLFSSL_CTX *ctx)
return ctx->timeout;
}
/* returns the time in seconds of the current timeout */
long wolfSSL_get_timeout(WOLFSSL* ssl)
{
WOLFSSL_ENTER("wolfSSL_get_timeout");
if (ssl == NULL)
return 0;
return ssl->timeout;
}
#ifdef HAVE_ECC
int wolfSSL_SSL_CTX_set_tmp_ecdh(WOLFSSL_CTX *ctx, WOLFSSL_EC_KEY *ecdh)
{

View File

@ -10755,6 +10755,31 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType,
}
#endif /* !WOLFSSL_NO_TLS12 */
#ifdef WOLFSSL_TLS13
/* Gets a WOLFSL_METHOD type that is not set as client or server
*
* Returns a pointer to a WOLFSSL_METHOD struct
*/
WOLFSSL_METHOD* wolfTLSv1_3_method(void)
{
return wolfTLSv1_3_method_ex(NULL);
}
WOLFSSL_METHOD* wolfTLSv1_3_method_ex(void* heap)
{
WOLFSSL_METHOD* m;
WOLFSSL_ENTER("TLSv1_3_method");
#ifndef NO_WOLFSSL_CLIENT
m = wolfTLSv1_3_client_method_ex(heap);
#else
m = wolfTLSv1_3_server_method_ex(heap);
#endif
if (m != NULL) {
m->side = WOLFSSL_NEITHER_END;
}
return m;
}
#endif /* WOLFSSL_TLS13 */
#ifdef WOLFSSL_DTLS
WOLFSSL_METHOD* wolfDTLS_method(void)
{

View File

@ -1486,6 +1486,30 @@ WOLFSSL_API void wolfSSL_CTX_SetIOSend(WOLFSSL_CTX *ctx, CallbackIOSend CBIOSend
}
/* sets the IO callback to use for receives at WOLFSSL level */
WOLFSSL_API void wolfSSL_SSLSetIORecv(WOLFSSL *ssl, CallbackIORecv CBIORecv)
{
if (ssl != NULL) {
ssl->CBIORecv = CBIORecv;
#ifdef OPENSSL_EXTRA
ssl->cbioFlag |= WOLFSSL_CBIO_RECV;
#endif
}
}
/* sets the IO callback to use for sends at WOLFSSL level */
WOLFSSL_API void wolfSSL_SSLSetIOSend(WOLFSSL *ssl, CallbackIOSend CBIOSend)
{
if (ssl != NULL) {
ssl->CBIOSend = CBIOSend;
#ifdef OPENSSL_EXTRA
ssl->cbioFlag |= WOLFSSL_CBIO_SEND;
#endif
}
}
WOLFSSL_API void wolfSSL_SetIOReadCtx(WOLFSSL* ssl, void *rctx)
{
ssl->IOCB_ReadCtx = rctx;

View File

@ -578,6 +578,9 @@ static void test_wolfSSL_Method_Allocators(void)
#ifndef WOLFSSL_NO_TLS12
TEST_VALID_METHOD_ALLOCATOR(wolfTLSv1_2_method);
#endif /* !WOLFSSL_NO_TLS12 */
#ifdef WOLFSSL_TLS13
TEST_VALID_METHOD_ALLOCATOR(wolfTLSv1_3_method);
#endif /* WOLFSSL_TLS13 */
#ifdef WOLFSSL_DTLS
TEST_VALID_METHOD_ALLOCATOR(wolfDTLS_method);
#ifndef NO_OLD_TLS
@ -4353,6 +4356,87 @@ static void test_wolfSSL_URI(void)
#endif
}
static void test_wolfSSL_TBS(void)
{
#if !defined(NO_CERTS) && !defined(NO_RSA) && !defined(NO_FILESYSTEM) \
&& defined(OPENSSL_EXTRA)
WOLFSSL_X509* x509;
const unsigned char* tbs;
int tbsSz;
printf(testingFmt, "wolfSSL TBS");
AssertNotNull(x509 =
wolfSSL_X509_load_certificate_file(caCertFile, WOLFSSL_FILETYPE_PEM));
AssertNull(tbs = wolfSSL_X509_get_tbs(NULL, &tbsSz));
AssertNull(tbs = wolfSSL_X509_get_tbs(x509, NULL));
AssertNotNull(tbs = wolfSSL_X509_get_tbs(x509, &tbsSz));
AssertIntEQ(tbsSz, 918);
wolfSSL_FreeX509(x509);
printf(resultFmt, passed);
#endif
}
static void test_wolfSSL_X509_verify(void)
{
#if !defined(NO_CERTS) && !defined(NO_RSA) && !defined(NO_FILESYSTEM) \
&& defined(OPENSSL_EXTRA)
WOLFSSL_X509* ca;
WOLFSSL_X509* server;
WOLFSSL_EVP_PKEY* pkey;
unsigned char buf[2048];
unsigned char* pt;
int bufSz;
printf(testingFmt, "wolfSSL X509 verify");
AssertNotNull(ca =
wolfSSL_X509_load_certificate_file(caCertFile, WOLFSSL_FILETYPE_PEM));
AssertIntNE(wolfSSL_X509_get_pubkey_buffer(NULL, buf, &bufSz),
WOLFSSL_SUCCESS);
AssertIntEQ(wolfSSL_X509_get_pubkey_buffer(ca, NULL, &bufSz),
WOLFSSL_SUCCESS);
AssertIntEQ(bufSz, 294);
bufSz = 2048;
AssertIntEQ(wolfSSL_X509_get_pubkey_buffer(ca, buf, &bufSz),
WOLFSSL_SUCCESS);
AssertIntEQ(wolfSSL_X509_get_pubkey_type(NULL), WOLFSSL_FAILURE);
AssertIntEQ(wolfSSL_X509_get_pubkey_type(ca), RSAk);
AssertNotNull(server =
wolfSSL_X509_load_certificate_file(svrCertFile, WOLFSSL_FILETYPE_PEM));
/* success case */
pt = buf;
AssertNotNull(pkey = wolfSSL_d2i_PUBKEY(NULL, &pt, bufSz));
AssertIntEQ(wolfSSL_X509_verify(server, pkey), WOLFSSL_SUCCESS);
wolfSSL_EVP_PKEY_free(pkey);
/* fail case */
bufSz = 2048;
AssertIntEQ(wolfSSL_X509_get_pubkey_buffer(server, buf, &bufSz),
WOLFSSL_SUCCESS);
pt = buf;
AssertNotNull(pkey = wolfSSL_d2i_PUBKEY(NULL, &pt, bufSz));
AssertIntEQ(wolfSSL_X509_verify(server, pkey), WOLFSSL_FAILURE);
AssertIntEQ(wolfSSL_X509_verify(NULL, pkey), WOLFSSL_FATAL_ERROR);
AssertIntEQ(wolfSSL_X509_verify(server, NULL), WOLFSSL_FATAL_ERROR);
wolfSSL_EVP_PKEY_free(pkey);
wolfSSL_FreeX509(ca);
wolfSSL_FreeX509(server);
printf(resultFmt, passed);
#endif
}
/* Testing function wolfSSL_CTX_SetMinVersion; sets the minimum downgrade
* version allowed.
* POST: 1 on success.
@ -20676,6 +20760,9 @@ static void test_wolfSSL_OBJ(void)
AssertNotNull(obj = OBJ_nid2obj(NID_sha256));
AssertIntEQ(OBJ_obj2nid(obj), NID_sha256);
AssertIntEQ(OBJ_obj2txt(buf, (int)sizeof(buf), obj, 1), 22);
#ifdef WOLFSSL_CERT_EXT
AssertIntEQ(OBJ_txt2nid(buf), NID_sha256);
#endif
AssertIntGT(OBJ_obj2txt(buf, (int)sizeof(buf), obj, 0), 0);
ASN1_OBJECT_free(obj);
@ -24365,6 +24452,8 @@ void ApiTest(void)
test_wolfSSL_PKCS8();
test_wolfSSL_PKCS5();
test_wolfSSL_URI();
test_wolfSSL_TBS();
test_wolfSSL_X509_verify();
test_wc_PemToDer();
test_wc_AllocDer();

View File

@ -5640,12 +5640,20 @@ int wc_GetCertDates(Cert* cert, struct tm* before, struct tm* after)
#endif /* WOLFSSL_CERT_GEN && WOLFSSL_ALT_NAMES */
#endif /* !NO_ASN_TIME */
int DecodeToKey(DecodedCert* cert, int verify)
/* parses certificate up to point of X.509 public key
*
* if cert date is invalid then badDate gets set to error value, otherwise is 0
*
* returns a negative value on fail case
*/
int wc_GetPubX509(DecodedCert* cert, int verify, int* badDate)
{
int badDate = 0;
int ret;
if (cert == NULL || badDate == NULL)
return BAD_FUNC_ARG;
*badDate = 0;
if ( (ret = GetCertHeader(cert)) < 0)
return ret;
@ -5661,12 +5669,23 @@ int DecodeToKey(DecodedCert* cert, int verify)
return ret;
if ( (ret = GetValidity(cert, verify)) < 0)
badDate = ret;
*badDate = ret;
if ( (ret = GetName(cert, SUBJECT)) < 0)
return ret;
WOLFSSL_MSG("Got Subject Name");
return ret;
}
int DecodeToKey(DecodedCert* cert, int verify)
{
int badDate = 0;
int ret;
if ( (ret = wc_GetPubX509(cert, verify, &badDate)) < 0)
return ret;
/* Determine if self signed */
cert->selfSigned = XMEMCMP(cert->issuerHash,
@ -7749,7 +7768,7 @@ static Signer* GetCABySubjectAndPubKey(DecodedCert* cert, void* cm)
}
#endif
#ifdef WOLFSSL_SMALL_CERT_VERIFY
#if defined(WOLFSSL_SMALL_CERT_VERIFY) || defined(OPENSSL_EXTRA)
/* Only quick step through the certificate to find fields that are then used
* in certificate signature verification.
* Must use the signature OID from the signed part of the certificate.
@ -7759,7 +7778,8 @@ static Signer* GetCABySubjectAndPubKey(DecodedCert* cert, void* cm)
* Doesn't support:
* OCSP Only: alt lookup using subject and pub key w/o sig check
*/
int CheckCertSignature(const byte* cert, word32 certSz, void* heap, void* cm)
static int CheckCertSignature_ex(const byte* cert, word32 certSz, void* heap,
void* cm, const byte* pubKey, word32 pubKeySz, int pubKeyOID)
{
#ifndef WOLFSSL_SMALL_STACK
SignatureCtx sigCtx[1];
@ -7770,12 +7790,12 @@ int CheckCertSignature(const byte* cert, word32 certSz, void* heap, void* cm)
Signer* ca = NULL;
word32 idx = 0;
int len;
word32 tbsCertIdx;
word32 sigIndex;
word32 tbsCertIdx = 0;
word32 sigIndex = 0;
word32 signatureOID;
word32 oid;
word32 issuerIdx;
word32 issuerSz;
word32 issuerIdx = 0;
word32 issuerSz = 0;
#ifndef NO_SKID
int extLen;
word32 extIdx;
@ -7963,7 +7983,7 @@ int CheckCertSignature(const byte* cert, word32 certSz, void* heap, void* cm)
}
}
if (ret == 0) {
if (ret == 0 && pubKey == NULL) {
if (extAuthKeyIdSet)
ca = GetCA(cm, hash);
if (ca == NULL) {
@ -7973,13 +7993,13 @@ int CheckCertSignature(const byte* cert, word32 certSz, void* heap, void* cm)
}
}
#else
if (ret == 0) {
if (ret == 0 && pubKey == NULL) {
ret = CalcHashId(cert + issuerIdx, issuerSz, hash);
if (ret == 0)
ca = GetCA(cm, hash);
}
#endif /* !NO_SKID */
if (ca == NULL)
if (ca == NULL && pubKey == NULL)
ret = ASN_NO_SIGNER_E;
if (ret == 0) {
@ -7999,9 +8019,18 @@ int CheckCertSignature(const byte* cert, word32 certSz, void* heap, void* cm)
}
if (ret == 0) {
ret = ConfirmSignature(sigCtx, cert + tbsCertIdx, sigIndex - tbsCertIdx,
if (pubKey != NULL) {
ret = ConfirmSignature(sigCtx, cert + tbsCertIdx,
sigIndex - tbsCertIdx,
pubKey, pubKeySz, pubKeyOID,
cert + idx, len, signatureOID);
}
else {
ret = ConfirmSignature(sigCtx, cert + tbsCertIdx,
sigIndex - tbsCertIdx,
ca->publicKey, ca->pubKeySize, ca->keyOID,
cert + idx, len, signatureOID);
}
if (ret != 0) {
WOLFSSL_MSG("Confirm signature failed");
}
@ -8014,7 +8043,26 @@ int CheckCertSignature(const byte* cert, word32 certSz, void* heap, void* cm)
#endif
return ret;
}
#ifdef OPENSSL_EXTRA
/* Call CheckCertSignature_ex using a public key buffer for verification
*/
int CheckCertSignaturePubKey(const byte* cert, word32 certSz, void* heap,
const byte* pubKey, word32 pubKeySz, int pubKeyOID)
{
return CheckCertSignature_ex(cert, certSz, heap, NULL,
pubKey, pubKeySz, pubKeyOID);
}
#endif /* OPENSSL_EXTRA */
#ifdef WOLFSSL_SMALL_CERT_VERIFY
/* Call CheckCertSignature_ex using a certificate manager (cm)
*/
int CheckCertSignature(const byte* cert, word32 certSz, void* heap, void* cm)
{
return CheckCertSignature_ex(cert, certSz, heap, cm, NULL, 0, 0);
}
#endif /* WOLFSSL_SMALL_CERT_VERIFY */
#endif /* WOLFSSL_SMALL_CERT_VERIFY || OPENSSL_EXTRA */
int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm)
{
@ -10818,7 +10866,7 @@ static int SetExtKeyUsage(Cert* cert, byte* output, word32 outSz, byte input)
}
/* Encode OID string representation to ITU-T X.690 format */
static int EncodePolicyOID(byte *out, word32 *outSz, const char *in, void* heap)
int EncodePolicyOID(byte *out, word32 *outSz, const char *in, void* heap)
{
word32 val, idx = 0, nb_val;
char *token, *str, *ptr;

View File

@ -468,6 +468,7 @@ WOLFSSL_API WOLFSSL_METHOD *wolfTLSv1_2_method(void);
WOLFSSL_API WOLFSSL_METHOD *wolfTLSv1_2_server_method(void);
WOLFSSL_API WOLFSSL_METHOD *wolfTLSv1_2_client_method(void);
#ifdef WOLFSSL_TLS13
WOLFSSL_API WOLFSSL_METHOD *wolfTLSv1_3_method(void);
WOLFSSL_API WOLFSSL_METHOD *wolfTLSv1_3_server_method(void);
WOLFSSL_API WOLFSSL_METHOD *wolfTLSv1_3_client_method(void);
#endif
@ -579,6 +580,7 @@ WOLFSSL_API int wolfSSL_set_read_fd (WOLFSSL*, int);
WOLFSSL_API char* wolfSSL_get_cipher_list(int priority);
WOLFSSL_API char* wolfSSL_get_cipher_list_ex(WOLFSSL* ssl, int priority);
WOLFSSL_API int wolfSSL_get_ciphers(char*, int);
WOLFSSL_API int wolfSSL_get_ciphers_iana(char*, int);
WOLFSSL_API const char* wolfSSL_get_cipher_name(WOLFSSL* ssl);
WOLFSSL_API const char* wolfSSL_get_cipher_name_from_suite(const unsigned char,
const unsigned char);
@ -930,6 +932,7 @@ WOLFSSL_API unsigned char* wolfSSL_X509_get_authorityKeyID(
WOLFSSL_API unsigned char* wolfSSL_X509_get_subjectKeyID(
WOLFSSL_X509*, unsigned char*, int*);
WOLFSSL_API int wolfSSL_X509_verify(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey);
WOLFSSL_API int wolfSSL_X509_set_subject_name(WOLFSSL_X509*,
WOLFSSL_X509_NAME*);
WOLFSSL_API int wolfSSL_X509_set_pubkey(WOLFSSL_X509*, WOLFSSL_EVP_PKEY*);
@ -952,6 +955,9 @@ WOLFSSL_API int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX*);
WOLFSSL_API const char* wolfSSL_X509_verify_cert_error_string(long);
WOLFSSL_API int wolfSSL_X509_get_signature_type(WOLFSSL_X509*);
WOLFSSL_API int wolfSSL_X509_get_signature(WOLFSSL_X509*, unsigned char*, int*);
WOLFSSL_API int wolfSSL_X509_get_pubkey_buffer(WOLFSSL_X509*, unsigned char*,
int*);
WOLFSSL_API int wolfSSL_X509_get_pubkey_type(WOLFSSL_X509* x509);
WOLFSSL_API int wolfSSL_X509_LOOKUP_add_dir(WOLFSSL_X509_LOOKUP*,const char*,long);
WOLFSSL_API int wolfSSL_X509_LOOKUP_load_file(WOLFSSL_X509_LOOKUP*, const char*,
@ -1586,6 +1592,7 @@ WOLFSSL_API const unsigned char* wolfSSL_get_sessionID(const WOLFSSL_SESSION* s)
WOLFSSL_API int wolfSSL_X509_get_serial_number(WOLFSSL_X509*,unsigned char*,int*);
WOLFSSL_API char* wolfSSL_X509_get_subjectCN(WOLFSSL_X509*);
WOLFSSL_API const unsigned char* wolfSSL_X509_get_der(WOLFSSL_X509*, int*);
WOLFSSL_API const unsigned char* wolfSSL_X509_get_tbs(WOLFSSL_X509*, int*);
WOLFSSL_API const unsigned char* wolfSSL_X509_notBefore(WOLFSSL_X509*);
WOLFSSL_API const unsigned char* wolfSSL_X509_notAfter(WOLFSSL_X509*);
WOLFSSL_API int wolfSSL_X509_version(WOLFSSL_X509*);
@ -2966,6 +2973,7 @@ WOLFSSL_API int wolfSSL_X509_NAME_digest(const WOLFSSL_X509_NAME *data,
const WOLFSSL_EVP_MD *type, unsigned char *md, unsigned int *len);
WOLFSSL_API long wolfSSL_SSL_CTX_get_timeout(const WOLFSSL_CTX *ctx);
WOLFSSL_API long wolfSSL_get_timeout(WOLFSSL* ssl);
WOLFSSL_API int wolfSSL_SSL_CTX_set_tmp_ecdh(WOLFSSL_CTX *ctx,
WOLFSSL_EC_KEY *ecdh);
WOLFSSL_API int wolfSSL_SSL_CTX_remove_session(WOLFSSL_CTX *,

View File

@ -939,9 +939,14 @@ WOLFSSL_ASN_API int ParseCert(DecodedCert*, int type, int verify, void* cm);
WOLFSSL_LOCAL int DecodePolicyOID(char *o, word32 oSz,
const byte *in, word32 inSz);
WOLFSSL_LOCAL int EncodePolicyOID(byte *out, word32 *outSz,
const char *in, void* heap);
WOLFSSL_API int CheckCertSignature(const byte*,word32,void*,void* cm);
WOLFSSL_LOCAL int CheckCertSignaturePubKey(const byte* cert, word32 certSz,
void* heap, const byte* pubKey, word32 pubKeySz, int pubKeyOID);
WOLFSSL_LOCAL int ParseCertRelative(DecodedCert*,int type,int verify,void* cm);
WOLFSSL_LOCAL int DecodeToKey(DecodedCert*, int verify);
WOLFSSL_LOCAL int wc_GetPubX509(DecodedCert* cert, int verify, int* badDate);
WOLFSSL_LOCAL const byte* OidFromId(word32 id, word32 type, word32* oidSz);
WOLFSSL_LOCAL Signer* MakeSigner(void*);

View File

@ -418,6 +418,8 @@ typedef int (*CallbackIORecv)(WOLFSSL *ssl, char *buf, int sz, void *ctx);
typedef int (*CallbackIOSend)(WOLFSSL *ssl, char *buf, int sz, void *ctx);
WOLFSSL_API void wolfSSL_CTX_SetIORecv(WOLFSSL_CTX*, CallbackIORecv);
WOLFSSL_API void wolfSSL_CTX_SetIOSend(WOLFSSL_CTX*, CallbackIOSend);
WOLFSSL_API void wolfSSL_SSLSetIORecv(WOLFSSL*, CallbackIORecv);
WOLFSSL_API void wolfSSL_SSLSetIOSend(WOLFSSL*, CallbackIOSend);
/* deprecated old name */
#define wolfSSL_SetIORecv wolfSSL_CTX_SetIORecv
#define wolfSSL_SetIOSend wolfSSL_CTX_SetIOSend