1a98d478eSShuo Chen#include <openssl/aes.h> 2a98d478eSShuo Chen#include <openssl/conf.h> 3a98d478eSShuo Chen#include <openssl/err.h> 4a98d478eSShuo Chen#include <openssl/ssl.h> 5a98d478eSShuo Chen 6a98d478eSShuo Chen#include <stdio.h> 7a98d478eSShuo Chen 89acb42f4SShuo Chen#include "timer.h" 99acb42f4SShuo Chen 10a98d478eSShuo Chenint main(int argc, char* argv[]) 11a98d478eSShuo Chen{ 123592419dSShuo Chen printf("Compiled with " OPENSSL_VERSION_TEXT "\n"); 13a98d478eSShuo Chen SSL_load_error_strings(); 14a98d478eSShuo Chen // ERR_load_BIO_strings(); 15a98d478eSShuo Chen SSL_library_init(); 16a98d478eSShuo Chen OPENSSL_config(NULL); 17a98d478eSShuo Chen 18b140ba61SShuo Chen SSL_CTX* ctx = SSL_CTX_new(TLSv1_2_server_method()); 193af4c543SShuo Chen SSL_CTX_set_options(ctx, SSL_OP_NO_COMPRESSION); 20a98d478eSShuo Chen 21a98d478eSShuo Chen EC_KEY* ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); 22a98d478eSShuo Chen SSL_CTX_set_options(ctx, SSL_OP_SINGLE_ECDH_USE); 23132b87adSShuo Chen // if (argc > 3) 24132b87adSShuo Chen SSL_CTX_set_tmp_ecdh(ctx, ecdh); 25a98d478eSShuo Chen EC_KEY_free(ecdh); 26a98d478eSShuo Chen 27b140ba61SShuo Chen const char* CertFile = "server.pem"; // argv[1]; 28b140ba61SShuo Chen const char* KeyFile = "server.pem"; // argv[2]; 29a98d478eSShuo Chen SSL_CTX_use_certificate_file(ctx, CertFile, SSL_FILETYPE_PEM); 30a98d478eSShuo Chen SSL_CTX_use_PrivateKey_file(ctx, KeyFile, SSL_FILETYPE_PEM); 31a98d478eSShuo Chen if (!SSL_CTX_check_private_key(ctx)) 32a98d478eSShuo Chen abort(); 33a98d478eSShuo Chen 34b140ba61SShuo Chen SSL_CTX* ctx_client = SSL_CTX_new(TLSv1_2_client_method()); 35a98d478eSShuo Chen 36a98d478eSShuo Chen double start = now(); 37a98d478eSShuo Chen const int N = 1000; 38a98d478eSShuo Chen SSL *ssl, *ssl_client; 399acb42f4SShuo Chen Timer tc, ts; 40a98d478eSShuo Chen for (int i = 0; i < N; ++i) 41a98d478eSShuo Chen { 42132b87adSShuo Chen BIO *client, *server; 43132b87adSShuo Chen BIO_new_bio_pair(&client, 0, &server, 0); 44132b87adSShuo Chen 45a98d478eSShuo Chen ssl = SSL_new (ctx); 46a98d478eSShuo Chen ssl_client = SSL_new (ctx_client); 47132b87adSShuo Chen SSL_set_bio(ssl, server, server); 48132b87adSShuo Chen SSL_set_bio(ssl_client, client, client); 49a98d478eSShuo Chen 509acb42f4SShuo Chen tc.start(); 51a98d478eSShuo Chen int ret = SSL_connect(ssl_client); 529acb42f4SShuo Chen tc.stop(); 53a98d478eSShuo Chen //printf("%d %d\n", ret, BIO_retry_type(&server)); 549acb42f4SShuo Chen ts.start(); 55a98d478eSShuo Chen int ret2 = SSL_accept(ssl); 569acb42f4SShuo Chen ts.stop(); 57a98d478eSShuo Chen //printf("%d %d\n", ret2, BIO_retry_type(&client)); 58a98d478eSShuo Chen 59a98d478eSShuo Chen while (true) 60a98d478eSShuo Chen { 619acb42f4SShuo Chen tc.start(); 629acb42f4SShuo Chen ret = SSL_do_handshake(ssl_client); 639acb42f4SShuo Chen tc.stop(); 64a98d478eSShuo Chen //printf("client handshake %d %d\n", ret, BIO_retry_type(&server)); 659acb42f4SShuo Chen ts.start(); 669acb42f4SShuo Chen ret2 = SSL_do_handshake(ssl); 679acb42f4SShuo Chen ts.stop(); 68a98d478eSShuo Chen //printf("server handshake %d %d\n", ret2, BIO_retry_type(&client)); 69a98d478eSShuo Chen //if (ret == -1 && BIO_retry_type(&server) == 0) 70a98d478eSShuo Chen // break; 71a98d478eSShuo Chen //if (ret2 == -1 && BIO_retry_type(&client) == 0) 72a98d478eSShuo Chen // break; 73a98d478eSShuo Chen if (ret == 1 && ret2 == 1) 74a98d478eSShuo Chen break; 75a98d478eSShuo Chen } 76a98d478eSShuo Chen 77a98d478eSShuo Chen if (i == 0) 783592419dSShuo Chen { 793592419dSShuo Chen printf("SSL connection using %s %s\n", SSL_get_version(ssl_client), SSL_get_cipher (ssl_client)); 803592419dSShuo Chen#ifdef OPENSSL_IS_BORINGSSL 813592419dSShuo Chen printf("Curve: %s\n", SSL_get_curve_name(SSL_get_curve_id(ssl_client))); 823592419dSShuo Chen#elif OPENSSL_VERSION_NUMBER >= 0x10002000L 833592419dSShuo Chen EVP_PKEY *key; 843592419dSShuo Chen if (SSL_get_server_tmp_key(ssl_client, &key)) 853592419dSShuo Chen { 863592419dSShuo Chen if (EVP_PKEY_id(key) == EVP_PKEY_EC) 873592419dSShuo Chen { 883592419dSShuo Chen EC_KEY *ec = EVP_PKEY_get1_EC_KEY(key); 893592419dSShuo Chen int nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec)); 903592419dSShuo Chen EC_KEY_free(ec); 913592419dSShuo Chen const char *cname = EC_curve_nid2nist(nid); 923592419dSShuo Chen if (!cname) 933592419dSShuo Chen cname = OBJ_nid2sn(nid); 943592419dSShuo Chen printf("Curve: %s, %d bits\n", cname, EVP_PKEY_bits(key)); 953592419dSShuo Chen } 963592419dSShuo Chen } 973592419dSShuo Chen#endif 983592419dSShuo Chen } 99a98d478eSShuo Chen if (i != N-1) 100a98d478eSShuo Chen { 101a98d478eSShuo Chen SSL_free (ssl); 102a98d478eSShuo Chen SSL_free (ssl_client); 103a98d478eSShuo Chen } 104a98d478eSShuo Chen } 105a98d478eSShuo Chen double elapsed = now() - start; 106a98d478eSShuo Chen printf("%.2fs %.1f handshakes/s\n", elapsed, N / elapsed); 1079acb42f4SShuo Chen printf("client %.3f %.1f\n", tc.seconds(), N / tc.seconds()); 1089acb42f4SShuo Chen printf("server %.3f %.1f\n", ts.seconds(), N / ts.seconds()); 1099acb42f4SShuo Chen printf("server/client %.2f\n", ts.seconds() / tc.seconds()); 1109acb42f4SShuo Chen 111a98d478eSShuo Chen 112a98d478eSShuo Chen double start2 = now(); 113cc4062ffSShuo Chen const int M = 1000; 114a98d478eSShuo Chen char buf[1024] = { 0 }; 115a98d478eSShuo Chen for (int i = 0; i < M*1024; ++i) 116a98d478eSShuo Chen { 117132b87adSShuo Chen int nw = SSL_write(ssl_client, buf, sizeof buf); 118132b87adSShuo Chen if (nw != sizeof buf) 119132b87adSShuo Chen { 120132b87adSShuo Chen printf("nw = %d\n", nw); 121132b87adSShuo Chen } 122132b87adSShuo Chen int nr = SSL_read(ssl, buf, sizeof buf); 123132b87adSShuo Chen if (nr != sizeof buf) 124a98d478eSShuo Chen { 125132b87adSShuo Chen printf("nr = %d\n", nr); 126a98d478eSShuo Chen } 127a98d478eSShuo Chen } 128a98d478eSShuo Chen elapsed = now() - start2; 129a98d478eSShuo Chen printf("%.2f %.1f MiB/s\n", elapsed, M / elapsed); 130a98d478eSShuo Chen SSL_free (ssl); 131a98d478eSShuo Chen SSL_free (ssl_client); 132a98d478eSShuo Chen 133a98d478eSShuo Chen SSL_CTX_free (ctx); 134a98d478eSShuo Chen SSL_CTX_free (ctx_client); 135a98d478eSShuo Chen} 136