diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..07374ec89 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +CMakeCache.txt +CMakeFiles +CTestTestfile.cmake +cmake_install.cmake +Testing diff --git a/ChangeLog b/ChangeLog index 6b2c96996..63eb30f5d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -10,6 +10,8 @@ Bugfixes * Moved mpi_inv_mod() outside POLARSSL_GENPRIME * Allow R and A to point to same mpi in mpi_div_mpi (found by Manuel Pégourié-Gonnard) + * Fixed possible segfault in mpi_shift_r() (found by Manuel + Pégourié-Gonnard) * Added max length check for rsa_pkcs1_sign with PKCS#1 v2.1 = Version 1.2.0 released 2012-10-31 diff --git a/include/.gitignore b/include/.gitignore new file mode 100644 index 000000000..f3c7a7c5d --- /dev/null +++ b/include/.gitignore @@ -0,0 +1 @@ +Makefile diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h index 5a1e7fc08..2020d3168 100644 --- a/include/polarssl/ssl.h +++ b/include/polarssl/ssl.h @@ -720,20 +720,22 @@ void ssl_set_ciphersuites( ssl_context *ssl, const int *ciphersuites ); * \brief Set the data required to verify peer certificate * * \param ssl SSL context - * \param ca_chain trusted CA chain + * \param ca_chain trusted CA chain (meaning all fully trusted top-level CAs) * \param ca_crl trusted CA CRLs * \param peer_cn expected peer CommonName (or NULL) - * - * \note TODO: add two more parameters: depth and crl */ void ssl_set_ca_chain( ssl_context *ssl, x509_cert *ca_chain, x509_crl *ca_crl, const char *peer_cn ); /** - * \brief Set own certificate and private key + * \brief Set own certificate chain and private key + * + * Note: own_cert should contain IN order from the bottom + * up your certificate chain. The top certificate (self-signed) + * can be omitted. * * \param ssl SSL context - * \param own_cert own public certificate + * \param own_cert own public certificate chain * \param rsa_key own private RSA key */ void ssl_set_own_cert( ssl_context *ssl, x509_cert *own_cert, @@ -747,8 +749,12 @@ void ssl_set_own_cert( ssl_context *ssl, x509_cert *own_cert, * of the callback parameters, with the only change being * that the rsa_context * is a void * in the callbacks) * + * Note: own_cert should contain IN order from the bottom + * up your certificate chain. The top certificate (self-signed) + * can be omitted. + * * \param ssl SSL context - * \param own_cert own public certificate + * \param own_cert own public certificate chain * \param rsa_key alternate implementation private RSA key * \param rsa_decrypt_func alternate implementation of \c rsa_pkcs1_decrypt() * \param rsa_sign_func alternate implementation of \c rsa_pkcs1_sign() diff --git a/library/.gitignore b/library/.gitignore new file mode 100644 index 000000000..9d80fa47a --- /dev/null +++ b/library/.gitignore @@ -0,0 +1,2 @@ +*.o +libpolarssl* diff --git a/library/bignum.c b/library/bignum.c index 23feb6a91..f2608c1df 100644 --- a/library/bignum.c +++ b/library/bignum.c @@ -611,6 +611,9 @@ int mpi_shift_r( mpi *X, size_t count ) v0 = count / biL; v1 = count & (biL - 1); + if( v0 > X->n || ( v0 == X->n && v1 > 0 ) ) + return mpi_lset( X, 0 ); + /* * shift by count / limb_size */ diff --git a/programs/.gitignore b/programs/.gitignore new file mode 100644 index 000000000..d6d9efcf6 --- /dev/null +++ b/programs/.gitignore @@ -0,0 +1,39 @@ +*/Makefile +aes/aescrypt2 +aes/crypt_and_hash +hash/generic_sum +hash/hello +hash/md5sum +hash/sha1sum +hash/sha2sum +pkey/dh_client +pkey/dh_genprime +pkey/dh_server +pkey/key_app +pkey/key_app_writer +pkey/mpi_demo +pkey/rsa_decrypt +pkey/rsa_encrypt +pkey/rsa_genkey +pkey/rsa_sign +pkey/rsa_sign_pss +pkey/rsa_verify +pkey/rsa_verify_pss +random/gen_entropy +random/gen_random_ctr_drbg +random/gen_random_havege +ssl/ssl_client1 +ssl/ssl_client2 +ssl/ssl_fork_server +ssl/ssl_mail_client +ssl/ssl_server +ssl/ssl_server2 +test/benchmark +test/o_p_test +test/selftest +test/ssl_cert_test +test/ssl_test +util/strerror +x509/cert_app +x509/cert_req +x509/crl_app diff --git a/programs/ssl/ssl_client1.c b/programs/ssl/ssl_client1.c index 7631a226b..78ad43e72 100644 --- a/programs/ssl/ssl_client1.c +++ b/programs/ssl/ssl_client1.c @@ -37,6 +37,7 @@ #include "polarssl/entropy.h" #include "polarssl/ctr_drbg.h" #include "polarssl/error.h" +#include "polarssl/certs.h" #define SERVER_PORT 4433 #define SERVER_NAME "localhost" @@ -78,6 +79,7 @@ int main( int argc, char *argv[] ) entropy_context entropy; ctr_drbg_context ctr_drbg; ssl_context ssl; + x509_cert cacert; ((void) argc); ((void) argv); @@ -86,6 +88,7 @@ int main( int argc, char *argv[] ) * 0. Initialize the RNG and the session data */ memset( &ssl, 0, sizeof( ssl_context ) ); + memset( &cacert, 0, sizeof( x509_cert ) ); printf( "\n . Seeding the random number generator..." ); fflush( stdout ); @@ -100,6 +103,28 @@ int main( int argc, char *argv[] ) printf( " ok\n" ); + /* + * 0. Initialize certificates + */ + printf( " . Loading the CA root certificate ..." ); + fflush( stdout ); + +#if defined(POLARSSL_CERTS_C) + ret = x509parse_crt( &cacert, (unsigned char *) test_ca_crt, + strlen( test_ca_crt ) ); +#else + ret = 1; + printf("POLARSSL_CERTS_C not defined."); +#endif + + if( ret < 0 ) + { + printf( " failed\n ! x509parse_crt returned -0x%x\n\n", -ret ); + goto exit; + } + + printf( " ok (%d skipped)\n", ret ); + /* * 1. Start the connection */ @@ -131,13 +156,57 @@ int main( int argc, char *argv[] ) printf( " ok\n" ); ssl_set_endpoint( &ssl, SSL_IS_CLIENT ); - ssl_set_authmode( &ssl, SSL_VERIFY_NONE ); + ssl_set_authmode( &ssl, SSL_VERIFY_OPTIONAL ); + ssl_set_ca_chain( &ssl, &cacert, NULL, "PolarSSL Server 1" ); ssl_set_rng( &ssl, ctr_drbg_random, &ctr_drbg ); ssl_set_dbg( &ssl, my_debug, stdout ); ssl_set_bio( &ssl, net_recv, &server_fd, net_send, &server_fd ); + /* + * 4. Handshake + */ + printf( " . Performing the SSL/TLS handshake..." ); + fflush( stdout ); + + while( ( ret = ssl_handshake( &ssl ) ) != 0 ) + { + if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE ) + { + printf( " failed\n ! ssl_handshake returned -0x%x\n\n", -ret ); + goto exit; + } + } + + printf( " ok\n" ); + + /* + * 5. Verify the server certificate + */ + printf( " . Verifying peer X.509 certificate..." ); + + if( ( ret = ssl_get_verify_result( &ssl ) ) != 0 ) + { + printf( " failed\n" ); + + if( ( ret & BADCERT_EXPIRED ) != 0 ) + printf( " ! server certificate has expired\n" ); + + if( ( ret & BADCERT_REVOKED ) != 0 ) + printf( " ! server certificate has been revoked\n" ); + + if( ( ret & BADCERT_CN_MISMATCH ) != 0 ) + printf( " ! CN mismatch (expected CN=%s)\n", "PolarSSL Server 1" ); + + if( ( ret & BADCERT_NOT_TRUSTED ) != 0 ) + printf( " ! self-signed or not signed by a trusted CA\n" ); + + printf( "\n" ); + } + else + printf( " ok\n" ); + /* * 3. Write the GET request */ @@ -206,6 +275,7 @@ exit: } #endif + x509_free( &cacert ); net_close( server_fd ); ssl_free( &ssl ); diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index 6e047dcc0..0d7a4180f 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -127,9 +127,12 @@ int my_verify( void *data, x509_cert *crt, int depth, int *flags ) #if defined(POLARSSL_FS_IO) #define USAGE_IO \ - " ca_file=%%s default: \"\" (pre-loaded)\n" \ - " ca_path=%%s default: \"\" (pre-loaded) (overrides ca_file)\n" \ - " crt_file=%%s default: \"\" (pre-loaded)\n" \ + " ca_file=%%s The single file containing the top-level CA(s) you fully trust\n" \ + " default: \"\" (pre-loaded)\n" \ + " ca_path=%%s The path containing the top-level CA(s) you fully trust\n" \ + " default: \"\" (pre-loaded) (overrides ca_file)\n" \ + " crt_file=%%s Your own cert and chain (in bottom to top order, top may be omitted)\n" \ + " default: \"\" (pre-loaded)\n" \ " key_file=%%s default: \"\" (pre-loaded)\n" #else #define USAGE_IO \ diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index f6cf4870a..cc94e5ca7 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -184,9 +184,12 @@ int my_ciphersuites[] = #if defined(POLARSSL_FS_IO) #define USAGE_IO \ - " ca_file=%%s default: \"\" (pre-loaded)\n" \ - " ca_path=%%s default: \"\" (pre-loaded) (overrides ca_file)\n" \ - " crt_file=%%s default: \"\" (pre-loaded)\n" \ + " ca_file=%%s The single file containing the top-level CA(s) you fully trust\n" \ + " default: \"\" (pre-loaded)\n" \ + " ca_path=%%s The path containing the top-level CA(s) you fully trust\n" \ + " default: \"\" (pre-loaded) (overrides ca_file)\n" \ + " crt_file=%%s Your own cert and chain (in bottom to top order, top may be omitted)\n" \ + " default: \"\" (pre-loaded)\n" \ " key_file=%%s default: \"\" (pre-loaded)\n" #else #define USAGE_IO \ diff --git a/tests/.gitignore b/tests/.gitignore new file mode 100644 index 000000000..084f664cc --- /dev/null +++ b/tests/.gitignore @@ -0,0 +1,2 @@ +test_suite* +data_files/mpi_write diff --git a/tests/suites/test_suite_mpi.data b/tests/suites/test_suite_mpi.data index 67fa9c3b5..7197b6301 100644 --- a/tests/suites/test_suite_mpi.data +++ b/tests/suites/test_suite_mpi.data @@ -309,6 +309,18 @@ mpi_shift_r:10:"128":1:10:"64" Test mpi_shift_r #2 mpi_shift_r:10:"120815570979701484704906977000760567182871429114712069861589084706550626575967516787438008593490722779337547394120718248995900363209947025063336882559539208430319216688889117222633155838468458047056355241515415159736436403445579777425189969":45:10:"3433785053053426415343295076376096153094051405637175942660777670498379921354157795219578264137985649407981651226029903483433269093721578004287291678324982297860947730012217028349628999378309630601971640587504883789518896817457" +Test mpi_shift_r #4 +mpi_shift_r:16:"FFFFFFFFFFFFFFFF":63:16:"01" + +Test mpi_shift_r #4 +mpi_shift_r:16:"FFFFFFFFFFFFFFFF":64:16:"00" + +Test mpi_shift_r #6 +mpi_shift_r:16:"FFFFFFFFFFFFFFFF":65:16:"00" + +Test mpi_shift_r #7 +mpi_shift_r:16:"FFFFFFFFFFFFFFFF":128:16:"00" + Base test mpi_mul_mpi #1 mpi_mul_mpi:10:"5":10:"7":10:"35" diff --git a/tests/suites/test_suite_mpi.function b/tests/suites/test_suite_mpi.function index 663539259..70d9b4f18 100644 --- a/tests/suites/test_suite_mpi.function +++ b/tests/suites/test_suite_mpi.function @@ -162,7 +162,7 @@ mpi_set_bit:radix_X:input_X:pos:val:radix_Y:output_Y TEST_ASSERT( mpi_set_bit( &X, {pos}, {val} ) == 0 ); TEST_ASSERT( mpi_cmp_mpi( &X, &Y ) == 0 ); - mpi_free( &X ); + mpi_free( &X ); mpi_free( &Y ); } END_CASE