1/* 2 * Remember to turn off CPU frequency scaling before testing. 3 */ 4 5 6#include <polarssl/ctr_drbg.h> 7#include <polarssl/error.h> 8#include <polarssl/entropy.h> 9#include <polarssl/ssl.h> 10 11#include <polarssl/certs.h> 12 13#include <muduo/base/Thread.h> 14 15#include <boost/bind.hpp> 16 17#include <stdio.h> 18#include <sys/socket.h> 19#include <sys/time.h> 20 21bool useRSA = false; 22bool useECDHE = false; 23const int N = 500; 24 25double now() 26{ 27 struct timeval tv; 28 gettimeofday(&tv, NULL); 29 return tv.tv_sec + tv.tv_usec / 1000000.0; 30} 31 32// FIXME: net_recv with buffer 33 34void clientThread(entropy_context* entropy, int* clientFd) 35{ 36 ctr_drbg_context ctr_drbg; 37 ctr_drbg_init(&ctr_drbg, entropy_func, entropy, NULL, 0); 38 39 ssl_context ssl; 40 bzero(&ssl, sizeof ssl); 41 ssl_init(&ssl); 42 ssl_set_rng(&ssl, ctr_drbg_random, &ctr_drbg); 43 ssl_set_bio(&ssl, &net_recv, clientFd, &net_send, clientFd); 44 ssl_set_endpoint(&ssl, SSL_IS_CLIENT); 45 ssl_set_authmode(&ssl, SSL_VERIFY_NONE); 46 47 for (int i = 0; i < N; ++i) 48 { 49 ssl_session_reset( &ssl ); 50 int ret = 0; 51 while ( (ret = ssl_handshake(&ssl)) != 0) 52 { 53 if (ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE) 54 { 55 printf("client handshake failed %d\n", ret); 56 break; 57 } 58 } 59 if (i == 0) 60 printf("client done %s %s\n", ssl_get_version(&ssl), ssl_get_ciphersuite(&ssl)); 61 } 62 63 ssl_free(&ssl); 64} 65 66void serverThread(entropy_context* entropy, int* serverFd) 67{ 68 const char* srv_cert = test_srv_crt_ec; 69 const char* srv_key = test_srv_key_ec; 70 if (useRSA) 71 { 72 srv_cert = test_srv_crt; 73 srv_key = test_srv_key; 74 } 75 x509_crt cert; 76 x509_crt_init(&cert); 77 x509_crt_parse(&cert, reinterpret_cast<const unsigned char*>(srv_cert), strlen(srv_cert)); 78 x509_crt_parse(&cert, reinterpret_cast<const unsigned char*>(test_ca_list), strlen(test_ca_list)); 79 80 pk_context pkey; 81 pk_init(&pkey); 82 pk_parse_key(&pkey, reinterpret_cast<const unsigned char*>(srv_key), strlen(srv_key), NULL, 0); 83 84 ctr_drbg_context ctr_drbg; 85 ctr_drbg_init(&ctr_drbg, entropy_func, entropy, NULL, 0); 86 87 ssl_context ssl_server; 88 bzero(&ssl_server, sizeof ssl_server); 89 ssl_init(&ssl_server); 90 ssl_set_rng(&ssl_server, ctr_drbg_random, &ctr_drbg); 91 ssl_set_bio(&ssl_server, &net_recv, serverFd, &net_send, serverFd); 92 ssl_set_endpoint(&ssl_server, SSL_IS_SERVER); 93 ssl_set_authmode(&ssl_server, SSL_VERIFY_NONE); 94 ssl_set_ca_chain(&ssl_server, cert.next, NULL, NULL); 95 ssl_set_own_cert(&ssl_server, &cert, &pkey); 96 // ssl_set_dbg(&ssl_server, my_debug, (void*)"server"); 97 ecp_group_id curves[] = { POLARSSL_ECP_DP_SECP256R1, POLARSSL_ECP_DP_NONE }; 98 ssl_set_curves(&ssl_server, curves); 99 int ciphersuites[] = { TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, 0 }; 100 if (!useECDHE) 101 ssl_set_ciphersuites(&ssl_server, ciphersuites); 102 103 for (int i = 0; i < N; ++i) 104 { 105 ssl_session_reset(&ssl_server); 106 int ret = 0; 107 while ( (ret = ssl_handshake(&ssl_server)) != 0) 108 { 109 if (ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE) 110 { 111 printf("server handshake failed %d\n", ret); 112 break; 113 } 114 } 115 if (i == 0) 116 printf("server done %s %s\n", ssl_get_version(&ssl_server), ssl_get_ciphersuite(&ssl_server)); 117 } 118 119 ssl_free(&ssl_server); 120 pk_free(&pkey); 121 x509_crt_free(&cert); 122} 123 124int main(int argc, char* argv[]) 125{ 126 unsigned char buf[16384] = { 0 }; 127 entropy_context entropy; 128 entropy_init(&entropy); 129 130 if (argc > 1) 131 useRSA = true; 132 133 useECDHE = argc > 2; 134 135 int fds[2]; 136 if (::socketpair(AF_UNIX, SOCK_STREAM, 0, fds)) 137 abort(); 138 139 double start = now(); 140 muduo::Thread client(boost::bind(&clientThread, &entropy, &fds[0]), "ssl client"); 141 muduo::Thread server(boost::bind(&serverThread, &entropy, &fds[1]), "ssl server"); 142 client.start(); 143 server.start(); 144 145 client.join(); 146 server.join(); 147 double elapsed = now() - start; 148 printf("%.2fs %.1f handshakes/s\n", elapsed, N / elapsed); 149 entropy_free(&entropy); 150} 151