1#include <polarssl/ctr_drbg.h> 2#include <polarssl/error.h> 3#include <polarssl/entropy.h> 4#include <polarssl/ssl.h> 5 6#include <polarssl/certs.h> 7 8#include <muduo/net/Buffer.h> 9#include <string> 10#include <stdio.h> 11#include <sys/time.h> 12#include "timer.h" 13 14muduo::net::Buffer clientOut, serverOut; 15 16int net_recv(void* ctx, unsigned char* buf, size_t len) 17{ 18 muduo::net::Buffer* in = static_cast<muduo::net::Buffer*>(ctx); 19 //printf("%s recv %zd\n", in == &clientOut ? "server" : "client", len); 20 if (in->readableBytes() > 0) 21 { 22 size_t n = std::min(in->readableBytes(), len); 23 memcpy(buf, in->peek(), n); 24 in->retrieve(n); 25 26 /* 27 if (n < len) 28 printf("got %zd\n", n); 29 else 30 printf("\n"); 31 */ 32 return n; 33 } 34 else 35 { 36 //printf("got 0\n"); 37 return POLARSSL_ERR_NET_WANT_READ; 38 } 39} 40 41int net_send(void* ctx, const unsigned char* buf, size_t len) 42{ 43 muduo::net::Buffer* out = static_cast<muduo::net::Buffer*>(ctx); 44 // printf("%s send %zd\n", out == &clientOut ? "client" : "server", len); 45 out->append(buf, len); 46 return len; 47} 48 49int main(int argc, char* argv[]) 50{ 51 entropy_context entropy; 52 entropy_init(&entropy); 53 ctr_drbg_context ctr_drbg; 54 ctr_drbg_init(&ctr_drbg, entropy_func, &entropy, NULL, 0); 55 56 ssl_context ssl; 57 bzero(&ssl, sizeof ssl); 58 ssl_init(&ssl); 59 ssl_set_rng(&ssl, ctr_drbg_random, &ctr_drbg); 60 ssl_set_bio(&ssl, &net_recv, &serverOut, &net_send, &clientOut); 61 ssl_set_endpoint(&ssl, SSL_IS_CLIENT); 62 ssl_set_authmode(&ssl, SSL_VERIFY_NONE); 63 64 const char* srv_cert = test_srv_crt_ec; 65 const char* srv_key = test_srv_key_ec; 66 std::string arg = argc > 1 ? argv[1] : "r"; 67 bool useRSA = arg == "r" || arg == "er"; 68 bool useECDHE = arg == "er" || arg == "ee"; 69 if (useRSA) 70 { 71 srv_cert = test_srv_crt; 72 srv_key = test_srv_key; 73 } 74 x509_crt cert; 75 x509_crt_init(&cert); 76 // int ret = x509_crt_parse_file(&cert, argv[1]); 77 // printf("cert parse %d\n", ret); 78 x509_crt_parse(&cert, reinterpret_cast<const unsigned char*>(srv_cert), strlen(srv_cert)); 79 x509_crt_parse(&cert, reinterpret_cast<const unsigned char*>(test_ca_list), strlen(test_ca_list)); 80 81 pk_context pkey; 82 pk_init(&pkey); 83 pk_parse_key(&pkey, reinterpret_cast<const unsigned char*>(srv_key), strlen(srv_key), NULL, 0); 84 // ret = pk_parse_keyfile(&pkey, argv[2], NULL); 85 // printf("key parse %d\n", ret); 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, &clientOut, &net_send, &serverOut); 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 ecp_group_id curves[] = { POLARSSL_ECP_DP_SECP256R1, POLARSSL_ECP_DP_SECP224K1, POLARSSL_ECP_DP_NONE }; 97 ssl_set_curves(&ssl_server, curves); 98 if (useECDHE) 99 { 100 int ciphersuites[] = { TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 0 }; 101 ssl_set_ciphersuites(&ssl_server, ciphersuites); 102 } 103 else 104 { 105 int ciphersuites[] = { TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, 0 }; 106 ssl_set_ciphersuites(&ssl_server, ciphersuites); 107 } 108 109 double start = now(); 110 Timer tc, ts; 111 const int N = 500; 112 for (int i = 0; i < N; ++i) 113 { 114 ssl_session_reset(&ssl); 115 ssl_session_reset(&ssl_server); 116 while (true) 117 { 118 tc.start(); 119 int ret = ssl_handshake(&ssl); 120 tc.stop(); 121 //printf("ssl %d\n", ret); 122 if (ret < 0) 123 { 124 if (ret != POLARSSL_ERR_NET_WANT_READ) 125 { 126 char errbuf[512]; 127 polarssl_strerror(ret, errbuf, sizeof errbuf); 128 printf("client error %d %s\n", ret, errbuf); 129 break; 130 } 131 } 132 else if (ret == 0 && i == 0) 133 { 134 printf("client done %s %s\n", ssl_get_version(&ssl), ssl_get_ciphersuite(&ssl)); 135 } 136 137 ts.start(); 138 int ret2 = ssl_handshake(&ssl_server); 139 ts.stop(); 140 // printf("srv %d\n", ret2); 141 if (ret2 < 0) 142 { 143 if (ret != POLARSSL_ERR_NET_WANT_READ) 144 { 145 char errbuf[512]; 146 polarssl_strerror(ret2, errbuf, sizeof errbuf); 147 printf("server error %d %s\n", ret2, errbuf); 148 break; 149 } 150 } 151 else if (ret2 == 0) 152 { 153 // printf("server done %s %s\n", ssl_get_version(&ssl_server), ssl_get_ciphersuite(&ssl_server)); 154 } 155 156 if (ret == 0 && ret2 == 0) 157 break; 158 } 159 } 160 double elapsed = now() - start; 161 printf("%.2fs %.1f handshakes/s\n", elapsed, N / elapsed); 162 printf("client %.3f %.1f\n", tc.seconds(), N / tc.seconds()); 163 printf("server %.3f %.1f\n", ts.seconds(), N / ts.seconds()); 164 printf("server/client %.2f\n", ts.seconds() / tc.seconds()); 165 166 double start2 = now(); 167 const int M = 200; 168 unsigned char buf[16384] = { 0 }; 169 for (int i = 0; i < M*1024; ++i) 170 { 171 int n = ssl_write(&ssl, buf, 1024); 172 if (n < 0) 173 { 174 char errbuf[512]; 175 polarssl_strerror(n, errbuf, sizeof errbuf); 176 printf("%s\n", errbuf); 177 } 178 /* 179 n = ssl_read(&ssl_server, buf, 8192); 180 if (n != 1024) 181 break; 182 if (n < 0) 183 { 184 char errbuf[512]; 185 polarssl_strerror(n, errbuf, sizeof errbuf); 186 printf("%s\n", errbuf); 187 } 188 */ 189 clientOut.retrieveAll(); 190 } 191 elapsed = now() - start2; 192 printf("%.2f %.1f MiB/s\n", elapsed, M / elapsed); 193 194 ssl_free(&ssl); 195 ssl_free(&ssl_server); 196 pk_free(&pkey); 197 x509_crt_free(&cert); 198 entropy_free(&entropy); 199} 200