1#include <openssl/aes.h>
2#include <openssl/conf.h>
3#include <openssl/err.h>
4#include <openssl/ssl.h>
5
6#include <malloc.h>
7#include <mcheck.h>
8#include <stdio.h>
9
10#include "timer.h"
11
12#include <string>
13#include <vector>
14
15void (*old_free_hook) (void *__ptr, const void *);
16void *(*old_malloc_hook)(size_t __size, const void *);
17
18void my_free_hook (void*, const void *);
19
20void* my_malloc_hook(size_t size, const void* caller)
21{
22  void *result;
23  /* Restore all old hooks */
24  __malloc_hook = old_malloc_hook;
25  __free_hook = old_free_hook;
26  /* Call recursively */
27  result = malloc (size);
28  /* Save underlying hooks */
29  old_malloc_hook = __malloc_hook;
30  old_free_hook = __free_hook;
31  /* printf might call malloc, so protect it too. */
32  printf ("%p malloc (%u) returns %p\n", caller, (unsigned int) size, result);
33  /* Restore our own hooks */
34  __malloc_hook = my_malloc_hook;
35  __free_hook = my_free_hook;
36  return result;
37}
38
39void my_free_hook (void *ptr, const void *caller)
40{
41  if (!ptr) return;
42  /* Restore all old hooks */
43  __malloc_hook = old_malloc_hook;
44  __free_hook = old_free_hook;
45  /* Call recursively */
46  free (ptr);
47  /* Save underlying hooks */
48  old_malloc_hook = __malloc_hook;
49  old_free_hook = __free_hook;
50  /* printf might call free, so protect it too. */
51  printf ("freed %p\n", ptr);
52  /* Restore our own hooks */
53  __malloc_hook = my_malloc_hook;
54  __free_hook = my_free_hook;
55}
56
57void init_hook()
58{
59  old_malloc_hook = __malloc_hook;
60  old_free_hook = __free_hook;
61  __malloc_hook = my_malloc_hook;
62  __free_hook = my_free_hook;
63}
64
65int main(int argc, char* argv[])
66{
67  SSL_load_error_strings();
68  ERR_load_BIO_strings();
69  SSL_library_init();
70  OPENSSL_config(NULL);
71
72  SSL_CTX* ctx = SSL_CTX_new(TLSv1_2_server_method());
73  SSL_CTX_set_options(ctx, SSL_OP_NO_COMPRESSION);
74
75  EC_KEY* ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
76  SSL_CTX_set_options(ctx, SSL_OP_SINGLE_ECDH_USE);
77  SSL_CTX_set_tmp_ecdh(ctx, ecdh);
78  EC_KEY_free(ecdh);
79
80  const char* CertFile = "server.pem";  // argv[1];
81  const char* KeyFile = "server.pem";  // argv[2];
82  SSL_CTX_use_certificate_file(ctx, CertFile, SSL_FILETYPE_PEM);
83  SSL_CTX_use_PrivateKey_file(ctx, KeyFile, SSL_FILETYPE_PEM);
84  if (!SSL_CTX_check_private_key(ctx))
85    abort();
86
87  SSL_CTX* ctx_client = SSL_CTX_new(TLSv1_2_client_method());
88
89  init_hook();
90
91  const int N = 10;
92  SSL *ssl, *ssl_client;
93  std::vector<SSL*> ssls;
94  for (int i = 0; i < N; ++i)
95  {
96    printf("=============================================== BIO_new_bio_pair %d\n", i);
97    BIO *client, *server;
98    BIO_new_bio_pair(&client, 0, &server, 0);
99
100    printf("=============================================== SSL_new server %d\n", i);
101    ssl = SSL_new (ctx);
102    printf("=============================================== SSL_new client %d\n", i);
103    ssl_client = SSL_new (ctx_client);
104    SSL_set_bio(ssl, server, server);
105    SSL_set_bio(ssl_client, client, client);
106
107    printf("=============================================== SSL_connect client %d\n", i);
108    int ret = SSL_connect(ssl_client);
109    printf("=============================================== SSL_accept server %d\n", i);
110    int ret2 = SSL_accept(ssl);
111
112    while (true)
113    {
114      printf("=============================================== SSL_handshake client %d\n", i);
115      ret = SSL_do_handshake(ssl_client);
116      printf("=============================================== SSL_handshake server %d\n", i);
117      ret2 = SSL_do_handshake(ssl);
118      if (ret == 1 && ret2 == 1)
119        break;
120    }
121
122    if (i == 0)
123      printf ("SSL connection using %s %s\n", SSL_get_version(ssl_client), SSL_get_cipher (ssl_client));
124    /*
125    if (i != N-1)
126    {
127      printf("=============================================== SSL_free server %d\n", i);
128      SSL_free (ssl);
129      printf("=============================================== SSL_free client %d\n", i);
130      SSL_free (ssl_client);
131    }
132    else
133    */
134    {
135      ssls.push_back(ssl);
136      ssls.push_back(ssl_client);
137    }
138  }
139
140  printf("=============================================== data \n");
141
142  double start2 = now();
143  const int M = 300;
144  char buf[1024] = { 0 };
145  for (int i = 0; i < M*1024; ++i)
146  {
147    int nw = SSL_write(ssl_client, buf, sizeof buf);
148    if (nw != sizeof buf)
149    {
150      printf("nw = %d\n", nw);
151    }
152    int nr = SSL_read(ssl, buf, sizeof buf);
153    if (nr != sizeof buf)
154    {
155      printf("nr = %d\n", nr);
156    }
157  }
158  double elapsed = now() - start2;
159  printf("%.2f %.1f MiB/s\n", elapsed, M / elapsed);
160  printf("=============================================== SSL_free\n");
161  for (int i = 0; i < ssls.size(); ++i)
162    SSL_free(ssls[i]);
163
164  printf("=============================================== SSL_CTX_free\n");
165  SSL_CTX_free (ctx);
166  SSL_CTX_free (ctx_client);
167  // OPENSSL_cleanup();  // only in 1.1.0
168  printf("=============================================== end\n");
169}
170