diff --git a/src/x509_str.c b/src/x509_str.c index 49cd7deb6..897deaf84 100644 --- a/src/x509_str.c +++ b/src/x509_str.c @@ -384,7 +384,8 @@ int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx) * a trusted CA in the CM */ ret = X509StoreVerifyCert(ctx); if (ret != WOLFSSL_SUCCESS) { - if ((ctx->store->param->flags & X509_V_FLAG_PARTIAL_CHAIN) && + if (((ctx->flags & X509_V_FLAG_PARTIAL_CHAIN) || + (ctx->store->param->flags & X509_V_FLAG_PARTIAL_CHAIN)) && (added == 1)) { wolfSSL_sk_X509_push(ctx->chain, ctx->current_cert); ret = WOLFSSL_SUCCESS; @@ -550,9 +551,9 @@ int wolfSSL_X509_STORE_CTX_set_purpose(WOLFSSL_X509_STORE_CTX *ctx, void wolfSSL_X509_STORE_CTX_set_flags(WOLFSSL_X509_STORE_CTX *ctx, unsigned long flags) { - (void)ctx; - (void)flags; - WOLFSSL_STUB("wolfSSL_X509_STORE_CTX_set_flags (not implemented)"); + if ((ctx != NULL) && (flags & X509_V_FLAG_PARTIAL_CHAIN)){ + ctx->flags |= X509_V_FLAG_PARTIAL_CHAIN; + } } #endif /* !NO_WOLFSSL_STUB */ @@ -1329,6 +1330,9 @@ int wolfSSL_X509_STORE_set_flags(WOLFSSL_X509_STORE* store, unsigned long flag) ret = wolfSSL_CertManagerDisableCRL(store->cm); } #endif + if (flag & X509_V_FLAG_PARTIAL_CHAIN) { + store->param->flags |= X509_V_FLAG_PARTIAL_CHAIN; + } return ret; } diff --git a/tests/api.c b/tests/api.c index 806410cb3..965aca6b1 100644 --- a/tests/api.c +++ b/tests/api.c @@ -225,6 +225,7 @@ #include #include #include + #include #ifdef OPENSSL_ALL #include #include @@ -60207,6 +60208,54 @@ static int test_wolfSSL_X509_STORE_CTX_ex9(X509_STORE_test_data *testData) sk_X509_free(trusted); return EXPECT_RESULT(); } + +static int test_wolfSSL_X509_STORE_CTX_ex10(X509_STORE_test_data *testData) +{ + EXPECT_DECLS; + X509_STORE* store = NULL; + X509_STORE_CTX* ctx = NULL; + STACK_OF(X509)* chain = NULL; + + /* Test case 10, ensure partial chain flag works */ + ExpectNotNull(store = X509_STORE_new()); + ExpectIntEQ(X509_STORE_add_cert(store, testData->x509CaInt), 1); + ExpectIntEQ(X509_STORE_add_cert(store, testData->x509CaInt2), 1); + ExpectNotNull(ctx = X509_STORE_CTX_new()); + ExpectIntEQ(X509_STORE_CTX_init(ctx, store, testData->x509Leaf, NULL), 1); + /* Fails because chain is incomplete */ + ExpectIntNE(X509_verify_cert(ctx), 1); + ExpectIntEQ(X509_STORE_set_flags(store, X509_V_FLAG_PARTIAL_CHAIN), 1); + /* Partial chain now OK */ + ExpectIntEQ(X509_verify_cert(ctx), 1); + ExpectNotNull(chain = X509_STORE_CTX_get_chain(ctx)); + X509_STORE_CTX_free(ctx); + X509_STORE_free(store); + return EXPECT_RESULT(); +} + +static int test_wolfSSL_X509_STORE_CTX_ex11(X509_STORE_test_data *testData) +{ + EXPECT_DECLS; + X509_STORE* store = NULL; + X509_STORE_CTX* ctx = NULL; + STACK_OF(X509)* chain = NULL; + + /* Test case 11, test partial chain flag on ctx itself */ + ExpectNotNull(store = X509_STORE_new()); + ExpectIntEQ(X509_STORE_add_cert(store, testData->x509CaInt), 1); + ExpectIntEQ(X509_STORE_add_cert(store, testData->x509CaInt2), 1); + ExpectNotNull(ctx = X509_STORE_CTX_new()); + ExpectIntEQ(X509_STORE_CTX_init(ctx, store, testData->x509Leaf, NULL), 1); + /* Fails because chain is incomplete */ + ExpectIntNE(X509_verify_cert(ctx), 1); + X509_STORE_CTX_set_flags(ctx, X509_V_FLAG_PARTIAL_CHAIN); + /* Partial chain now OK */ + ExpectIntEQ(X509_verify_cert(ctx), 1); + ExpectNotNull(chain = X509_STORE_CTX_get_chain(ctx)); + X509_STORE_CTX_free(ctx); + X509_STORE_free(store); + return EXPECT_RESULT(); +} #endif static int test_wolfSSL_X509_STORE_CTX_ex(void) @@ -60244,6 +60293,8 @@ static int test_wolfSSL_X509_STORE_CTX_ex(void) ExpectIntEQ(test_wolfSSL_X509_STORE_CTX_ex7(&testData), 1); ExpectIntEQ(test_wolfSSL_X509_STORE_CTX_ex8(&testData), 1); ExpectIntEQ(test_wolfSSL_X509_STORE_CTX_ex9(&testData), 1); + ExpectIntEQ(test_wolfSSL_X509_STORE_CTX_ex10(&testData), 1); + ExpectIntEQ(test_wolfSSL_X509_STORE_CTX_ex11(&testData), 1); if(testData.x509Ca) { X509_free(testData.x509Ca); diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 411d4f82b..7b28fa228 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -701,6 +701,7 @@ struct WOLFSSL_X509_STORE_CTX { WOLFSSL_BUFFER_INFO* certs; /* peer certs */ WOLFSSL_X509_STORE_CTX_verify_cb verify_cb; /* verify callback */ void* heap; + int flags; WOLF_STACK_OF(WOLFSSL_X509)* ctxIntermediates; /* Intermediates specified * on store ctx init */ WOLF_STACK_OF(WOLFSSL_X509)* setTrustedSk;/* A trusted stack override