forked from wolfSSL/wolfssl
ALPN : add option to continue in case of client/server protocol mismatch (like OpenSSL)
This commit is contained in:
@ -194,7 +194,7 @@ static void Usage(void)
|
||||
printf("-C Disable CRL\n");
|
||||
#endif
|
||||
#ifdef HAVE_ALPN
|
||||
printf("-n <str> Application-Layer Protocole Name\n");
|
||||
printf("-n <str> Application-Layer Protocole Name ({C,F}:<list>)\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -247,6 +247,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
||||
int overrideDateErrors = 0;
|
||||
int minDhKeyBits = DEFAULT_MIN_DHKEY_BITS;
|
||||
char* alpnList = NULL;
|
||||
unsigned char alpn_opt = 0;
|
||||
char* cipherList = NULL;
|
||||
const char* verifyCert = caCert;
|
||||
const char* ourCert = cliCert;
|
||||
@ -294,6 +295,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
||||
(void)disableCRL;
|
||||
(void)minDhKeyBits;
|
||||
(void)alpnList;
|
||||
(void)alpn_opt;
|
||||
|
||||
StackTrap();
|
||||
|
||||
@ -500,6 +502,18 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
||||
case 'n' :
|
||||
#ifdef HAVE_ALPN
|
||||
alpnList = myoptarg;
|
||||
|
||||
if (alpnList[0] == 'C' && alpnList[1] == ':')
|
||||
alpn_opt = WOLFSSL_ALPN_CONTINUE_ON_MISMATCH;
|
||||
else if (alpnList[0] == 'F' && alpnList[1] == ':')
|
||||
alpn_opt = WOLFSSL_ALPN_FAILED_ON_MISMATCH;
|
||||
else {
|
||||
Usage();
|
||||
exit(MY_EX_USAGE);
|
||||
}
|
||||
|
||||
alpnList += 2;
|
||||
|
||||
#endif
|
||||
break;
|
||||
|
||||
@ -812,7 +826,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
||||
#ifdef HAVE_ALPN
|
||||
if (alpnList != NULL) {
|
||||
printf("ALPN accepted protocols list : %s\n", alpnList);
|
||||
wolfSSL_UseALPN(ssl, alpnList, (word32)XSTRLEN(alpnList));
|
||||
wolfSSL_UseALPN(ssl, alpnList, (word32)XSTRLEN(alpnList), alpn_opt);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -885,16 +899,19 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
||||
showPeer(ssl);
|
||||
|
||||
#ifdef HAVE_ALPN
|
||||
{
|
||||
if (alpnList != NULL) {
|
||||
int err;
|
||||
char *protocol_name = NULL;
|
||||
word16 protocol_nameSz = 0;
|
||||
|
||||
if (wolfSSL_ALPN_GetProtocol(ssl, &protocol_name,
|
||||
&protocol_nameSz) != SSL_SUCCESS)
|
||||
printf("Getting ALPN protocol name failed\n");
|
||||
else
|
||||
err = wolfSSL_ALPN_GetProtocol(ssl, &protocol_name, &protocol_nameSz);
|
||||
if (err == SSL_SUCCESS)
|
||||
printf("Received ALPN protocol : %s (%d)\n",
|
||||
protocol_name, protocol_nameSz);
|
||||
else if (err == SSL_ALPN_NOT_FOUND)
|
||||
printf("Not received ALPN response (no match with server)\n");
|
||||
else
|
||||
printf("Getting ALPN protocol name failed\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -988,7 +1005,8 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
||||
#ifdef HAVE_ALPN
|
||||
if (alpnList != NULL) {
|
||||
printf("ALPN accepted protocols list : %s\n", alpnList);
|
||||
wolfSSL_UseALPN(sslResume, alpnList, (word32)XSTRLEN(alpnList));
|
||||
wolfSSL_UseALPN(sslResume, alpnList, (word32)XSTRLEN(alpnList),
|
||||
alpn_opt);
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_SECURE_RENEGOTIATION
|
||||
@ -1024,17 +1042,21 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
||||
printf("didn't reuse session id!!!\n");
|
||||
|
||||
#ifdef HAVE_ALPN
|
||||
{
|
||||
if (alpnList != NULL) {
|
||||
int err;
|
||||
char *protocol_name = NULL;
|
||||
word16 protocol_nameSz = 0;
|
||||
|
||||
printf("Sending ALPN accepted list : %s\n", alpnList);
|
||||
if (wolfSSL_ALPN_GetProtocol(sslResume, &protocol_name,
|
||||
&protocol_nameSz) != SSL_SUCCESS)
|
||||
printf("Getting ALPN protocol name failed\n");
|
||||
else
|
||||
err = wolfSSL_ALPN_GetProtocol(sslResume, &protocol_name,
|
||||
&protocol_nameSz);
|
||||
if (err == SSL_SUCCESS)
|
||||
printf("Received ALPN protocol : %s (%d)\n",
|
||||
protocol_name, protocol_nameSz);
|
||||
else if (err == SSL_ALPN_NOT_FOUND)
|
||||
printf("Not received ALPN response (no match with server)\n");
|
||||
else
|
||||
printf("Getting ALPN protocol name failed\n");
|
||||
}
|
||||
#endif
|
||||
if (wolfSSL_write(sslResume, resumeMsg, resumeSz) != resumeSz)
|
||||
|
@ -162,7 +162,7 @@ static void Usage(void)
|
||||
printf("-I Do not send PSK identity hint\n");
|
||||
#endif
|
||||
#ifdef HAVE_ALPN
|
||||
printf("-L <str> Application-Layer Protocole Name\n");
|
||||
printf("-L <str> Application-Layer Protocole Name ({C,F}:<list>)\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -198,6 +198,7 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args)
|
||||
int minDhKeyBits = DEFAULT_MIN_DHKEY_BITS;
|
||||
int ret;
|
||||
char* alpnList = NULL;
|
||||
unsigned char alpn_opt = 0;
|
||||
char* cipherList = NULL;
|
||||
const char* verifyCert = cliCert;
|
||||
const char* ourCert = svrCert;
|
||||
@ -237,6 +238,7 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args)
|
||||
(void)doCliCertCheck;
|
||||
(void)minDhKeyBits;
|
||||
(void)alpnList;
|
||||
(void)alpn_opt;
|
||||
|
||||
#ifdef CYASSL_TIRTOS
|
||||
fdOpenSession(Task_self());
|
||||
@ -384,6 +386,18 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args)
|
||||
case 'L' :
|
||||
#ifdef HAVE_ALPN
|
||||
alpnList = myoptarg;
|
||||
|
||||
if (alpnList[0] == 'C' && alpnList[1] == ':')
|
||||
alpn_opt = WOLFSSL_ALPN_CONTINUE_ON_MISMATCH;
|
||||
else if (alpnList[0] == 'F' && alpnList[1] == ':')
|
||||
alpn_opt = WOLFSSL_ALPN_FAILED_ON_MISMATCH;
|
||||
else {
|
||||
Usage();
|
||||
exit(MY_EX_USAGE);
|
||||
}
|
||||
|
||||
alpnList += 2;
|
||||
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
@ -636,7 +650,7 @@ while (1) { /* allow resume option */
|
||||
#ifdef HAVE_ALPN
|
||||
if (alpnList != NULL) {
|
||||
printf("ALPN accepted protocols list : %s\n", alpnList);
|
||||
wolfSSL_UseALPN(ssl, alpnList, (word32)XSTRLEN(alpnList));
|
||||
wolfSSL_UseALPN(ssl, alpnList, (word32)XSTRLEN(alpnList), alpn_opt);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -683,16 +697,19 @@ while (1) { /* allow resume option */
|
||||
showPeer(ssl);
|
||||
|
||||
#ifdef HAVE_ALPN
|
||||
{
|
||||
if (alpnList != NULL) {
|
||||
int err;
|
||||
char *protocol_name = NULL;
|
||||
word16 protocol_nameSz = 0;
|
||||
|
||||
if (wolfSSL_ALPN_GetProtocol(ssl, &protocol_name,
|
||||
&protocol_nameSz) != SSL_SUCCESS)
|
||||
printf("Getting ALPN protocol name failed\n");
|
||||
else
|
||||
err = wolfSSL_ALPN_GetProtocol(ssl, &protocol_name, &protocol_nameSz);
|
||||
if (err == SSL_SUCCESS)
|
||||
printf("Send ALPN protocol : %s (%d)\n",
|
||||
protocol_name, protocol_nameSz);
|
||||
else if (err == SSL_ALPN_NOT_FOUND)
|
||||
printf("Not send ALPN response (no match with server)\n");
|
||||
else
|
||||
printf("Getting ALPN protocol name failed\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
13
src/ssl.c
13
src/ssl.c
@ -889,7 +889,7 @@ int wolfSSL_UseSupportedQSH(WOLFSSL* ssl, word16 name)
|
||||
#ifdef HAVE_ALPN
|
||||
|
||||
int wolfSSL_UseALPN(WOLFSSL* ssl, char *protocol_name_list,
|
||||
word32 protocol_name_listSz)
|
||||
word32 protocol_name_listSz, byte options)
|
||||
{
|
||||
char *list, *ptr, *token[10];
|
||||
word16 len;
|
||||
@ -904,10 +904,17 @@ int wolfSSL_UseALPN(WOLFSSL* ssl, char *protocol_name_list,
|
||||
if (protocol_name_listSz > (WOLFSSL_MAX_ALPN_NUMBER *
|
||||
WOLFSSL_MAX_ALPN_PROTO_NAME_LEN +
|
||||
WOLFSSL_MAX_ALPN_NUMBER)) {
|
||||
WOLFSSL_MSG("Invalid arguments, procolt name list too long");
|
||||
WOLFSSL_MSG("Invalid arguments, protocol name list too long");
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (!(options & WOLFSSL_ALPN_CONTINUE_ON_MISMATCH) &&
|
||||
!(options & WOLFSSL_ALPN_FAILED_ON_MISMATCH)) {
|
||||
WOLFSSL_MSG("Invalid arguments, options not supported");
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
|
||||
list = (char *)XMALLOC(protocol_name_listSz+1, NULL,
|
||||
DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (list == NULL) {
|
||||
@ -927,7 +934,7 @@ int wolfSSL_UseALPN(WOLFSSL* ssl, char *protocol_name_list,
|
||||
while ((idx--) > 0) {
|
||||
len = (word16)XSTRLEN(token[idx]);
|
||||
|
||||
ret = TLSX_UseALPN(&ssl->extensions, token[idx], len);
|
||||
ret = TLSX_UseALPN(&ssl->extensions, token[idx], len, options);
|
||||
if (ret != SSL_SUCCESS) {
|
||||
WOLFSSL_MSG("TLSX_UseALPN failure");
|
||||
break;
|
||||
|
45
src/tls.c
45
src/tls.c
@ -867,6 +867,8 @@ static ALPN* TLSX_ALPN_New(char *protocol_name, word16 protocol_nameSz)
|
||||
}
|
||||
|
||||
alpn->next = NULL;
|
||||
alpn->negociated = 0;
|
||||
alpn->options = 0;
|
||||
|
||||
alpn->protocol_name = XMALLOC(protocol_nameSz + 1, 0, DYNAMIC_TYPE_TLSX);
|
||||
if (alpn->protocol_name == NULL) {
|
||||
@ -977,6 +979,8 @@ static int TLSX_SetALPN(TLSX** extensions, const void* data, word16 size)
|
||||
return MEMORY_E;
|
||||
}
|
||||
|
||||
alpn->negociated = 1;
|
||||
|
||||
ret = TLSX_Push(extensions, WOLFSSL_ALPN, (void*)alpn);
|
||||
if (ret != 0) {
|
||||
TLSX_ALPN_Free(alpn);
|
||||
@ -995,7 +999,7 @@ static int TLSX_ALPN_ParseAndSet(WOLFSSL *ssl, byte *input, word16 length,
|
||||
word16 offset = 0;
|
||||
int r = BUFFER_ERROR;
|
||||
TLSX *extension;
|
||||
ALPN *alpn = NULL;
|
||||
ALPN *alpn = NULL, *list;
|
||||
|
||||
extension = TLSX_Find(ssl->extensions, WOLFSSL_ALPN);
|
||||
if (extension == NULL)
|
||||
@ -1017,14 +1021,15 @@ static int TLSX_ALPN_ParseAndSet(WOLFSSL *ssl, byte *input, word16 length,
|
||||
if (length != OPAQUE16_LEN + size)
|
||||
return BUFFER_ERROR;
|
||||
|
||||
list = (ALPN*)extension->data;
|
||||
|
||||
for (size = 0; offset < length; offset += size) {
|
||||
|
||||
size = input[offset++];
|
||||
if (offset + size > length)
|
||||
return BUFFER_ERROR;
|
||||
|
||||
alpn = TLSX_ALPN_Find((ALPN*)extension->data,
|
||||
(char*)input + offset, size);
|
||||
alpn = TLSX_ALPN_Find(list, (char*)input + offset, size);
|
||||
if (alpn != NULL) {
|
||||
WOLFSSL_MSG("ALPN protocol match");
|
||||
break;
|
||||
@ -1034,13 +1039,21 @@ static int TLSX_ALPN_ParseAndSet(WOLFSSL *ssl, byte *input, word16 length,
|
||||
if (alpn == NULL) {
|
||||
WOLFSSL_MSG("No ALPN protocol match");
|
||||
|
||||
/* do nothing if no protocol match between client and server and option
|
||||
is set to continue (like OpenSSL) */
|
||||
if (list->options & WOLFSSL_ALPN_CONTINUE_ON_MISMATCH) {
|
||||
WOLFSSL_MSG("Continue on mismatch");
|
||||
return 0;
|
||||
}
|
||||
|
||||
SendAlert(ssl, alert_fatal, no_application_protocol);
|
||||
return UNKNOWN_ALPN_PROTOCOL_NAME_E;
|
||||
}
|
||||
|
||||
/* set the matching negociated protocol */
|
||||
r = TLSX_SetALPN(&ssl->extensions,
|
||||
alpn->protocol_name, (word16)XSTRLEN(alpn->protocol_name));
|
||||
alpn->protocol_name,
|
||||
(word16)XSTRLEN(alpn->protocol_name));
|
||||
if (r != SSL_SUCCESS) {
|
||||
WOLFSSL_MSG("TLSX_UseALPN failed");
|
||||
return BUFFER_ERROR;
|
||||
@ -1057,7 +1070,7 @@ static int TLSX_ALPN_ParseAndSet(WOLFSSL *ssl, byte *input, word16 length,
|
||||
}
|
||||
|
||||
/** Add a protocol name to the list of accepted usable ones */
|
||||
int TLSX_UseALPN(TLSX** extensions, const void* data, word16 size)
|
||||
int TLSX_UseALPN(TLSX** extensions, const void* data, word16 size, byte options)
|
||||
{
|
||||
ALPN *alpn;
|
||||
TLSX *extension;
|
||||
@ -1072,6 +1085,9 @@ int TLSX_UseALPN(TLSX** extensions, const void* data, word16 size)
|
||||
return MEMORY_E;
|
||||
}
|
||||
|
||||
/* Set Options of ALPN */
|
||||
alpn->options = options;
|
||||
|
||||
extension = TLSX_Find(*extensions, WOLFSSL_ALPN);
|
||||
if (extension == NULL) {
|
||||
ret = TLSX_Push(extensions, WOLFSSL_ALPN, (void*)alpn);
|
||||
@ -1101,13 +1117,28 @@ int TLSX_ALPN_GetRequest(TLSX* extensions, void** data, word16 *dataSz)
|
||||
extension = TLSX_Find(extensions, WOLFSSL_ALPN);
|
||||
if (extension == NULL) {
|
||||
WOLFSSL_MSG("TLS extension not found");
|
||||
return SSL_FATAL_ERROR;
|
||||
return SSL_ALPN_NOT_FOUND;
|
||||
}
|
||||
|
||||
alpn = (ALPN *)extension->data;
|
||||
if (alpn == NULL) {
|
||||
WOLFSSL_MSG("ALPN extension not found");
|
||||
return WOLFSSL_ALPN_NO_MATCH;
|
||||
*data = NULL;
|
||||
*dataSz = 0;
|
||||
return SSL_FATAL_ERROR;
|
||||
}
|
||||
|
||||
if (alpn->negociated != 1) {
|
||||
|
||||
/* consider as an error */
|
||||
if (alpn->options & WOLFSSL_ALPN_FAILED_ON_MISMATCH) {
|
||||
WOLFSSL_MSG("No protocol match with peer -> Failed");
|
||||
return SSL_FATAL_ERROR;
|
||||
}
|
||||
|
||||
/* continue without negociated protocol */
|
||||
WOLFSSL_MSG("No protocol match with peer -> Continue");
|
||||
return SSL_ALPN_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (alpn->next != NULL) {
|
||||
|
74
tests/api.c
74
tests/api.c
@ -1215,7 +1215,19 @@ static void use_ALPN_all(WOLFSSL* ssl)
|
||||
0x73, 0x70, 0x64, 0x79, 0x2f, 0x31, 0x2c,
|
||||
0x73, 0x70, 0x64, 0x79, 0x2f, 0x32, 0x2c,
|
||||
0x73, 0x70, 0x64, 0x79, 0x2f, 0x33};
|
||||
AssertIntEQ(SSL_SUCCESS, wolfSSL_UseALPN(ssl, alpn_list, sizeof(alpn_list)));
|
||||
AssertIntEQ(SSL_SUCCESS, wolfSSL_UseALPN(ssl, alpn_list, sizeof(alpn_list),
|
||||
WOLFSSL_ALPN_FAILED_ON_MISMATCH));
|
||||
}
|
||||
|
||||
static void use_ALPN_all_continue(WOLFSSL* ssl)
|
||||
{
|
||||
/* http/1.1,spdy/1,spdy/2,spdy/3 */
|
||||
char alpn_list[] = {0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31, 0x2c,
|
||||
0x73, 0x70, 0x64, 0x79, 0x2f, 0x31, 0x2c,
|
||||
0x73, 0x70, 0x64, 0x79, 0x2f, 0x32, 0x2c,
|
||||
0x73, 0x70, 0x64, 0x79, 0x2f, 0x33};
|
||||
AssertIntEQ(SSL_SUCCESS, wolfSSL_UseALPN(ssl, alpn_list, sizeof(alpn_list),
|
||||
WOLFSSL_ALPN_CONTINUE_ON_MISMATCH));
|
||||
}
|
||||
|
||||
static void use_ALPN_one(WOLFSSL* ssl)
|
||||
@ -1223,7 +1235,8 @@ static void use_ALPN_one(WOLFSSL* ssl)
|
||||
/* spdy/2 */
|
||||
char proto[] = {0x73, 0x70, 0x64, 0x79, 0x2f, 0x32};
|
||||
|
||||
AssertIntEQ(SSL_SUCCESS, wolfSSL_UseALPN(ssl, proto, sizeof(proto)));
|
||||
AssertIntEQ(SSL_SUCCESS, wolfSSL_UseALPN(ssl, proto, sizeof(proto),
|
||||
WOLFSSL_ALPN_FAILED_ON_MISMATCH));
|
||||
}
|
||||
|
||||
static void use_ALPN_unknown(WOLFSSL* ssl)
|
||||
@ -1231,7 +1244,17 @@ static void use_ALPN_unknown(WOLFSSL* ssl)
|
||||
/* http/2.0 */
|
||||
char proto[] = {0x68, 0x74, 0x74, 0x70, 0x2f, 0x32, 0x2e, 0x30};
|
||||
|
||||
AssertIntEQ(SSL_SUCCESS, wolfSSL_UseALPN(ssl, proto, sizeof(proto)));
|
||||
AssertIntEQ(SSL_SUCCESS, wolfSSL_UseALPN(ssl, proto, sizeof(proto),
|
||||
WOLFSSL_ALPN_FAILED_ON_MISMATCH));
|
||||
}
|
||||
|
||||
static void use_ALPN_unknown_continue(WOLFSSL* ssl)
|
||||
{
|
||||
/* http/2.0 */
|
||||
char proto[] = {0x68, 0x74, 0x74, 0x70, 0x2f, 0x32, 0x2e, 0x30};
|
||||
|
||||
AssertIntEQ(SSL_SUCCESS, wolfSSL_UseALPN(ssl, proto, sizeof(proto),
|
||||
WOLFSSL_ALPN_CONTINUE_ON_MISMATCH));
|
||||
}
|
||||
|
||||
static void verify_ALPN_not_matching_spdy3(WOLFSSL* ssl)
|
||||
@ -1242,9 +1265,6 @@ static void verify_ALPN_not_matching_spdy3(WOLFSSL* ssl)
|
||||
char *proto;
|
||||
word16 protoSz = 0;
|
||||
|
||||
printf("verify_ALPN_not_matching GetProtocol(ssl) = %d\n",
|
||||
wolfSSL_ALPN_GetProtocol(ssl, &proto, &protoSz));
|
||||
|
||||
AssertIntEQ(SSL_SUCCESS, wolfSSL_ALPN_GetProtocol(ssl, &proto, &protoSz));
|
||||
|
||||
/* check value */
|
||||
@ -1252,6 +1272,19 @@ static void verify_ALPN_not_matching_spdy3(WOLFSSL* ssl)
|
||||
AssertIntNE(0, XMEMCMP(nego_proto, proto, sizeof(nego_proto)));
|
||||
}
|
||||
|
||||
static void verify_ALPN_not_matching_continue(WOLFSSL* ssl)
|
||||
{
|
||||
char *proto = NULL;
|
||||
word16 protoSz = 0;
|
||||
|
||||
AssertIntEQ(SSL_ALPN_NOT_FOUND,
|
||||
wolfSSL_ALPN_GetProtocol(ssl, &proto, &protoSz));
|
||||
|
||||
/* check value */
|
||||
AssertIntEQ(1, 0 == protoSz);
|
||||
AssertIntEQ(1, NULL == proto);
|
||||
}
|
||||
|
||||
static void verify_ALPN_matching_http1(WOLFSSL* ssl)
|
||||
{
|
||||
/* http/1.1 */
|
||||
@ -1259,9 +1292,6 @@ static void verify_ALPN_matching_http1(WOLFSSL* ssl)
|
||||
char *proto;
|
||||
word16 protoSz = 0;
|
||||
|
||||
printf("verify_ALPN_matching GetProtocol(ssl) = %d\n",
|
||||
wolfSSL_ALPN_GetProtocol(ssl, &proto, &protoSz));
|
||||
|
||||
AssertIntEQ(SSL_SUCCESS, wolfSSL_ALPN_GetProtocol(ssl, &proto, &protoSz));
|
||||
|
||||
/* check value */
|
||||
@ -1276,9 +1306,6 @@ static void verify_ALPN_matching_spdy2(WOLFSSL* ssl)
|
||||
char *proto;
|
||||
word16 protoSz = 0;
|
||||
|
||||
printf("verify_ALPN_matching GetProtocol(ssl) = %d\n",
|
||||
wolfSSL_ALPN_GetProtocol(ssl, &proto, &protoSz));
|
||||
|
||||
AssertIntEQ(SSL_SUCCESS, wolfSSL_ALPN_GetProtocol(ssl, &proto, &protoSz));
|
||||
|
||||
/* check value */
|
||||
@ -1286,7 +1313,6 @@ static void verify_ALPN_matching_spdy2(WOLFSSL* ssl)
|
||||
AssertIntEQ(0, XMEMCMP(nego_proto, proto, protoSz));
|
||||
}
|
||||
|
||||
|
||||
static void test_wolfSSL_UseALPN_connection(void)
|
||||
{
|
||||
unsigned long i;
|
||||
@ -1307,6 +1333,10 @@ static void test_wolfSSL_UseALPN_connection(void)
|
||||
{0, 0, 0, 0},
|
||||
{0, 0, use_ALPN_all, 0},
|
||||
|
||||
/* success case missmatch behavior but option 'continue' set */
|
||||
{0, 0, use_ALPN_all_continue, verify_ALPN_not_matching_continue},
|
||||
{0, 0, use_ALPN_unknown_continue, 0},
|
||||
|
||||
/* missmatch behavior with same list
|
||||
* the first and only this one must be taken */
|
||||
{0, 0, use_ALPN_all, 0},
|
||||
@ -1345,13 +1375,16 @@ static void test_wolfSSL_UseALPN_params(void)
|
||||
|
||||
/* error cases */
|
||||
AssertIntNE(SSL_SUCCESS,
|
||||
wolfSSL_UseALPN(NULL, http1, sizeof(http1)));
|
||||
AssertIntNE(SSL_SUCCESS, wolfSSL_UseALPN(ssl, NULL, 0));
|
||||
wolfSSL_UseALPN(NULL, http1, sizeof(http1),
|
||||
WOLFSSL_ALPN_FAILED_ON_MISMATCH));
|
||||
AssertIntNE(SSL_SUCCESS, wolfSSL_UseALPN(ssl, NULL, 0,
|
||||
WOLFSSL_ALPN_FAILED_ON_MISMATCH));
|
||||
|
||||
/* success case */
|
||||
/* http1 only */
|
||||
AssertIntEQ(SSL_SUCCESS,
|
||||
wolfSSL_UseALPN(ssl, http1, sizeof(http1)));
|
||||
wolfSSL_UseALPN(ssl, http1, sizeof(http1),
|
||||
WOLFSSL_ALPN_FAILED_ON_MISMATCH));
|
||||
|
||||
/* http1, spdy1 */
|
||||
memcpy(buff, http1, sizeof(http1));
|
||||
@ -1359,7 +1392,8 @@ static void test_wolfSSL_UseALPN_params(void)
|
||||
buff[idx++] = ',';
|
||||
memcpy(buff+idx, spdy1, sizeof(spdy1));
|
||||
idx += sizeof(spdy1);
|
||||
AssertIntEQ(SSL_SUCCESS, wolfSSL_UseALPN(ssl, buff, idx));
|
||||
AssertIntEQ(SSL_SUCCESS, wolfSSL_UseALPN(ssl, buff, idx,
|
||||
WOLFSSL_ALPN_FAILED_ON_MISMATCH));
|
||||
|
||||
/* http1, spdy2, spdy1 */
|
||||
memcpy(buff, http1, sizeof(http1));
|
||||
@ -1370,7 +1404,8 @@ static void test_wolfSSL_UseALPN_params(void)
|
||||
buff[idx++] = ',';
|
||||
memcpy(buff+idx, spdy1, sizeof(spdy1));
|
||||
idx += sizeof(spdy1);
|
||||
AssertIntEQ(SSL_SUCCESS, wolfSSL_UseALPN(ssl, buff, idx));
|
||||
AssertIntEQ(SSL_SUCCESS, wolfSSL_UseALPN(ssl, buff, idx,
|
||||
WOLFSSL_ALPN_FAILED_ON_MISMATCH));
|
||||
|
||||
/* spdy3, http1, spdy2, spdy1 */
|
||||
memcpy(buff, spdy3, sizeof(spdy3));
|
||||
@ -1384,7 +1419,8 @@ static void test_wolfSSL_UseALPN_params(void)
|
||||
buff[idx++] = ',';
|
||||
memcpy(buff+idx, spdy1, sizeof(spdy1));
|
||||
idx += sizeof(spdy1);
|
||||
AssertIntEQ(SSL_SUCCESS, wolfSSL_UseALPN(ssl, buff, idx));
|
||||
AssertIntEQ(SSL_SUCCESS, wolfSSL_UseALPN(ssl, buff, idx,
|
||||
WOLFSSL_ALPN_CONTINUE_ON_MISMATCH));
|
||||
|
||||
wolfSSL_free(ssl);
|
||||
wolfSSL_CTX_free(ctx);
|
||||
|
@ -1540,13 +1540,17 @@ WOLFSSL_LOCAL int TLSX_SNI_GetFromBuffer(const byte* buffer, word32 bufferSz,
|
||||
typedef struct ALPN {
|
||||
char* protocol_name; /* ALPN protocol name */
|
||||
struct ALPN* next; /* List Behavior */
|
||||
byte options; /* Behaviour options */
|
||||
byte negociated; /* ALPN protocol negociated or not */
|
||||
} ALPN;
|
||||
|
||||
WOLFSSL_LOCAL int TLSX_ALPN_GetRequest(TLSX* extensions,
|
||||
void** data, word16 *dataSz);
|
||||
|
||||
WOLFSSL_LOCAL int TLSX_UseALPN(TLSX** extensions, const void* data,
|
||||
word16 size);
|
||||
word16 size, byte options);
|
||||
|
||||
WOLFSSL_LOCAL int TLSX_ALPN_SetOptions(TLSX** extensions, const byte option);
|
||||
#endif /* HAVE_ALPN */
|
||||
|
||||
/* Maximum Fragment Length */
|
||||
|
@ -674,6 +674,7 @@ enum { /* ssl Constants */
|
||||
SSL_SUCCESS = 1,
|
||||
SSL_SHUTDOWN_NOT_DONE = 2, /* call wolfSSL_shutdown again to complete */
|
||||
|
||||
SSL_ALPN_NOT_FOUND = -9,
|
||||
SSL_BAD_CERTTYPE = -8,
|
||||
SSL_BAD_STAT = -7,
|
||||
SSL_BAD_PATH = -6,
|
||||
@ -1354,7 +1355,9 @@ WOLFSSL_API int wolfSSL_SNI_GetFromBuffer(
|
||||
/* ALPN status code */
|
||||
enum {
|
||||
WOLFSSL_ALPN_NO_MATCH = 0,
|
||||
WOLFSSL_ALPN_MATCH = 1
|
||||
WOLFSSL_ALPN_MATCH = 1,
|
||||
WOLFSSL_ALPN_CONTINUE_ON_MISMATCH = 2,
|
||||
WOLFSSL_ALPN_FAILED_ON_MISMATCH = 4,
|
||||
};
|
||||
|
||||
enum {
|
||||
@ -1363,7 +1366,8 @@ enum {
|
||||
};
|
||||
|
||||
WOLFSSL_API int wolfSSL_UseALPN(WOLFSSL* ssl, char *protocol_name_list,
|
||||
unsigned int protocol_name_listSz);
|
||||
unsigned int protocol_name_listSz,
|
||||
unsigned char options);
|
||||
|
||||
WOLFSSL_API int wolfSSL_ALPN_GetProtocol(WOLFSSL* ssl, char **protocol_name,
|
||||
unsigned short *size);
|
||||
|
Reference in New Issue
Block a user