From db758dc98be0a91f0a6f9688c24b5929e75b2c4e Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Sat, 12 Mar 2016 09:37:32 -0700 Subject: [PATCH] update test script, fall back to cert name search, fix der free --- configure.ac | 10 ++++ scripts/include.am | 16 +++--- scripts/trusted_peer.test | 108 ++++++++++++++++++++++++++++++++------ src/internal.c | 13 +++-- src/ssl.c | 46 +++++++++++----- wolfcrypt/src/asn.c | 4 -- wolfssl/internal.h | 10 +++- 7 files changed, 162 insertions(+), 45 deletions(-) diff --git a/configure.ac b/configure.ac index 45c859c16..c7e14cc9d 100644 --- a/configure.ac +++ b/configure.ac @@ -2510,6 +2510,7 @@ AM_CONDITIONAL([BUILD_PSK], [test "x$ENABLED_PSK" = "xyes"]) # check if should run the trusted peer certs test +# (for now checking both C_FLAGS and C_EXTRA_FLAGS) case $C_EXTRA_FLAGS in *WOLFSSL_TRUST_PEER_CERT*) have_tp=yes @@ -2517,6 +2518,15 @@ case $C_EXTRA_FLAGS in *) have_tp=no ;; esac +if test "$have_tp" = "no"; then + case $C_FLAGS in + *WOLFSSL_TRUST_PEER_CERT*) + have_tp=yes + break;; + *) + have_tp=no ;; + esac +fi AM_CONDITIONAL([BUILD_TRUST_PEER_CERT], [test "x$have_tp" = "xyes"]) diff --git a/scripts/include.am b/scripts/include.am index 2a0c8f4a7..53087fdc5 100644 --- a/scripts/include.am +++ b/scripts/include.am @@ -39,8 +39,16 @@ endif endif +if BUILD_PSK +dist_noinst_SCRIPTS+= scripts/psk.test endif +if BUILD_TRUST_PEER_CERT +dist_noinst_SCRIPTS+= scripts/trusted_peer.test +endif + +endif # end of BUILD_EXAMPLE_SERVERS + if BUILD_EXAMPLE_CLIENTS if !BUILD_IPV6 dist_noinst_SCRIPTS+= scripts/external.test @@ -49,14 +57,6 @@ dist_noinst_SCRIPTS+= scripts/google.test endif endif -if BUILD_PSK -dist_noinst_SCRIPTS+= scripts/psk.test -endif - -if BUILD_TRUST_PEER_CERT -dist_noinst_SCRIPTS+= scripts/trusted_peer.test -endif - EXTRA_DIST += scripts/testsuite.pcap # leave openssl.test as extra until non bash works EXTRA_DIST += scripts/openssl.test diff --git a/scripts/trusted_peer.test b/scripts/trusted_peer.test index a07836280..a4faf1c18 100755 --- a/scripts/trusted_peer.test +++ b/scripts/trusted_peer.test @@ -15,6 +15,17 @@ counter=0 # per source tree ready_file=`pwd`/wolfssl_tp_ready$$ +# variables for certs so can use RSA or ECC +client_cert=`pwd`/certs/client-cert.pem +client_ca=`pwd`/certs/ca-cert.pem +client_key=`pwd`/certs/client-key.pem +ca_key=`pwd`/certs/ca-key.pem +server_cert=`pwd`/certs/server-cert.pem +server_key=`pwd`/certs/server-key.pem +combined_cert=`pwd`/certs/client_combined.pem +wrong_ca=`pwd`/certs/wolfssl-website-ca.pem +wrong_cert=`pwd`/certs/server-revoked-cert.pem + echo "ready file $ready_file" create_port() { @@ -63,15 +74,41 @@ trap do_trap INT TERM [ ! -x ./examples/client/client ] && echo -e "\n\nClient doesn't exist" && exit 1 +# Look for if RSA and/or ECC is enabled and adjust certs/keys +ciphers=`./examples/client/client -e` +if [[ $ciphers != *"RSA"* ]]; then + if [[ $ciphers == *"ECDSA"* ]]; then + client_cert=`pwd`/certs/client-ecc-cert.pem + client_ca=`pwd`/certs/server-ecc.pem + client_key=`pwd`/certs/ecc-client-key.pem + ca_key=`pwd`/certs/ecc-key.pem + server_cert=`pwd`/certs/server-ecc.pem + server_key=`pwd`/certs/ecc-key.pem + wrong_ca=`pwd`/certs/server-ecc-comp.pem + wrong_cert=`pwd`/certs/server-ecc-comp.pem + else + echo "configure options not set up for test. No RSA or ECC" + exit 0 + fi +fi + +# CRL list not set up for tests +crl_test=`./examples/client/client -h` +if [[ $crl_test == *"-C "* ]]; then + echo "test not set up to run with CRL" + exit 0 +fi + # Test for trusted peer certs build echo "" echo "Checking built with trusted peer certs " echo "-----------------------------------------------------" port=0 -./examples/server/server -E certs/client-cert.pem -R $ready_file -p $port & +remove_ready_file +./examples/server/server -E $client_cert -c $server_cert -k $server_key -R $ready_file -p $port & server_pid=$! create_port -./examples/client/client -p $port +./examples/client/client -A $client_ca -p $port RESULT=$? remove_ready_file # if fail here then is a settings issue so return 0 @@ -86,10 +123,10 @@ echo "" echo "Server and Client relying on trusted peer cert loaded" echo "-----------------------------------------------------" port=0 -./examples/server/server -A certs/wolfssl-website-ca.pem -E certs/client-cert.pem -c certs/server-cert.pem -R $ready_file -p $port & +./examples/server/server -A $wrong_ca -E $client_cert -c $server_cert -k $server_key -R $ready_file -p $port & server_pid=$! create_port -./examples/client/client -A certs/wolfssl-website-ca.pem -E certs/server-cert.pem -c certs/client-cert.pem -p $port +./examples/client/client -A $wrong_ca -E $server_cert -c $client_cert -p $port RESULT=$? remove_ready_file if [ $RESULT -ne 0 ]; then @@ -103,10 +140,10 @@ echo "" echo "Server relying on trusted peer cert loaded" echo "-----------------------------------------------------" port=0 -./examples/server/server -A certs/wolfssl-website-ca.pem -E certs/client-cert.pem -c certs/server-cert.pem -R $ready_file -p $port & +./examples/server/server -A $wrong_ca -E $client_cert -c $server_cert -k $server_key -R $ready_file -p $port & server_pid=$! create_port -./examples/client/client -c certs/client-cert.pem -p $port +./examples/client/client -A $client_ca -c $client_cert -p $port RESULT=$? remove_ready_file if [ $RESULT -ne 0 ]; then @@ -120,10 +157,10 @@ echo "" echo "Client relying on trusted peer cert loaded" echo "-----------------------------------------------------" port=0 -./examples/server/server -c certs/server-cert.pem -R $ready_file -p $port & +./examples/server/server -c $server_cert -k $server_key -R $ready_file -p $port & server_pid=$! create_port -./examples/client/client -E certs/server-cert.pem -p $port +./examples/client/client -A $wrong_ca -E $server_cert -p $port RESULT=$? remove_ready_file if [ $RESULT -ne 0 ]; then @@ -137,10 +174,10 @@ echo "" echo "Client fall through to loaded CAs" echo "-----------------------------------------------------" port=0 -./examples/server/server -R $ready_file -p $port & +./examples/server/server -c $server_cert -k $server_key -R $ready_file -p $port & server_pid=$! create_port -./examples/client/client -E certs/server-revoked-cert.pem -p $port +./examples/client/client -A $client_ca -E $wrong_cert -p $port RESULT=$? remove_ready_file if [ $RESULT -ne 0 ]; then @@ -151,13 +188,15 @@ fi echo "" # Test that client can fail +# check if using ECC client example is hard coded to load correct ECC ca so skip +if [[ $wrong_ca != *"ecc"* ]]; then echo "Client wrong CA and wrong trusted peer cert loaded" echo "-----------------------------------------------------" port=0 -./examples/server/server -R $ready_file -p $port & +./examples/server/server -c $server_cert -k $server_key -R $ready_file -p $port & server_pid=$! create_port -./examples/client/client -A certs/wolfssl-website-ca.pem -E certs/server-revoked-cert.pem -p $port +./examples/client/client -A $wrong_ca -E $wrong_cert -p $port RESULT=$? remove_ready_file if [ $RESULT -eq 0 ]; then @@ -166,15 +205,16 @@ if [ $RESULT -eq 0 ]; then exit 1 fi echo "" +fi # Test that server can fail echo "Server wrong CA and wrong trusted peer cert loaded" echo "-----------------------------------------------------" port=0 -./examples/server/server -A certs/wolfssl-website-ca.pem -E certs/server-revoked-cert.pem -R $ready_file -p $port & +./examples/server/server -A $wrong_ca -E $wrong_cert -c $server_cert -k $server_key -R $ready_file -p $port & server_pid=$! create_port -./examples/client/client -p $port +./examples/client/client -A $client_ca -p $port RESULT=$? remove_ready_file if [ $RESULT -eq 0 ]; then @@ -188,10 +228,10 @@ echo "" echo "Server fall through to loaded CAs" echo "-----------------------------------------------------" port=0 -./examples/server/server -E certs/server-revoked-cert.pem -R $ready_file -p $port & +./examples/server/server -E $wrong_cert -c $server_cert -k $server_key -R $ready_file -p $port & server_pid=$! create_port -./examples/client/client -p $port +./examples/client/client -A $client_ca -p $port RESULT=$? remove_ready_file if [ $RESULT -ne 0 ]; then @@ -201,6 +241,42 @@ if [ $RESULT -ne 0 ]; then fi echo "" +# test loading multiple certs +echo "Server loading multiple trusted peer certs" +echo "Test two success cases and one fail case" +echo "-----------------------------------------------------" +port=0 +cat $client_cert $client_ca > $combined_cert +./examples/server/server -i -A $wrong_ca -E $combined_cert -c $server_cert -k $server_key -R $ready_file -p $port & +server_pid=$! +create_port +./examples/client/client -A $client_ca -c $client_cert -k $client_key -p $port +RESULT=$? +if [ $RESULT -ne 0 ]; then + echo -e "\nServer load multiple trusted peer certs failed!" + do_cleanup + exit 1 +fi +./examples/client/client -A $client_ca -c $client_ca -k $ca_key -p $port +RESULT=$? +if [ $RESULT -ne 0 ]; then + echo -e "\nServer load multiple trusted peer certs failed!" + do_cleanup + exit 1 +fi +./examples/client/client -A $client_ca -c $wrong_cert -k $client_key -p $port +RESULT=$? +if [ $RESULT -eq 0 ]; then + echo -e "\nServer load multiple trusted peer certs failed!" + do_cleanup + exit 1 +fi + +do_cleanup # kill PID of server running in infinit loop +rm $combined_cert +remove_ready_file +echo "" + echo "-----------------------------------------------------" echo "ALL TESTS PASSED" echo "-----------------------------------------------------" diff --git a/src/internal.c b/src/internal.c index d78ab2acd..c1fa85438 100644 --- a/src/internal.c +++ b/src/internal.c @@ -4630,10 +4630,17 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, 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); + if (dCert->extAuthKeyIdSet) { + tp = GetTrustedPeer(ssl->ctx->cm, dCert->extSubjKeyId, + WC_MATCH_SKID); + } + else { /* if the cert has no SKID try to match by name */ + tp = GetTrustedPeer(ssl->ctx->cm, dCert->subjectHash, + WC_MATCH_NAME); + } #else /* NO_SKID */ - tp = GetTrustedPeer(ssl->ctx->cm, dCert->subjectHash); + tp = GetTrustedPeer(ssl->ctx->cm, dCert->subjectHash, + WC_MATCH_NAME); #endif /* NO SKID */ WOLFSSL_MSG("Checking for trusted peer cert"); diff --git a/src/ssl.c b/src/ssl.c index 5abb4a2b5..dd2d392f0 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -2239,8 +2239,10 @@ int AlreadyTrustedPeer(WOLFSSL_CERT_MANAGER* cm, byte* hash) } -/* return Trusted Peer if found, otherwise NULL */ -TrustedPeerCert* GetTrustedPeer(void* vp, byte* hash) +/* return Trusted Peer if found, otherwise NULL + type is what to match on + */ +TrustedPeerCert* GetTrustedPeer(void* vp, byte* hash, int type) { WOLFSSL_CERT_MANAGER* cm = (WOLFSSL_CERT_MANAGER*)vp; TrustedPeerCert* ret = NULL; @@ -2258,11 +2260,20 @@ TrustedPeerCert* GetTrustedPeer(void* vp, byte* hash) tp = cm->tpTable[row]; while (tp) { byte* subjectHash; - #ifndef NO_SKID - subjectHash = tp->subjectKeyIdHash; - #else - subjectHash = tp->subjectNameHash; - #endif + switch (type) { + #ifndef NO_SKID + case WC_MATCH_SKID: + subjectHash = tp->subjectKeyIdHash; + break; + #endif + case WC_MATCH_NAME: + subjectHash = tp->subjectNameHash; + break; + default: + WOLFSSL_MSG("Unknown search type"); + UnLockMutex(&cm->tpLock); + return NULL; + } if (XMEMCMP(hash, subjectHash, SIGNER_DIGEST_SIZE) == 0) { ret = tp; break; @@ -2366,11 +2377,12 @@ Signer* GetCAByName(void* vp, byte* hash) #ifdef WOLFSSL_TRUST_PEER_CERT /* add a trusted peer cert to linked list */ -int AddTrustedPeer(WOLFSSL_CERT_MANAGER* cm, DerBuffer* der, int verify) +int AddTrustedPeer(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int verify) { int ret, row; TrustedPeerCert* peerCert; DecodedCert* cert = NULL; + DerBuffer* der = *pDer; byte* subjectHash = NULL; WOLFSSL_MSG("Adding a Trusted Peer Cert"); @@ -2397,7 +2409,12 @@ int AddTrustedPeer(WOLFSSL_CERT_MANAGER* cm, DerBuffer* der, int verify) XMEMSET(peerCert, 0, sizeof(TrustedPeerCert)); #ifndef NO_SKID - subjectHash = cert->extSubjKeyId; + if (cert->extAuthKeyIdSet) { + subjectHash = cert->extSubjKeyId; + } + else { + subjectHash = cert->subjectHash; + } #else subjectHash = cert->subjectHash; #endif @@ -2449,7 +2466,12 @@ int AddTrustedPeer(WOLFSSL_CERT_MANAGER* cm, DerBuffer* der, int verify) #endif #ifndef NO_SKID - row = TrustedPeerHashSigner(peerCert->subjectKeyIdHash); + if (cert->extAuthKeyIdSet) { + row = TrustedPeerHashSigner(peerCert->subjectKeyIdHash); + } + else { + row = TrustedPeerHashSigner(peerCert->subjectNameHash); + } #else row = TrustedPeerHashSigner(peerCert->subjectNameHash); #endif @@ -2472,7 +2494,7 @@ int AddTrustedPeer(WOLFSSL_CERT_MANAGER* cm, DerBuffer* der, int verify) FreeDecodedCert(cert); XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER); WOLFSSL_MSG(" Freeing der trusted peer cert"); - FreeDer(der); + FreeDer(&der); WOLFSSL_MSG(" OK Freeing der trusted peer cert"); WOLFSSL_LEAVE("AddTrustedPeer", ret); @@ -3320,7 +3342,7 @@ static int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, else if (type == TRUSTED_PEER_TYPE) { if (ctx == NULL) { WOLFSSL_MSG("Need context for trusted peer cert load"); - XFREE(der.buffer, heap, dynamicType); + FreeDer(&der); return BAD_FUNC_ARG; } /* add trusted peer cert */ diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index a44e93523..79ed25d03 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -4900,10 +4900,6 @@ int ParseCert(DecodedCert* cert, int type, int verify, void* cm) extern "C" { #endif WOLFSSL_LOCAL Signer* GetCA(void* signers, byte* hash); -#ifdef WOLFSSL_TRUST_PEER_CERT - WOLFSSL_LOCAL TrustedPeerCert* GetTrustedPeer(void* signers, byte* hash); - WOLFSSL_LOCAL int MatchTrustedPeer(TrustedPeerCert* tp, DecodedCert* cert); -#endif /* WOLFSSL_TRUST_PEER_CERT */ #ifndef NO_SKID WOLFSSL_LOCAL Signer* GetCAByName(void* signers, byte* hash); #endif diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 2524a7334..1bdad174d 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -1946,7 +1946,7 @@ int ProcessOldClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, int AlreadySigner(WOLFSSL_CERT_MANAGER* cm, byte* hash); #ifdef WOLFSSL_TRUST_PEER_CERT WOLFSSL_LOCAL - int AddTrustedPeer(WOLFSSL_CERT_MANAGER* cm, DerBuffer* der, int verify); + int AddTrustedPeer(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int verify); WOLFSSL_LOCAL int AlreadyTrustedPeer(WOLFSSL_CERT_MANAGER* cm, byte* hash); #endif @@ -2839,7 +2839,13 @@ WOLFSSL_LOCAL int VerifyClientSuite(WOLFSSL* ssl); RsaKey* key); #endif #ifdef WOLFSSL_TRUST_PEER_CERT - WOLFSSL_LOCAL TrustedPeerCert* GetTrustedPeer(void* vp, byte* hash); + + /* options for searching hash table for a matching trusted peer cert */ + #define WC_MATCH_SKID 0 + #define WC_MATCH_NAME 1 + + WOLFSSL_LOCAL TrustedPeerCert* GetTrustedPeer(void* vp, byte* hash, + int type); WOLFSSL_LOCAL int MatchTrustedPeer(TrustedPeerCert* tp, DecodedCert* cert); #endif