From b7663a940efa1ae70d3710dbdc2063683a8d9cf3 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Fri, 28 Sep 2018 09:05:59 -0700 Subject: [PATCH 1/8] Trusted CA Key Indication Extension Added an API for enabling the Trusted CA Key Indication extension from RFC6066 section 6. If the server doesn't have a match for the client, the client will abandon the session. --- configure.ac | 13 +- examples/client/client.c | 24 ++- examples/server/server.c | 23 ++- src/internal.c | 6 + src/ssl.c | 24 +++ src/tls.c | 339 +++++++++++++++++++++++++++++++++++++++ tests/api.c | 51 ++++++ wolfssl/error-ssl.h | 2 + wolfssl/internal.h | 20 +++ wolfssl/ssl.h | 17 ++ 10 files changed, 515 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index f9a7cca60..f36fafb17 100644 --- a/configure.ac +++ b/configure.ac @@ -168,6 +168,7 @@ then enable_maxfragment=yes enable_alpn=yes enable_truncatedhmac=yes + enable_trusted_ca=yes enable_supportedcurves=yes enable_session_ticket=yes enable_tlsx=yes @@ -2863,6 +2864,14 @@ then AM_CFLAGS="$AM_CFLAGS -DHAVE_TLS_EXTENSIONS -DHAVE_MAX_FRAGMENT" fi +# Trusted CA Indication Extension +AC_ARG_ENABLE([trustedca], + [AS_HELP_STRING([--enable-trustedca],[Enable Trusted CA Indication (default: disabled)])], + [ ENABLED_TRUSTED_CA=$enableval ],[ ENABLED_TRUSTED_CA=no ]) + +AS_IF([test "x$ENABLED_TRUSTED_CA" = "xyes"], + [AM_CFLAGS="$AM_CFLAGS -DHAVE_TLS_EXTENSIONS -DHAVE_TRUSTED_CA"]) + # Truncated HMAC AC_ARG_ENABLE([truncatedhmac], [AS_HELP_STRING([--enable-truncatedhmac],[Enable Truncated HMAC (default: disabled)])], @@ -2992,7 +3001,8 @@ then ENABLED_MAX_FRAGMENT=yes ENABLED_TRUNCATED_HMAC=yes ENABLED_ALPN=yes - AM_CFLAGS="$AM_CFLAGS -DHAVE_TLS_EXTENSIONS -DHAVE_SNI -DHAVE_MAX_FRAGMENT -DHAVE_TRUNCATED_HMAC -DHAVE_ALPN" + ENABLED_TRUSTED_CA=yes + AM_CFLAGS="$AM_CFLAGS -DHAVE_TLS_EXTENSIONS -DHAVE_SNI -DHAVE_MAX_FRAGMENT -DHAVE_TRUNCATED_HMAC -DHAVE_ALPN -DHAVE_TRUSTED_CA" # Check the ECC supported curves prereq AS_IF([test "x$ENABLED_ECC" = "xyes" || test "x$ENABLED_CURVE25519" = "xyes"], [ENABLED_SUPPORTED_CURVES=yes @@ -4930,6 +4940,7 @@ echo " * Whitewood netRandom: $ENABLED_WNR" echo " * Server Name Indication: $ENABLED_SNI" echo " * ALPN: $ENABLED_ALPN" echo " * Maximum Fragment Length: $ENABLED_MAX_FRAGMENT" +echo " * Trusted CA Indication: $ENABLED_TRUSTED_CA" echo " * Truncated HMAC: $ENABLED_TRUNCATED_HMAC" echo " * Supported Elliptic Curves: $ENABLED_SUPPORTED_CURVES" echo " * FFDHE only in client: $ENABLED_FFDHE_ONLY" diff --git a/examples/client/client.c b/examples/client/client.c index 446e29e1c..cd72d5253 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -1290,6 +1290,9 @@ static void Usage(void) #endif #ifdef WOLFSSL_MULTICAST printf("%s", msg[++msgid]); /* -3 */ +#endif +#ifdef HAVE_TRUSTED_CA + printf("-5 Use Trusted CA Key Indication\n"); #endif printf("%s", msg[++msgid]); /* -1 */ #if !defined(NO_DH) && !defined(HAVE_FIPS) && \ @@ -1387,6 +1390,9 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) #ifdef HAVE_SNI char* sniHostName = NULL; #endif +#ifdef HAVE_TRUSTED_CA + int trustedCaKeyId = 0; +#endif #ifdef HAVE_MAX_FRAGMENT byte maxFragment = 0; #endif @@ -1492,7 +1498,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) while ((ch = mygetopt(argc, argv, "?:" "ab:c:defgh:ijk:l:mnop:q:rstuv:wxyz" "A:B:CDE:F:GH:IJKL:M:NO:PQRS:TUVW:XYZ:" - "01:23:4")) != -1) { + "01:23:5")) != -1) { switch (ch) { case '?' : if(myoptarg!=NULL) { @@ -1912,6 +1918,11 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) forceScr = 1; resumeScr = 1; #endif + + case '5' : + #ifdef HAVE_TRUSTED_CA + trustedCaKeyId = 1; + #endif /* HAVE_TRUSTED_CA */ break; default: @@ -2356,11 +2367,12 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) #endif /* WOLFSSL_ASYNC_CRYPT */ #ifdef HAVE_SNI - if (sniHostName) + if (sniHostName) { if (wolfSSL_CTX_UseSNI(ctx, 0, sniHostName, (word16) XSTRLEN(sniHostName)) != WOLFSSL_SUCCESS) { wolfSSL_CTX_free(ctx); ctx = NULL; err_sys("UseSNI failed"); + } } #endif #ifdef HAVE_MAX_FRAGMENT @@ -2601,6 +2613,14 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) wolfSSL_set_SessionTicket_cb(ssl, sessionTicketCB, (void*)"initial session"); #endif +#ifdef HAVE_TRUSTED_CA + if (trustedCaKeyId) { + if (wolfSSL_UseTrustedCA(ssl, WOLFSSL_TRUSTED_CA_PRE_AGREED, + NULL, 0) != WOLFSSL_SUCCESS) { + err_sys("UseTrustedCA failed"); + } + } +#endif #ifdef HAVE_ALPN if (alpnList != NULL) { printf("ALPN accepted protocols list : %s\n", alpnList); diff --git a/examples/server/server.c b/examples/server/server.c index dc1b30ae6..30ccd1879 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -825,6 +825,9 @@ static void Usage(void) printf("%s", msg[++msgId]); /* -3 */ #endif printf("%s", msg[++msgId]); /* -1 */ +#ifdef HAVE_TRUSTED_CA + printf("-5 Use Trusted CA Key Indication\n"); +#endif /* HAVE_TRUSTED_CA */ } THREAD_RETURN WOLFSSL_THREAD server_test(void* args) @@ -914,6 +917,10 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) char* sniHostName = NULL; #endif +#ifdef HAVE_TRUSTED_CA + int trustedCaKeyId = 0; +#endif /* HAVE_TRUSTED_CA */ + #ifdef HAVE_OCSP int useOcsp = 0; char* ocspUrl = NULL; @@ -1010,7 +1017,7 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) while ((ch = mygetopt(argc, argv, "?:" "abc:defgijk:l:mnop:q:rstuv:wxy" "A:B:C:D:E:GH:IJKL:MNO:PQR:S:TUVYZ:" - "01:23:4:")) != -1) { + "01:23:4:5")) != -1) { switch (ch) { case '?' : if(myoptarg!=NULL) { @@ -1372,6 +1379,11 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) doBlockSeq = 1; dtlsCtx.blockSeq = atoi(myoptarg); #endif + + case '5' : + #ifdef HAVE_TRUSTED_CA + trustedCaKeyId = 1; + #endif /* HAVE_TRUSTED_CA */ break; default: @@ -1953,6 +1965,15 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) err_sys_ex(runWithErrors, "error in setting fd"); } +#ifdef HAVE_TRUSTED_CA + if (trustedCaKeyId) { + if (wolfSSL_UseTrustedCA(ssl, WOLFSSL_TRUSTED_CA_PRE_AGREED, + NULL, 0) != WOLFSSL_SUCCESS) { + err_sys_ex(runWithErrors, "UseTrustedCA failed"); + } + } +#endif /* HAVE_TRUSTED_CA */ + #ifdef HAVE_ALPN if (alpnList != NULL) { printf("ALPN accepted protocols list : %s\n", alpnList); diff --git a/src/internal.c b/src/internal.c index 133ce6f2a..39c0ea003 100644 --- a/src/internal.c +++ b/src/internal.c @@ -15947,6 +15947,12 @@ const char* wolfSSL_ERR_reason_error_string(unsigned long e) case DH_PARAMS_NOT_FFDHE_E: return "Server DH parameters were not from the FFDHE set as required"; + case TCA_INVALID_ID_TYPE: + return "TLS Extension Trusted CA ID type invalid"; + + case TCA_ABSENT_ERROR: + return "TLS Extension Trusted CA ID response absent"; + default : return "unknown error number"; } diff --git a/src/ssl.c b/src/ssl.c index c83b31726..592c8f8ef 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -1960,6 +1960,30 @@ int wolfSSL_SNI_GetFromBuffer(const byte* clientHello, word32 helloSz, #endif /* HAVE_SNI */ +#ifdef HAVE_TRUSTED_CA + +WOLFSSL_API int wolfSSL_UseTrustedCA(WOLFSSL* ssl, byte type, + const byte* cert, word32 certSz) +{ + if (ssl == NULL) + return BAD_FUNC_ARG; + + return TLSX_UseTrustedCA(&ssl->extensions, type, cert, certSz, ssl->heap); +} + + +WOLFSSL_API int wolfSSL_CTX_UseTrustedCA(WOLFSSL_CTX* ctx, byte type, + const byte* cert, word32 certSz) +{ + if (ctx == NULL) + return BAD_FUNC_ARG; + + return TLSX_UseTrustedCA(&ctx->extensions, type, cert, certSz, ctx->heap); +} + +#endif /* HAVE_TRUSTED_CA */ + + #ifdef HAVE_MAX_FRAGMENT #ifndef NO_WOLFSSL_CLIENT diff --git a/src/tls.c b/src/tls.c index 6532cf10e..6e9049a4f 100644 --- a/src/tls.c +++ b/src/tls.c @@ -2305,6 +2305,313 @@ int TLSX_SNI_GetFromBuffer(const byte* clientHello, word32 helloSz, #endif /* HAVE_SNI */ +/******************************************************************************/ +/* Trusted CA Key Indication */ +/******************************************************************************/ + +#ifdef HAVE_TRUSTED_CA + +/** Creates a new TCA object. */ +static TCA* TLSX_TCA_New(byte type, const byte* id, word16 idSz, void* heap) +{ + TCA* tca = (TCA*)XMALLOC(sizeof(TCA), heap, DYNAMIC_TYPE_TLSX); + + if (tca) { + XMEMSET(tca, 0, sizeof(TCA)); + tca->type = type; + + switch (type) { + case WOLFSSL_TRUSTED_CA_PRE_AGREED: + break; + + case WOLFSSL_TRUSTED_CA_KEY_SHA1: + case WOLFSSL_TRUSTED_CA_CERT_SHA1: + if (idSz == SHA_DIGEST_SIZE && + (tca->id = + (byte*)XMALLOC(idSz, heap, DYNAMIC_TYPE_TLSX))) { + XMEMCPY(tca->id, id, idSz); + tca->idSz = idSz; + } + else { + XFREE(tca, heap, DYNAMIC_TYPE_TLSX); + tca = NULL; + } + break; + + case WOLFSSL_TRUSTED_CA_X509_NAME: + if (idSz > 0 && + (tca->id = + (byte*)XMALLOC(idSz, heap, DYNAMIC_TYPE_TLSX))) { + XMEMCPY(tca->id, id, idSz); + tca->idSz = idSz; + } + else { + XFREE(tca, heap, DYNAMIC_TYPE_TLSX); + tca = NULL; + } + break; + + default: /* invalid type */ + XFREE(tca, heap, DYNAMIC_TYPE_TLSX); + tca = NULL; + } + } + + return tca; +} + +/** Releases a TCA object. */ +static void TLSX_TCA_Free(TCA* tca, void* heap) +{ + (void)heap; + + if (tca) { + if (tca->id) + XFREE(tca->id, heap, DYNAMIC_TYPE_TLSX); + XFREE(tca, heap, DYNAMIC_TYPE_TLSX); + } +} + +/** Releases all TCA objects in the provided list. */ +static void TLSX_TCA_FreeAll(TCA* list, void* heap) +{ + TCA* tca; + + while ((tca = list)) { + list = tca->next; + TLSX_TCA_Free(tca, heap); + } +} + +/** Tells the buffered size of the TCA objects in a list. */ +static word16 TLSX_TCA_GetSize(TCA* list) +{ + TCA* tca; + word16 length = OPAQUE16_LEN; /* list length */ + + while ((tca = list)) { + list = tca->next; + + length += ENUM_LEN; /* tca type */ + + switch (tca->type) { + case WOLFSSL_TRUSTED_CA_PRE_AGREED: + break; + case WOLFSSL_TRUSTED_CA_KEY_SHA1: + case WOLFSSL_TRUSTED_CA_CERT_SHA1: + length += tca->idSz; + break; + case WOLFSSL_TRUSTED_CA_X509_NAME: + length += OPAQUE16_LEN + tca->idSz; + break; + } + } + + return length; +} + +/** Writes the TCA objects of a list in a buffer. */ +static word16 TLSX_TCA_Write(TCA* list, byte* output) +{ + TCA* tca; + word16 offset = OPAQUE16_LEN; /* list length offset */ + + while ((tca = list)) { + list = tca->next; + + output[offset++] = tca->type; /* tca type */ + + switch (tca->type) { + case WOLFSSL_TRUSTED_CA_PRE_AGREED: + break; + case WOLFSSL_TRUSTED_CA_KEY_SHA1: + case WOLFSSL_TRUSTED_CA_CERT_SHA1: + XMEMCPY(output + offset, tca->id, tca->idSz); + offset += tca->idSz; + break; + case WOLFSSL_TRUSTED_CA_X509_NAME: + c16toa(tca->idSz, output + offset); /* tca length */ + offset += OPAQUE16_LEN; + XMEMCPY(output + offset, tca->id, tca->idSz); + offset += tca->idSz; + break; + } + } + + c16toa(offset - OPAQUE16_LEN, output); /* writing list length */ + + return offset; +} + +static TCA* TLSX_TCA_Find(TCA *list, byte type, const byte* id, word16 idSz) +{ + TCA* tca = list; + + while (tca && tca->type != type && type != WOLFSSL_TRUSTED_CA_PRE_AGREED && + idSz != tca->idSz && !XMEMCMP(id, tca->id, idSz)) + tca = tca->next; + + return tca; +} + +/** Parses a buffer of TCA extensions. */ +static int TLSX_TCA_Parse(WOLFSSL* ssl, const byte* input, word16 length, + byte isRequest) +{ +#ifndef NO_WOLFSSL_SERVER + word16 size = 0; + word16 offset = 0; +#endif + + TLSX *extension = TLSX_Find(ssl->extensions, TLSX_TRUSTED_CA_KEYS); + + if (!extension) + extension = TLSX_Find(ssl->ctx->extensions, TLSX_TRUSTED_CA_KEYS); + + if (!isRequest) { + #ifndef NO_WOLFSSL_CLIENT + if (!extension || !extension->data) + return TLSX_HandleUnsupportedExtension(ssl); + + if (length > 0) + return BUFFER_ERROR; /* TCA response MUST be empty. */ + + /* Set the flag that we're good for keys */ + TLSX_SetResponse(ssl, TLSX_TRUSTED_CA_KEYS); + + return 0; + #endif + } + +#ifndef NO_WOLFSSL_SERVER + if (!extension || !extension->data) { + /* Skipping, TCA not enabled at server side. */ + return 0; + } + + if (OPAQUE16_LEN > length) + return BUFFER_ERROR; + + ato16(input, &size); + offset += OPAQUE16_LEN; + + /* validating tca list length */ + if (length != OPAQUE16_LEN + size) + return BUFFER_ERROR; + + for (size = 0; offset < length; offset += size) { + TCA *tca = NULL; + byte type; + const byte* id = NULL; + word16 idSz = 0; + + if (offset + ENUM_LEN > length) + return BUFFER_ERROR; + + type = input[offset++]; + + switch (type) { + case WOLFSSL_TRUSTED_CA_PRE_AGREED: + break; + case WOLFSSL_TRUSTED_CA_KEY_SHA1: + case WOLFSSL_TRUSTED_CA_CERT_SHA1: + if (offset + SHA_DIGEST_SIZE > length) + return BUFFER_ERROR; + idSz = SHA_DIGEST_SIZE; + id = input + offset; + offset += idSz; + break; + case WOLFSSL_TRUSTED_CA_X509_NAME: + if (offset + OPAQUE16_LEN > length) + return BUFFER_ERROR; + ato16(input + offset, &idSz); + offset += OPAQUE16_LEN; + if (offset + idSz > length) + return BUFFER_ERROR; + id = input + offset; + offset += idSz; + break; + default: + return TCA_INVALID_ID_TYPE; + } + + tca = TLSX_TCA_Find((TCA*)extension->data, type, id, idSz); + if (!tca) + continue; + + TLSX_SetResponse(ssl, TLSX_TRUSTED_CA_KEYS); + } +#else + (void)input; +#endif + + return 0; +} + +static int TLSX_TCA_VerifyParse(WOLFSSL* ssl, byte isRequest) +{ + (void)ssl; + + if (!isRequest) { + #ifndef NO_WOLFSSL_CLIENT + TLSX* extension = TLSX_Find(ssl->extensions, TLSX_TRUSTED_CA_KEYS); + + if (extension && !extension->resp) { + SendAlert(ssl, alert_fatal, handshake_failure); + return TCA_ABSENT_ERROR; + } + #endif /* NO_WOLFSSL_CLIENT */ + } + + return 0; +} + +int TLSX_UseTrustedCA(TLSX** extensions, byte type, + const byte* id, word16 idSz, void* heap) +{ + TLSX* extension; + TCA* tca = NULL; + + if (extensions == NULL) + return BAD_FUNC_ARG; + + if ((tca = TLSX_TCA_New(type, id, idSz, heap)) == NULL) + return MEMORY_E; + + extension = TLSX_Find(*extensions, TLSX_TRUSTED_CA_KEYS); + if (!extension) { + int ret = TLSX_Push(extensions, TLSX_TRUSTED_CA_KEYS, (void*)tca, heap); + + if (ret != 0) { + TLSX_TCA_Free(tca, heap); + return ret; + } + } + else { + /* push new TCA object to extension data. */ + tca->next = (TCA*)extension->data; + extension->data = (void*)tca; + } + + return WOLFSSL_SUCCESS; +} + +#define TCA_FREE_ALL TLSX_TCA_FreeAll +#define TCA_GET_SIZE TLSX_TCA_GetSize +#define TCA_WRITE TLSX_TCA_Write +#define TCA_PARSE TLSX_TCA_Parse +#define TCA_VERIFY_PARSE TLSX_TCA_VerifyParse + +#else /* HAVE_TRUSTED_CA */ + +#define TCA_FREE_ALL(list, heap) +#define TCA_GET_SIZE(list) 0 +#define TCA_WRITE(a, b) 0 +#define TCA_PARSE(a, b, c, d) 0 +#define TCA_VERIFY_PARSE(a, b) 0 + +#endif /* HAVE_TRUSTED_CA */ + /******************************************************************************/ /* Max Fragment Length Negotiation */ /******************************************************************************/ @@ -8240,6 +8547,10 @@ void TLSX_FreeAll(TLSX* list, void* heap) SNI_FREE_ALL((SNI*)extension->data, heap); break; + case TLSX_TRUSTED_CA_KEYS: + TCA_FREE_ALL((TCA*)extension->data, heap); + break; + case TLSX_MAX_FRAGMENT_LENGTH: MFL_FREE_ALL(extension->data, heap); break; @@ -8365,6 +8676,12 @@ static int TLSX_GetSize(TLSX* list, byte* semaphore, byte msgType, word16* pLeng length += SNI_GET_SIZE((SNI*)extension->data); break; + case TLSX_TRUSTED_CA_KEYS: + /* TCA only sends the list on the request. */ + if (isRequest) + length += TCA_GET_SIZE((TCA*)extension->data); + break; + case TLSX_MAX_FRAGMENT_LENGTH: length += MFL_GET_SIZE(extension->data); break; @@ -8503,6 +8820,13 @@ static int TLSX_Write(TLSX* list, byte* output, byte* semaphore, } break; + case TLSX_TRUSTED_CA_KEYS: + WOLFSSL_MSG("Trusted CA Indication extension to write"); + if (isRequest) { + offset += TCA_WRITE((TCA*)extension->data, output + offset); + } + break; + case TLSX_MAX_FRAGMENT_LENGTH: WOLFSSL_MSG("Max Fragment Length extension to write"); offset += MFL_WRITE((byte*)extension->data, output + offset); @@ -9840,6 +10164,19 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType, ret = SNI_PARSE(ssl, input + offset, size, isRequest); break; + case TLSX_TRUSTED_CA_KEYS: + WOLFSSL_MSG("Trusted CA extension received"); + +#ifdef WOLFSSL_TLS13 + if (IsAtLeastTLSv1_3(ssl->version) && + msgType != client_hello && + msgType != encrypted_extensions) { + return EXT_NOT_ALLOWED; + } +#endif + ret = TCA_PARSE(ssl, input + offset, size, isRequest); + break; + case TLSX_MAX_FRAGMENT_LENGTH: WOLFSSL_MSG("Max Fragment Length extension received"); @@ -10128,6 +10465,8 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType, if (ret == 0) ret = SNI_VERIFY_PARSE(ssl, isRequest); + if (ret == 0) + ret = TCA_VERIFY_PARSE(ssl, isRequest); return ret; } diff --git a/tests/api.c b/tests/api.c index 99b2382af..384931256 100644 --- a/tests/api.c +++ b/tests/api.c @@ -3025,6 +3025,56 @@ static void test_wolfSSL_UseSNI(void) #endif } +static void test_wolfSSL_UseTrustedCA(void) +{ +#ifdef HAVE_TRUSTED_CA + WOLFSSL_CTX *ctx; + WOLFSSL *ssl; + byte id[20]; + + AssertNotNull((ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()))); + AssertNotNull((ssl = wolfSSL_new(ctx))); + XMEMSET(id, 0, sizeof(id)); + + /* error cases */ + AssertIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_UseTrustedCA(NULL, 0, NULL, 0)); + AssertIntNE(WOLFSSL_SUCCESS, wolfSSL_UseTrustedCA(NULL, 0, NULL, 0)); + AssertIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_UseTrustedCA(ctx, + WOLFSSL_TRUSTED_CA_CERT_SHA1+1, NULL, 0)); + AssertIntNE(WOLFSSL_SUCCESS, wolfSSL_UseTrustedCA(ssl, + WOLFSSL_TRUSTED_CA_CERT_SHA1+1, NULL, 0)); + AssertIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_UseTrustedCA(ctx, + WOLFSSL_TRUSTED_CA_CERT_SHA1, NULL, 0)); + AssertIntNE(WOLFSSL_SUCCESS, wolfSSL_UseTrustedCA(ssl, + WOLFSSL_TRUSTED_CA_CERT_SHA1, NULL, 0)); + AssertIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_UseTrustedCA(ctx, + WOLFSSL_TRUSTED_CA_CERT_SHA1, id, 5)); + AssertIntNE(WOLFSSL_SUCCESS, wolfSSL_UseTrustedCA(ssl, + WOLFSSL_TRUSTED_CA_CERT_SHA1, id, 5)); + AssertIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_UseTrustedCA(ctx, + WOLFSSL_TRUSTED_CA_X509_NAME, id, 0)); + AssertIntNE(WOLFSSL_SUCCESS, wolfSSL_UseTrustedCA(ssl, + WOLFSSL_TRUSTED_CA_X509_NAME, id, 0)); + + /* success cases */ + AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_UseTrustedCA(ctx, + WOLFSSL_TRUSTED_CA_PRE_AGREED, NULL, 0)); + AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_UseTrustedCA(ssl, + WOLFSSL_TRUSTED_CA_PRE_AGREED, NULL, 0)); + AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_UseTrustedCA(ctx, + WOLFSSL_TRUSTED_CA_KEY_SHA1, id, sizeof(id))); + AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_UseTrustedCA(ssl, + WOLFSSL_TRUSTED_CA_KEY_SHA1, id, sizeof(id))); + AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_UseTrustedCA(ctx, + WOLFSSL_TRUSTED_CA_X509_NAME, id, 5)); + AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_UseTrustedCA(ssl, + WOLFSSL_TRUSTED_CA_X509_NAME, id, 5)); + + wolfSSL_free(ssl); + wolfSSL_CTX_free(ctx); +#endif /* HAVE_TRUSTED_CA */ +} + static void test_wolfSSL_UseMaxFragment(void) { #if defined(HAVE_MAX_FRAGMENT) && !defined(NO_WOLFSSL_CLIENT) @@ -23409,6 +23459,7 @@ void ApiTest(void) /* TLS extensions tests */ test_wolfSSL_UseSNI(); + test_wolfSSL_UseTrustedCA(); test_wolfSSL_UseMaxFragment(); test_wolfSSL_UseTruncatedHMAC(); test_wolfSSL_UseSupportedCurve(); diff --git a/wolfssl/error-ssl.h b/wolfssl/error-ssl.h index c16002762..fcbcbc71f 100644 --- a/wolfssl/error-ssl.h +++ b/wolfssl/error-ssl.h @@ -161,6 +161,8 @@ enum wolfSSL_ErrorCodes { PRF_MISSING = -430, /* PRF not compiled in */ DTLS_RETX_OVER_TX = -431, /* Retransmit DTLS flight over */ DH_PARAMS_NOT_FFDHE_E = -432, /* DH params from server not FFDHE */ + TCA_INVALID_ID_TYPE = -433, /* TLSX TCA ID type invalid */ + TCA_ABSENT_ERROR = -434, /* TLSX TCA ID no response */ /* add strings to wolfSSL_ERR_reason_error_string in internal.c !!!!! */ /* begin negotiation parameter errors */ diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 4be19bae5..6280d9712 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2055,6 +2055,7 @@ typedef struct Keys { typedef enum { TLSX_SERVER_NAME = 0x0000, /* a.k.a. SNI */ TLSX_MAX_FRAGMENT_LENGTH = 0x0001, + TLSX_TRUSTED_CA_KEYS = 0x0003, TLSX_TRUNCATED_HMAC = 0x0004, TLSX_STATUS_REQUEST = 0x0005, /* a.k.a. OCSP stapling */ TLSX_SUPPORTED_GROUPS = 0x000a, /* a.k.a. Supported Curves */ @@ -2125,6 +2126,7 @@ WOLFSSL_LOCAL int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, #elif defined(HAVE_SNI) \ || defined(HAVE_MAX_FRAGMENT) \ + || defined(HAVE_TRUSTED_CA) \ || defined(HAVE_TRUNCATED_HMAC) \ || defined(HAVE_CERTIFICATE_STATUS_REQUEST) \ || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) \ @@ -2167,6 +2169,24 @@ WOLFSSL_LOCAL int TLSX_SNI_GetFromBuffer(const byte* buffer, word32 bufferSz, #endif /* HAVE_SNI */ +/* Trusted CA Key Indication - RFC 6066 (section 6) */ +#ifdef HAVE_TRUSTED_CA + +typedef struct TCA { + byte type; /* TCA Type */ + byte* id; /* TCA identifier */ + word16 idSz; /* TCA identifier size */ + struct TCA* next; /* List Behavior */ +#ifndef NO_WOLFSSL_CLIENT + byte options; /* Behavior options */ +#endif /* NO_WOLFSSL_CLIENT */ +} TCA; + +WOLFSSL_LOCAL int TLSX_UseTrustedCA(TLSX** extensions, byte type, + const byte* id, word16 idSz, void* heap); + +#endif /* HAVE_TRUSTED_CA */ + /* Application-Layer Protocol Negotiation - RFC 7301 */ #ifdef HAVE_ALPN typedef struct ALPN { diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 42004e0da..948263956 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -2248,6 +2248,23 @@ WOLFSSL_API unsigned short wolfSSL_SNI_GetRequest(WOLFSSL *ssl, #endif /* HAVE_SNI */ +/* Trusted CA Key Indication - RFC 6066 (Section 6) */ +#ifdef HAVE_TRUSTED_CA + +/* TCA Identifier Type */ +enum { + WOLFSSL_TRUSTED_CA_PRE_AGREED = 0, + WOLFSSL_TRUSTED_CA_KEY_SHA1 = 1, + WOLFSSL_TRUSTED_CA_X509_NAME = 2, + WOLFSSL_TRUSTED_CA_CERT_SHA1 = 3 +}; + +WOLFSSL_API int wolfSSL_UseTrustedCA(WOLFSSL* ssl, unsigned char type, + const unsigned char* cert, unsigned int certSz); +WOLFSSL_API int wolfSSL_CTX_UseTrustedCA(WOLFSSL_CTX* ctx, unsigned char type, + const unsigned char* cert, unsigned int certSz); +#endif /* HAVE_TRUSTED_CA */ + /* Application-Layer Protocol Negotiation */ #ifdef HAVE_ALPN From cb57a5f3ed26f49108f9851c36d5b97b3b2ef76b Mon Sep 17 00:00:00 2001 From: John Safranek Date: Mon, 1 Oct 2018 13:48:51 -0700 Subject: [PATCH 2/8] Added a test case for TrustedCA to the unit test.conf file. --- tests/test.conf | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/test.conf b/tests/test.conf index eaece3e6e..64e8b48ee 100644 --- a/tests/test.conf +++ b/tests/test.conf @@ -2438,3 +2438,11 @@ -v 3 -l ECDHE-RSA-AES128-GCM-SHA256 -i -4 + +# server TLSv1.2 with Trusted CA Indication (pre-shared) +-v 3 +-5 + +# client TLSv1.2 with Trusted CA Indication (pre-shared) +-v 3 +-5 From 2342ea15eb98bd5f1b768ea4b5045ff9a4af4131 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Mon, 1 Oct 2018 13:57:01 -0700 Subject: [PATCH 3/8] Remove the CTX versions of the UseTrustedCA functions. A session needs to be able to set a flag in the extension and that isn't allowed in the CTX extensions. --- src/ssl.c | 10 ---------- tests/api.c | 15 --------------- wolfssl/ssl.h | 2 -- 3 files changed, 27 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 592c8f8ef..dc9bb37f8 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -1971,16 +1971,6 @@ WOLFSSL_API int wolfSSL_UseTrustedCA(WOLFSSL* ssl, byte type, return TLSX_UseTrustedCA(&ssl->extensions, type, cert, certSz, ssl->heap); } - -WOLFSSL_API int wolfSSL_CTX_UseTrustedCA(WOLFSSL_CTX* ctx, byte type, - const byte* cert, word32 certSz) -{ - if (ctx == NULL) - return BAD_FUNC_ARG; - - return TLSX_UseTrustedCA(&ctx->extensions, type, cert, certSz, ctx->heap); -} - #endif /* HAVE_TRUSTED_CA */ diff --git a/tests/api.c b/tests/api.c index 384931256..da5767174 100644 --- a/tests/api.c +++ b/tests/api.c @@ -3037,36 +3037,21 @@ static void test_wolfSSL_UseTrustedCA(void) XMEMSET(id, 0, sizeof(id)); /* error cases */ - AssertIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_UseTrustedCA(NULL, 0, NULL, 0)); AssertIntNE(WOLFSSL_SUCCESS, wolfSSL_UseTrustedCA(NULL, 0, NULL, 0)); - AssertIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_UseTrustedCA(ctx, - WOLFSSL_TRUSTED_CA_CERT_SHA1+1, NULL, 0)); AssertIntNE(WOLFSSL_SUCCESS, wolfSSL_UseTrustedCA(ssl, WOLFSSL_TRUSTED_CA_CERT_SHA1+1, NULL, 0)); - AssertIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_UseTrustedCA(ctx, - WOLFSSL_TRUSTED_CA_CERT_SHA1, NULL, 0)); AssertIntNE(WOLFSSL_SUCCESS, wolfSSL_UseTrustedCA(ssl, WOLFSSL_TRUSTED_CA_CERT_SHA1, NULL, 0)); - AssertIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_UseTrustedCA(ctx, - WOLFSSL_TRUSTED_CA_CERT_SHA1, id, 5)); AssertIntNE(WOLFSSL_SUCCESS, wolfSSL_UseTrustedCA(ssl, WOLFSSL_TRUSTED_CA_CERT_SHA1, id, 5)); - AssertIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_UseTrustedCA(ctx, - WOLFSSL_TRUSTED_CA_X509_NAME, id, 0)); AssertIntNE(WOLFSSL_SUCCESS, wolfSSL_UseTrustedCA(ssl, WOLFSSL_TRUSTED_CA_X509_NAME, id, 0)); /* success cases */ - AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_UseTrustedCA(ctx, - WOLFSSL_TRUSTED_CA_PRE_AGREED, NULL, 0)); AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_UseTrustedCA(ssl, WOLFSSL_TRUSTED_CA_PRE_AGREED, NULL, 0)); - AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_UseTrustedCA(ctx, - WOLFSSL_TRUSTED_CA_KEY_SHA1, id, sizeof(id))); AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_UseTrustedCA(ssl, WOLFSSL_TRUSTED_CA_KEY_SHA1, id, sizeof(id))); - AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_UseTrustedCA(ctx, - WOLFSSL_TRUSTED_CA_X509_NAME, id, 5)); AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_UseTrustedCA(ssl, WOLFSSL_TRUSTED_CA_X509_NAME, id, 5)); diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 948263956..16baa6394 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -2261,8 +2261,6 @@ enum { WOLFSSL_API int wolfSSL_UseTrustedCA(WOLFSSL* ssl, unsigned char type, const unsigned char* cert, unsigned int certSz); -WOLFSSL_API int wolfSSL_CTX_UseTrustedCA(WOLFSSL_CTX* ctx, unsigned char type, - const unsigned char* cert, unsigned int certSz); #endif /* HAVE_TRUSTED_CA */ /* Application-Layer Protocol Negotiation */ From a1ed8e7a67f0797daba044a9e4f47165361e5eb1 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Tue, 19 Feb 2019 10:31:37 -0800 Subject: [PATCH 4/8] Fix a fall-through bug in the server options parsing around a new option. --- examples/server/server.c | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/server/server.c b/examples/server/server.c index 30ccd1879..8e4221e8f 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -1379,6 +1379,7 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) doBlockSeq = 1; dtlsCtx.blockSeq = atoi(myoptarg); #endif + break; case '5' : #ifdef HAVE_TRUSTED_CA From 201c85478e2ed1851172ff8001dad3fe718d5fb1 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Thu, 21 Feb 2019 10:28:23 -0800 Subject: [PATCH 5/8] Move the -5 option text into the localization array and add a Japanese translation. --- examples/client/client.c | 14 +++++++++++--- examples/server/server.c | 9 +++++++-- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/examples/client/client.c b/examples/client/client.c index cd72d5253..7c9ef25cf 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -988,7 +988,12 @@ static const char* client_usage_msg[][59] = { !defined(HAVE_SELFTEST) && !defined(WOLFSSL_OLD_PRIME_CHECK) "-2 Disable DH Prime check\n", /* 59 */ #endif +#ifdef HAVE_SECURE_RENEGOTIATION "-4 Use resumption for renegotiation\n", /* 60 */ +#endif +#ifdef HAVE_TRUSTED_CA + "-5 Use Trusted CA Key Indication\n", /* 61 */ +#endif NULL, }, #ifndef NO_MULTIBYTE_PRINT @@ -1146,6 +1151,9 @@ static const char* client_usage_msg[][59] = { #endif #ifdef HAVE_SECURE_RENEGOTIATION "-4 再交渉に再開を使用\n", /* 60 */ +#endif +#ifdef HAVE_TRUSTED_CA + "-5 信頼できる認証局の鍵表示を使用する\n", /* 61 */ #endif NULL, }, @@ -1290,9 +1298,6 @@ static void Usage(void) #endif #ifdef WOLFSSL_MULTICAST printf("%s", msg[++msgid]); /* -3 */ -#endif -#ifdef HAVE_TRUSTED_CA - printf("-5 Use Trusted CA Key Indication\n"); #endif printf("%s", msg[++msgid]); /* -1 */ #if !defined(NO_DH) && !defined(HAVE_FIPS) && \ @@ -1302,6 +1307,9 @@ static void Usage(void) #ifdef HAVE_SECURE_RENEGOTIATION printf("%s", msg[++msgid]); /* -4 */ #endif +#ifdef HAVE_TRUSTED_CA + printf("%s", msg[++msgid]); /* -5 */ +#endif } THREAD_RETURN WOLFSSL_THREAD client_test(void* args) diff --git a/examples/server/server.c b/examples/server/server.c index 8e4221e8f..4eda55701 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -594,6 +594,9 @@ static const char* server_usage_msg[][49] = { #endif "-1 Display a result by specified language." "\n 0: English, 1: Japanese\n", /* 48 */ +#ifdef HAVE_TRUSTED_CA + "-5 Use Trusted CA Key Indication\n", /* 51 */ +#endif NULL, }, #ifndef NO_MULTIBYTE_PRINT @@ -709,10 +712,12 @@ static const char* server_usage_msg[][49] = { #endif "-1 指定された言語で結果を表示します。" "\n 0: 英語、 1: 日本語\n", /* 48 */ +#ifdef HAVE_TRUSTED_CA + "-5 信頼できる認証局の鍵表示を使用する\n", /* 51 */ +#endif NULL, }, #endif - }; static void Usage(void) @@ -826,7 +831,7 @@ static void Usage(void) #endif printf("%s", msg[++msgId]); /* -1 */ #ifdef HAVE_TRUSTED_CA - printf("-5 Use Trusted CA Key Indication\n"); + printf("%s", msg[++msgId]); /* -5 */ #endif /* HAVE_TRUSTED_CA */ } From 8a4e8067f62a5e6b2f31490c156c86e5c8eef0a7 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Thu, 21 Feb 2019 11:40:46 -0800 Subject: [PATCH 6/8] 1. In the trusted CA extension code, add guards for NO_SHA around the cases that use SHA-1. 2. Check the trusted CA id pointer for NULL before copying. 3. Updated the api test for the NO_SHA change. 4. Remove the TCA options member as redundant. --- src/tls.c | 36 ++++++++++++++++++++++++++++++------ tests/api.c | 6 ++++++ wolfssl/internal.h | 3 --- 3 files changed, 36 insertions(+), 9 deletions(-) diff --git a/src/tls.c b/src/tls.c index 6e9049a4f..0abad816a 100644 --- a/src/tls.c +++ b/src/tls.c @@ -2324,6 +2324,7 @@ static TCA* TLSX_TCA_New(byte type, const byte* id, word16 idSz, void* heap) case WOLFSSL_TRUSTED_CA_PRE_AGREED: break; + #ifndef NO_SHA case WOLFSSL_TRUSTED_CA_KEY_SHA1: case WOLFSSL_TRUSTED_CA_CERT_SHA1: if (idSz == SHA_DIGEST_SIZE && @@ -2337,6 +2338,7 @@ static TCA* TLSX_TCA_New(byte type, const byte* id, word16 idSz, void* heap) tca = NULL; } break; + #endif case WOLFSSL_TRUSTED_CA_X509_NAME: if (idSz > 0 && @@ -2424,17 +2426,37 @@ static word16 TLSX_TCA_Write(TCA* list, byte* output) switch (tca->type) { case WOLFSSL_TRUSTED_CA_PRE_AGREED: break; + #ifndef NO_SHA case WOLFSSL_TRUSTED_CA_KEY_SHA1: case WOLFSSL_TRUSTED_CA_CERT_SHA1: - XMEMCPY(output + offset, tca->id, tca->idSz); - offset += tca->idSz; + if (tca->id != NULL) { + XMEMCPY(output + offset, tca->id, tca->idSz); + offset += tca->idSz; + } + else { + /* ID missing. Set to an empty string. */ + c16toa(0, output + offset); + offset += OPAQUE16_LEN; + } break; + #endif case WOLFSSL_TRUSTED_CA_X509_NAME: - c16toa(tca->idSz, output + offset); /* tca length */ - offset += OPAQUE16_LEN; - XMEMCPY(output + offset, tca->id, tca->idSz); - offset += tca->idSz; + if (tca->id != NULL) { + c16toa(tca->idSz, output + offset); /* tca length */ + offset += OPAQUE16_LEN; + XMEMCPY(output + offset, tca->id, tca->idSz); + offset += tca->idSz; + } + else { + /* ID missing. Set to an empty string. */ + c16toa(0, output + offset); + offset += OPAQUE16_LEN; + } break; + default: + /* ID unknown. Set to an empty string. */ + c16toa(0, output + offset); + offset += OPAQUE16_LEN; } } @@ -2513,6 +2535,7 @@ static int TLSX_TCA_Parse(WOLFSSL* ssl, const byte* input, word16 length, switch (type) { case WOLFSSL_TRUSTED_CA_PRE_AGREED: break; + #ifndef NO_SHA case WOLFSSL_TRUSTED_CA_KEY_SHA1: case WOLFSSL_TRUSTED_CA_CERT_SHA1: if (offset + SHA_DIGEST_SIZE > length) @@ -2521,6 +2544,7 @@ static int TLSX_TCA_Parse(WOLFSSL* ssl, const byte* input, word16 length, id = input + offset; offset += idSz; break; + #endif case WOLFSSL_TRUSTED_CA_X509_NAME: if (offset + OPAQUE16_LEN > length) return BUFFER_ERROR; diff --git a/tests/api.c b/tests/api.c index da5767174..9d5dcb4e6 100644 --- a/tests/api.c +++ b/tests/api.c @@ -3044,14 +3044,20 @@ static void test_wolfSSL_UseTrustedCA(void) WOLFSSL_TRUSTED_CA_CERT_SHA1, NULL, 0)); AssertIntNE(WOLFSSL_SUCCESS, wolfSSL_UseTrustedCA(ssl, WOLFSSL_TRUSTED_CA_CERT_SHA1, id, 5)); +#ifdef NO_SHA + AssertIntNE(WOLFSSL_SUCCESS, wolfSSL_UseTrustedCA(ssl, + WOLFSSL_TRUSTED_CA_KEY_SHA1, id, sizeof(id))); +#endif AssertIntNE(WOLFSSL_SUCCESS, wolfSSL_UseTrustedCA(ssl, WOLFSSL_TRUSTED_CA_X509_NAME, id, 0)); /* success cases */ AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_UseTrustedCA(ssl, WOLFSSL_TRUSTED_CA_PRE_AGREED, NULL, 0)); +#ifndef NO_SHA AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_UseTrustedCA(ssl, WOLFSSL_TRUSTED_CA_KEY_SHA1, id, sizeof(id))); +#endif AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_UseTrustedCA(ssl, WOLFSSL_TRUSTED_CA_X509_NAME, id, 5)); diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 6280d9712..b81054044 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2177,9 +2177,6 @@ typedef struct TCA { byte* id; /* TCA identifier */ word16 idSz; /* TCA identifier size */ struct TCA* next; /* List Behavior */ -#ifndef NO_WOLFSSL_CLIENT - byte options; /* Behavior options */ -#endif /* NO_WOLFSSL_CLIENT */ } TCA; WOLFSSL_LOCAL int TLSX_UseTrustedCA(TLSX** extensions, byte type, From 9bd40353c235611861c7576ea785cac899ad0c67 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Tue, 26 Feb 2019 10:06:53 -0800 Subject: [PATCH 7/8] 1. Rename the parameters cert and certSz on the function wolfSSL_UseTrustedCA() to certId and certIdSz. 2. Add better parameter checking to wolfSSL_UseTrustedCA() based on the ID type. --- src/ssl.c | 23 +++++++++++++++++++++-- wolfssl/ssl.h | 2 +- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index dc9bb37f8..bb8cdf5ae 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -1963,12 +1963,31 @@ int wolfSSL_SNI_GetFromBuffer(const byte* clientHello, word32 helloSz, #ifdef HAVE_TRUSTED_CA WOLFSSL_API int wolfSSL_UseTrustedCA(WOLFSSL* ssl, byte type, - const byte* cert, word32 certSz) + const byte* certId, word32 certIdSz) { if (ssl == NULL) return BAD_FUNC_ARG; - return TLSX_UseTrustedCA(&ssl->extensions, type, cert, certSz, ssl->heap); + if (type == WOLFSSL_TRUSTED_CA_PRE_AGREED) { + if (certId != NULL || certIdSz != 0) + return BAD_FUNC_ARG; + } + else if (type == WOLFSSL_TRUSTED_CA_X509_NAME) { + if (certId == NULL || certIdSz == 0) + return BAD_FUNC_ARG; + } + #ifndef NO_SHA + else if (type == WOLFSSL_TRUSTED_CA_KEY_SHA1 || + type == WOLFSSL_TRUSTED_CA_CERT_SHA1) { + if (certId == NULL || certIdSz != SHA_DIGEST_SIZE) + return BAD_FUNC_ARG; + } + #endif + else + return BAD_FUNC_ARG; + + return TLSX_UseTrustedCA(&ssl->extensions, + type, certId, certIdSz, ssl->heap); } #endif /* HAVE_TRUSTED_CA */ diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 16baa6394..ec1a0bee0 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -2260,7 +2260,7 @@ enum { }; WOLFSSL_API int wolfSSL_UseTrustedCA(WOLFSSL* ssl, unsigned char type, - const unsigned char* cert, unsigned int certSz); + const unsigned char* certId, unsigned int certIdSz); #endif /* HAVE_TRUSTED_CA */ /* Application-Layer Protocol Negotiation */ From 1eb46c697f064802f10c110cc19d741dc1343933 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Thu, 28 Feb 2019 16:15:47 -0800 Subject: [PATCH 8/8] 1. In the loop in TCA parse, when checking the list of IDs that the server has keys for, change the polarity of the comparison. If the current ID is in the list, set the response flag and break out of the loop. --- src/tls.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/tls.c b/src/tls.c index 0abad816a..8c048cf90 100644 --- a/src/tls.c +++ b/src/tls.c @@ -2559,11 +2559,13 @@ static int TLSX_TCA_Parse(WOLFSSL* ssl, const byte* input, word16 length, return TCA_INVALID_ID_TYPE; } + /* Find the type/ID in the TCA list. */ tca = TLSX_TCA_Find((TCA*)extension->data, type, id, idSz); - if (!tca) - continue; - - TLSX_SetResponse(ssl, TLSX_TRUSTED_CA_KEYS); + if (tca != NULL) { + /* Found it. Set the response flag and break out of the loop. */ + TLSX_SetResponse(ssl, TLSX_TRUSTED_CA_KEYS); + break; + } } #else (void)input; @@ -2572,6 +2574,7 @@ static int TLSX_TCA_Parse(WOLFSSL* ssl, const byte* input, word16 length, return 0; } +/* Checks to see if the server sent a response for the TCA. */ static int TLSX_TCA_VerifyParse(WOLFSSL* ssl, byte isRequest) { (void)ssl;