1#include <openssl/aes.h> 2#include <openssl/conf.h> 3#include <openssl/err.h> 4#include <openssl/ssl.h> 5 6#include <stdio.h> 7 8#include "timer.h" 9 10int main(int argc, char* argv[]) 11{ 12 printf("Compiled with " OPENSSL_VERSION_TEXT "\n"); 13 SSL_load_error_strings(); 14 // ERR_load_BIO_strings(); 15 SSL_library_init(); 16 OPENSSL_config(NULL); 17 18 SSL_CTX* ctx = SSL_CTX_new(TLSv1_2_server_method()); 19 SSL_CTX_set_options(ctx, SSL_OP_NO_COMPRESSION); 20 21 EC_KEY* ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); 22 SSL_CTX_set_options(ctx, SSL_OP_SINGLE_ECDH_USE); 23 // if (argc > 3) 24 SSL_CTX_set_tmp_ecdh(ctx, ecdh); 25 EC_KEY_free(ecdh); 26 27 const char* CertFile = "server.pem"; // argv[1]; 28 const char* KeyFile = "server.pem"; // argv[2]; 29 SSL_CTX_use_certificate_file(ctx, CertFile, SSL_FILETYPE_PEM); 30 SSL_CTX_use_PrivateKey_file(ctx, KeyFile, SSL_FILETYPE_PEM); 31 if (!SSL_CTX_check_private_key(ctx)) 32 abort(); 33 34 SSL_CTX* ctx_client = SSL_CTX_new(TLSv1_2_client_method()); 35 36 double start = now(); 37 const int N = 1000; 38 SSL *ssl, *ssl_client; 39 Timer tc, ts; 40 for (int i = 0; i < N; ++i) 41 { 42 BIO *client, *server; 43 BIO_new_bio_pair(&client, 0, &server, 0); 44 45 ssl = SSL_new (ctx); 46 ssl_client = SSL_new (ctx_client); 47 SSL_set_bio(ssl, server, server); 48 SSL_set_bio(ssl_client, client, client); 49 50 tc.start(); 51 int ret = SSL_connect(ssl_client); 52 tc.stop(); 53 //printf("%d %d\n", ret, BIO_retry_type(&server)); 54 ts.start(); 55 int ret2 = SSL_accept(ssl); 56 ts.stop(); 57 //printf("%d %d\n", ret2, BIO_retry_type(&client)); 58 59 while (true) 60 { 61 tc.start(); 62 ret = SSL_do_handshake(ssl_client); 63 tc.stop(); 64 //printf("client handshake %d %d\n", ret, BIO_retry_type(&server)); 65 ts.start(); 66 ret2 = SSL_do_handshake(ssl); 67 ts.stop(); 68 //printf("server handshake %d %d\n", ret2, BIO_retry_type(&client)); 69 //if (ret == -1 && BIO_retry_type(&server) == 0) 70 // break; 71 //if (ret2 == -1 && BIO_retry_type(&client) == 0) 72 // break; 73 if (ret == 1 && ret2 == 1) 74 break; 75 } 76 77 if (i == 0) 78 { 79 printf("SSL connection using %s %s\n", SSL_get_version(ssl_client), SSL_get_cipher (ssl_client)); 80#ifdef OPENSSL_IS_BORINGSSL 81 printf("Curve: %s\n", SSL_get_curve_name(SSL_get_curve_id(ssl_client))); 82#elif OPENSSL_VERSION_NUMBER >= 0x10002000L 83 EVP_PKEY *key; 84 if (SSL_get_server_tmp_key(ssl_client, &key)) 85 { 86 if (EVP_PKEY_id(key) == EVP_PKEY_EC) 87 { 88 EC_KEY *ec = EVP_PKEY_get1_EC_KEY(key); 89 int nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec)); 90 EC_KEY_free(ec); 91 const char *cname = EC_curve_nid2nist(nid); 92 if (!cname) 93 cname = OBJ_nid2sn(nid); 94 printf("Curve: %s, %d bits\n", cname, EVP_PKEY_bits(key)); 95 } 96 } 97#endif 98 } 99 if (i != N-1) 100 { 101 SSL_free (ssl); 102 SSL_free (ssl_client); 103 } 104 } 105 double elapsed = now() - start; 106 printf("%.2fs %.1f handshakes/s\n", elapsed, N / elapsed); 107 printf("client %.3f %.1f\n", tc.seconds(), N / tc.seconds()); 108 printf("server %.3f %.1f\n", ts.seconds(), N / ts.seconds()); 109 printf("server/client %.2f\n", ts.seconds() / tc.seconds()); 110 111 112 double start2 = now(); 113 const int M = 1000; 114 char buf[1024] = { 0 }; 115 for (int i = 0; i < M*1024; ++i) 116 { 117 int nw = SSL_write(ssl_client, buf, sizeof buf); 118 if (nw != sizeof buf) 119 { 120 printf("nw = %d\n", nw); 121 } 122 int nr = SSL_read(ssl, buf, sizeof buf); 123 if (nr != sizeof buf) 124 { 125 printf("nr = %d\n", nr); 126 } 127 } 128 elapsed = now() - start2; 129 printf("%.2f %.1f MiB/s\n", elapsed, M / elapsed); 130 SSL_free (ssl); 131 SSL_free (ssl_client); 132 133 SSL_CTX_free (ctx); 134 SSL_CTX_free (ctx_client); 135} 136