From 05d2cec7c10d8ba370181ae0869eda7a4674bf2f Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Mon, 29 Feb 2016 11:02:18 -0700 Subject: [PATCH] addition to api tests and refactor location of trusted peer cert check --- examples/client/client.c | 6 +++++ examples/server/server.c | 4 ++-- src/internal.c | 43 +++++++++++++++++++++++++++++++++ src/ssl.c | 10 ++------ tests/api.c | 52 ++++++++++++++++++++++++++++++++++++++++ wolfcrypt/src/asn.c | 30 ----------------------- 6 files changed, 105 insertions(+), 40 deletions(-) diff --git a/examples/client/client.c b/examples/client/client.c index 021e97958..417b3267f 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -977,6 +977,12 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) if (wolfSSL_CTX_load_verify_locations(ctx, eccCert, 0) != SSL_SUCCESS) err_sys("can't load ecc ca file, Please run from wolfSSL home dir"); #endif /* HAVE_ECC */ +#ifdef WOLFSSL_TRUST_PEER_CERT + if ((ret = wolfSSL_CTX_trust_peer_cert(ctx, svrCert, SSL_FILETYPE_PEM)) + != SSL_SUCCESS) { + err_sys("can't load trusted peer cert file"); + } +#endif /* WOLFSSL_TRUST_PEER_CERT */ } #endif /* !NO_FILESYSTEM && !NO_CERTS */ #if !defined(NO_CERTS) diff --git a/examples/server/server.c b/examples/server/server.c index a8320733b..adfb895a3 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -686,8 +686,8 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) if (SSL_CTX_load_verify_locations(ctx, verifyCert, 0) != SSL_SUCCESS) err_sys("can't load ca file, Please run from wolfSSL home dir"); #ifdef WOLFSSL_TRUST_PEER_CERT - if ((ret = wolfSSL_CTX_trust_peer_cert(ctx, - "./certs/client-cert.pem", SSL_FILETYPE_PEM)) != SSL_SUCCESS) { + if ((ret = wolfSSL_CTX_trust_peer_cert(ctx, cliCert, SSL_FILETYPE_PEM)) + != SSL_SUCCESS) { err_sys("can't load trusted peer cert file"); } #endif /* WOLFSSL_TRUST_PEER_CERT */ diff --git a/src/internal.c b/src/internal.c index 10aa7349a..523daf1e2 100644 --- a/src/internal.c +++ b/src/internal.c @@ -4554,6 +4554,10 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, WOLFSSL_X509_STORE_CTX store[1]; #endif +#ifdef WOLFSSL_TRUST_PEER_CERT + byte haveTrustPeer = 0; /* was cert verified by loaded trusted peer cert */ +#endif + #ifdef WOLFSSL_CALLBACKS if (ssl->hsInfoOn) AddPacketName("Certificate", &ssl->handShakeInfo); if (ssl->toInfoOn) AddLateName("Certificate", &ssl->timeoutInfo); @@ -4624,6 +4628,34 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, return MEMORY_E; #endif +#ifdef WOLFSSL_TRUST_PEER_CERT + /* if using trusted peer certs check before verify chain and CA test */ + if (count > 0) { + TrustedPeerCert* tp = NULL; + + InitDecodedCert(dCert, certs[0].buffer, certs[0].length, ssl->heap); + ret = ParseCertRelative(dCert, CERT_TYPE, 0, ssl->ctx->cm); + #ifndef NO_SKID + if (dCert->extAuthKeyIdSet) + tp = GetTrustedPeer(ssl->ctx->cm, dCert->extSubjKeyId); + #else /* NO_SKID */ + tp = GetTrustedPeer(ssl->ctx->cm, dCert->issuerHash); + #endif /* NO SKID */ + WOLFSSL_MSG("Checking for trusted peer cert"); + + if (tp == NULL) { + /* no trusted peer cert */ + WOLFSSL_MSG("No matching trusted peer cert. Checking CAs"); + } else if (MatchTrustedPeer(tp, dCert)){ + WOLFSSL_MSG("Found matching trusted peer cert"); + haveTrustPeer = 1; + } else { + WOLFSSL_MSG("Trusted peer cert did not match!"); + } + } + if (!haveTrustPeer) { /* do not verify chain if trusted peer cert found */ +#endif /* WOLFSSL_TRUST_PEER_CERT */ + /* verify up to peer's first */ while (count > 1) { DerBuffer myCert = certs[count - 1]; @@ -4716,6 +4748,10 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, count--; } +#ifdef WOLFSSL_TRUST_PEER_CERT + } /* end of if (haveTrustPeer) -- a check for if already verified */ +#endif + /* peer's, may not have one if blank client cert sent by TLSv1.2 */ if (count) { DerBuffer myCert = certs[0]; @@ -4723,9 +4759,16 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, WOLFSSL_MSG("Verifying Peer's cert"); +#ifdef WOLFSSL_TRUST_PEER_CERT + if (!haveTrustPeer) { /* do not parse again if previously verified */ +#endif InitDecodedCert(dCert, myCert.buffer, myCert.length, ssl->heap); ret = ParseCertRelative(dCert, CERT_TYPE, !ssl->options.verifyNone, ssl->ctx->cm); +#ifdef WOLFSSL_TRUST_PEER_CERT + } +#endif + if (ret == 0) { WOLFSSL_MSG("Verified Peer's cert"); fatal = 0; diff --git a/src/ssl.c b/src/ssl.c index f16934157..22ed142fd 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -2290,7 +2290,6 @@ int MatchTrustedPeer(TrustedPeerCert* tp, DecodedCert* cert) /* compare signatures */ if (tp->sigLen == cert->sigLength) { - /* compare first four before comparing all */ if (XMEMCMP(tp->sig, cert->signature, cert->sigLength)) { return SSL_FAILURE; } @@ -2303,6 +2302,7 @@ int MatchTrustedPeer(TrustedPeerCert* tp, DecodedCert* cert) } #endif /* WOLFSSL_TRUST_PEER_CERT */ + /* return CA if found, otherwise NULL */ Signer* GetCA(void* vp, byte* hash) { @@ -4209,19 +4209,13 @@ int wolfSSL_CTX_load_verify_locations(WOLFSSL_CTX* ctx, const char* file, */ int wolfSSL_CTX_trust_peer_cert(WOLFSSL_CTX* ctx, const char* file, int type) { - int ret; - WOLFSSL_ENTER("wolfSSL_CTX_trust_peer_cert"); if (ctx == NULL || file == NULL) { return SSL_FAILURE; } - if ((ret = ProcessFile(ctx, file, type, TRUSTED_PEER_TYPE, NULL, 0, NULL)) - == SSL_SUCCESS) { - } - - return ret; + return ProcessFile(ctx, file, type, TRUSTED_PEER_TYPE, NULL, 0, NULL); } #endif /* WOLFSSL_TRUST_PEER_CERT */ diff --git a/tests/api.c b/tests/api.c index f2340c224..83b77ea3c 100644 --- a/tests/api.c +++ b/tests/api.c @@ -211,6 +211,57 @@ static void test_wolfSSL_CTX_use_PrivateKey_file(void) } +/* test both file and buffer versions along with unloading trusted peer certs */ +static void test_wolfSSL_CTX_trust_peer_cert(void) +{ +#if !defined(NO_CERTS) && defined(WOLFSSL_TRUST_PEER_CERT) + WOLFSSL_CTX *ctx; + + AssertNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method())); + +#if !defined(NO_FILESYSTEM) + /* invalid file */ + assert(wolfSSL_CTX_trust_peer_cert(ctx, NULL, + SSL_FILETYPE_PEM) != SSL_SUCCESS); + assert(wolfSSL_CTX_trust_peer_cert(ctx, bogusFile, + SSL_FILETYPE_PEM) != SSL_SUCCESS); + assert(wolfSSL_CTX_trust_peer_cert(ctx, cliCert, + SSL_FILETYPE_ASN1) != SSL_SUCCESS); + + /* success */ + assert(wolfSSL_CTX_trust_peer_cert(ctx, cliCert, SSL_FILETYPE_PEM) + == SSL_SUCCESS); + + /* unload cert */ + assert(wolfSSL_CTX_Unload_trust_peers(NULL) != SSL_SUCCESS); + assert(wolfSSL_CTX_Unload_trust_peers(ctx) == SSL_SUCCESS); +#endif + + /* Test of loading certs from buffers */ + + /* invalid ca buffer */ + assert(wolfSSL_CTX_trust_peer_buffer(ctx, NULL, -1, + SSL_FILETYPE_ASN1) != SSL_SUCCESS); + + /* success */ +#ifdef USE_CERT_BUFFERS_1024 + assert(wolfSSL_CTX_trust_peer_buffer(ctx, client_cert_der_1024, + sizeof_client_cert_der_1024, SSL_FILETYPE_ASN1) == SSL_SUCCESS); +#endif +#ifdef USE_CERT_BUFFERS_2048 + assert(wolfSSL_CTX_trust_peer_buffer(ctx, client_cert_der_2048, + sizeof_client_cert_der_2048, SSL_FILETYPE_ASN1) == SSL_SUCCESS); +#endif + + /* unload cert */ + assert(wolfSSL_CTX_Unload_trust_peers(NULL) != SSL_SUCCESS); + assert(wolfSSL_CTX_Unload_trust_peers(ctx) == SSL_SUCCESS); + + wolfSSL_CTX_free(ctx); +#endif +} + + static void test_wolfSSL_CTX_load_verify_locations(void) { #if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) @@ -1599,6 +1650,7 @@ void ApiTest(void) test_wolfSSL_CTX_use_certificate_file(); test_wolfSSL_CTX_use_PrivateKey_file(); test_wolfSSL_CTX_load_verify_locations(); + test_wolfSSL_CTX_trust_peer_cert(); test_wolfSSL_CTX_SetTmpDH_file(); test_wolfSSL_CTX_SetTmpDH_buffer(); test_server_wolfSSL_new(); diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 5cf59418d..a8e2bcc2b 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -5015,36 +5015,6 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm) #endif /* NO SKID */ WOLFSSL_MSG("About to verify certificate signature"); -#ifdef WOLFSSL_TRUST_PEER_CERT - /* check for trusted peer cert */ - { - TrustedPeerCert* tp = NULL; - #ifndef NO_SKID - if (cert->extAuthKeyIdSet) - tp = GetTrustedPeer(cm, cert->extAuthKeyId); - #else /* NO_SKID */ - tp = GetTrustedPeer(cm, cert->issuerHash); - #endif /* NO SKID */ - WOLFSSL_MSG("Checking for trusted peer cert"); - - if (tp == NULL) { - /* no trusted peer cert */ - WOLFSSL_MSG("No matching trusted peer cert checking CAs"); - } else if (MatchTrustedPeer(tp, cert)){ - WOLFSSL_MSG("Found matching trusted peer cert"); - if (badDate != 0) - return badDate; - - if (criticalExt != 0) - return criticalExt; - - return 0; - } else { - WOLFSSL_MSG("No matching trusted peer cert"); - } - } -#endif /* WOLFSSL_TRUST_PEER_CERT */ - if (ca) { #ifdef HAVE_OCSP /* Need the ca's public key hash for OCSP */