From 0f66c90b54f6be35e2d6dedefb5e3fc0ea2aba35 Mon Sep 17 00:00:00 2001 From: jordan Date: Thu, 29 Sep 2022 23:04:31 -0500 Subject: [PATCH] implement sk_X509_shift for zd 14898 --- src/ssl.c | 2 +- src/x509.c | 39 ++++++++++++++++++++-- tests/api.c | 96 +++++++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 117 insertions(+), 20 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 7bcb8f95c..37f8aef27 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -19532,7 +19532,7 @@ WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_set_peer_cert_chain(WOLFSSL* ssl) else if (ssl->options.side == WOLFSSL_SERVER_END) { /* to be compliant with openssl first element is kept as peer cert on server side.*/ - wolfSSL_sk_X509_shift(sk); + wolfSSL_sk_X509_pop(sk); } #endif if (ssl->peerCertChain != NULL) diff --git a/src/x509.c b/src/x509.c index a7981ee4b..b76ac1173 100644 --- a/src/x509.c +++ b/src/x509.c @@ -3667,7 +3667,9 @@ int wolfSSL_sk_X509_push(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk, WOLFSSL_X509* x50 } -WOLFSSL_X509* wolfSSL_sk_X509_pop(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk) { +/* Return and remove the last x509 pushed on stack */ +WOLFSSL_X509* wolfSSL_sk_X509_pop(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk) +{ WOLFSSL_STACK* node; WOLFSSL_X509* x509; @@ -3714,9 +3716,42 @@ WOLFSSL_X509* wolfSSL_sk_X509_value(STACK_OF(WOLFSSL_X509)* sk, int i) return sk->data.x509; } + +/* Return and remove the first x509 pushed on stack */ WOLFSSL_X509* wolfSSL_sk_X509_shift(WOLF_STACK_OF(WOLFSSL_X509)* sk) { - return wolfSSL_sk_X509_pop(sk); + WOLFSSL_STACK* node; + WOLFSSL_X509* x509; + + if (sk == NULL) { + return NULL; + } + + node = sk->next; + x509 = sk->data.x509; + + if (node != NULL) { + /* walk to end of stack to first node pushed, and remove it */ + WOLFSSL_STACK* prevNode = sk; + + while (node->next != NULL) { + prevNode = node; + node = node->next; + } + + x509 = node->data.x509; + prevNode->next = NULL; + XFREE(node, NULL, DYNAMIC_TYPE_X509); + } + else { /* only one x509 in stack */ + sk->data.x509 = NULL; + } + + if (sk->num > 0) { + sk->num -= 1; + } + + return x509; } #endif /* OPENSSL_EXTRA */ diff --git a/tests/api.c b/tests/api.c index 7e13a379f..23f213a72 100644 --- a/tests/api.c +++ b/tests/api.c @@ -49536,26 +49536,88 @@ static void free_x509(X509* x) static int test_sk_X509(void) { #if defined(OPENSSL_ALL) && !defined(NO_CERTS) - STACK_OF(X509)* s; + { + STACK_OF(X509)* s; - AssertNotNull(s = sk_X509_new()); - AssertIntEQ(sk_X509_num(s), 0); - sk_X509_pop_free(s, NULL); + AssertNotNull(s = sk_X509_new()); + AssertIntEQ(sk_X509_num(s), 0); + sk_X509_pop_free(s, NULL); - AssertNotNull(s = sk_X509_new_null()); - AssertIntEQ(sk_X509_num(s), 0); - sk_X509_pop_free(s, NULL); + AssertNotNull(s = sk_X509_new_null()); + AssertIntEQ(sk_X509_num(s), 0); + sk_X509_pop_free(s, NULL); - AssertNotNull(s = sk_X509_new()); - sk_X509_push(s, (X509*)1); - AssertIntEQ(sk_X509_num(s), 1); - AssertIntEQ((sk_X509_value(s, 0) == (X509*)1), 1); - sk_X509_push(s, (X509*)2); - AssertIntEQ(sk_X509_num(s), 2); - AssertIntEQ((sk_X509_value(s, 0) == (X509*)2), 1); - AssertIntEQ((sk_X509_value(s, 1) == (X509*)1), 1); - sk_X509_push(s, (X509*)2); - sk_X509_pop_free(s, free_x509); + AssertNotNull(s = sk_X509_new()); + sk_X509_push(s, (X509*)1); + AssertIntEQ(sk_X509_num(s), 1); + AssertIntEQ((sk_X509_value(s, 0) == (X509*)1), 1); + sk_X509_push(s, (X509*)2); + AssertIntEQ(sk_X509_num(s), 2); + AssertIntEQ((sk_X509_value(s, 0) == (X509*)2), 1); + AssertIntEQ((sk_X509_value(s, 1) == (X509*)1), 1); + sk_X509_push(s, (X509*)2); + sk_X509_pop_free(s, free_x509); + } + + { + /* Push a list of 10 X509s onto stack, then verify that + * value(), push(), shift(), and pop() behave as expected. */ + STACK_OF(X509)* s; + X509* xList[10]; + int i = 0; + const int len = (sizeof(xList) / sizeof(xList[0])); + + for (i = 0; i < len; ++i) + AssertNotNull(xList[i] = X509_new()); + + /* test push, pop, and free */ + AssertNotNull(s = sk_X509_new()); + + for (i = 0; i < len; ++i) { + sk_X509_push(s, xList[i]); + AssertIntEQ(sk_X509_num(s), i + 1); + AssertIntEQ((sk_X509_value(s, 0) == xList[i]), 1); + AssertIntEQ((sk_X509_value(s, i) == xList[0]), 1); + } + + /* pop returns and removes last pushed on stack, which is index 0 + * in sk_x509_value */ + for (i = 0; i < len; ++i) { + X509 * x = sk_X509_value(s, 0); + X509 * y = sk_X509_pop(s); + X509 * z = xList[len - 1 - i]; + + AssertIntEQ((x == y), 1); + AssertIntEQ((x == z), 1); + AssertIntEQ(sk_X509_num(s), len - 1 - i); + } + + sk_free(s); + + /* test push, shift, and free */ + AssertNotNull(s = sk_X509_new()); + + for (i = 0; i < len; ++i) { + sk_X509_push(s, xList[i]); + AssertIntEQ(sk_X509_num(s), i + 1); + AssertIntEQ((sk_X509_value(s, 0) == xList[i]), 1); + AssertIntEQ((sk_X509_value(s, i) == xList[0]), 1); + } + + /* shift returns and removes first pushed on stack, which is index i + * in sk_x509_value() */ + for (i = 0; i < len; ++i) { + X509 * x = sk_X509_value(s, len - 1 - i); + X509 * y = sk_X509_shift(s); + X509 * z = xList[i]; + + AssertIntEQ((x == y), 1); + AssertIntEQ((x == z), 1); + AssertIntEQ(sk_X509_num(s), len - 1 - i); + } + + sk_X509_pop_free(s, NULL); + } printf(resultFmt, passed); #endif