1
/* $Id: ssl_sock.c 4537 2013-06-19 06:47:43Z riza $ */
3
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24
#define CERT_DIR "../build/"
25
#define CERT_CA_FILE CERT_DIR "cacert.pem"
26
#define CERT_FILE CERT_DIR "cacert.pem"
27
#define CERT_PRIVKEY_FILE CERT_DIR "privkey.pem"
28
#define CERT_PRIVKEY_PASS ""
31
#if INCLUDE_SSLSOCK_TEST
34
static int clients_num;
37
pj_ioqueue_op_key_t op_key;
41
static int get_cipher_list(void) {
43
pj_ssl_cipher ciphers[100];
47
cipher_num = PJ_ARRAY_SIZE(ciphers);
48
status = pj_ssl_cipher_get_availables(ciphers, &cipher_num);
49
if (status != PJ_SUCCESS) {
50
app_perror("...FAILED to get available ciphers", status);
54
PJ_LOG(3, ("", "...Found %u ciphers:", cipher_num));
55
for (i = 0; i < cipher_num; ++i) {
57
st = pj_ssl_cipher_name(ciphers[i]);
61
PJ_LOG(3, ("", "...%3u: 0x%08x=%s", i+1, ciphers[i], st));
70
pj_pool_t *pool; /* pool */
71
pj_ioqueue_t *ioqueue; /* ioqueue */
72
pj_bool_t is_server; /* server role flag */
73
pj_bool_t is_verbose; /* verbose flag, e.g: cert info */
74
pj_bool_t echo; /* echo received data */
75
pj_status_t err; /* error flag */
76
pj_size_t sent; /* bytes sent */
77
pj_size_t recv; /* bytes received */
78
pj_uint8_t read_buf[256]; /* read buffer */
79
pj_bool_t done; /* test done flag */
80
char *send_str; /* data to send once connected */
81
pj_size_t send_str_len; /* send data length */
82
pj_bool_t check_echo; /* flag to compare sent & echoed data */
83
const char *check_echo_ptr; /* pointer/cursor for comparing data */
84
struct send_key send_key; /* send op key */
87
static void dump_ssl_info(const pj_ssl_sock_info *si)
91
/* Print cipher name */
92
tmp_st = pj_ssl_cipher_name(si->cipher);
95
PJ_LOG(3, ("", ".....Cipher: %s", tmp_st));
97
/* Print remote certificate info and verification result */
98
if (si->remote_cert_info && si->remote_cert_info->subject.info.slen)
101
const char *verif_msgs[32];
102
unsigned verif_msg_cnt;
104
/* Dump remote TLS certificate info */
105
PJ_LOG(3, ("", ".....Remote certificate info:"));
106
pj_ssl_cert_info_dump(si->remote_cert_info, " ", buf, sizeof(buf));
107
PJ_LOG(3,("", "\n%s", buf));
109
/* Dump remote TLS certificate verification result */
110
verif_msg_cnt = PJ_ARRAY_SIZE(verif_msgs);
111
pj_ssl_cert_get_verify_status_strings(si->verify_status,
112
verif_msgs, &verif_msg_cnt);
113
PJ_LOG(3,("", ".....Remote certificate verification result: %s",
114
(verif_msg_cnt == 1? verif_msgs[0]:"")));
115
if (verif_msg_cnt > 1) {
117
for (i = 0; i < verif_msg_cnt; ++i)
118
PJ_LOG(3,("", "..... - %s", verif_msgs[i]));
124
static pj_bool_t ssl_on_connect_complete(pj_ssl_sock_t *ssock,
127
struct test_state *st = (struct test_state*)
128
pj_ssl_sock_get_user_data(ssock);
130
pj_ssl_sock_info info;
131
char buf1[64], buf2[64];
133
if (status != PJ_SUCCESS) {
134
app_perror("...ERROR ssl_on_connect_complete()", status);
138
status = pj_ssl_sock_get_info(ssock, &info);
139
if (status != PJ_SUCCESS) {
140
app_perror("...ERROR pj_ssl_sock_get_info()", status);
144
pj_sockaddr_print((pj_sockaddr_t*)&info.local_addr, buf1, sizeof(buf1), 1);
145
pj_sockaddr_print((pj_sockaddr_t*)&info.remote_addr, buf2, sizeof(buf2), 1);
146
PJ_LOG(3, ("", "...Connected %s -> %s!", buf1, buf2));
149
dump_ssl_info(&info);
151
/* Start reading data */
152
read_buf[0] = st->read_buf;
153
status = pj_ssl_sock_start_read2(ssock, st->pool, sizeof(st->read_buf), (void**)read_buf, 0);
154
if (status != PJ_SUCCESS) {
155
app_perror("...ERROR pj_ssl_sock_start_read2()", status);
159
/* Start sending data */
160
while (st->sent < st->send_str_len) {
163
size = st->send_str_len - st->sent;
164
status = pj_ssl_sock_send(ssock, (pj_ioqueue_op_key_t*)&st->send_key,
165
st->send_str + st->sent, &size, 0);
166
if (status != PJ_SUCCESS && status != PJ_EPENDING) {
167
app_perror("...ERROR pj_ssl_sock_send()", status);
171
if (status == PJ_SUCCESS)
180
if (st->err != PJ_SUCCESS) {
181
pj_ssl_sock_close(ssock);
190
static pj_bool_t ssl_on_accept_complete(pj_ssl_sock_t *ssock,
191
pj_ssl_sock_t *newsock,
192
const pj_sockaddr_t *src_addr,
195
struct test_state *parent_st = (struct test_state*)
196
pj_ssl_sock_get_user_data(ssock);
197
struct test_state *st;
199
pj_ssl_sock_info info;
203
PJ_UNUSED_ARG(src_addr_len);
205
/* Duplicate parent test state to newly accepted test state */
206
st = (struct test_state*)pj_pool_zalloc(parent_st->pool, sizeof(struct test_state));
208
pj_ssl_sock_set_user_data(newsock, st);
210
status = pj_ssl_sock_get_info(newsock, &info);
211
if (status != PJ_SUCCESS) {
212
app_perror("...ERROR pj_ssl_sock_get_info()", status);
216
pj_sockaddr_print(src_addr, buf, sizeof(buf), 1);
217
PJ_LOG(3, ("", "...Accepted connection from %s", buf));
220
dump_ssl_info(&info);
222
/* Start reading data */
223
read_buf[0] = st->read_buf;
224
status = pj_ssl_sock_start_read2(newsock, st->pool, sizeof(st->read_buf), (void**)read_buf, 0);
225
if (status != PJ_SUCCESS) {
226
app_perror("...ERROR pj_ssl_sock_start_read2()", status);
230
/* Start sending data */
231
while (st->sent < st->send_str_len) {
234
size = st->send_str_len - st->sent;
235
status = pj_ssl_sock_send(newsock, (pj_ioqueue_op_key_t*)&st->send_key,
236
st->send_str + st->sent, &size, 0);
237
if (status != PJ_SUCCESS && status != PJ_EPENDING) {
238
app_perror("...ERROR pj_ssl_sock_send()", status);
242
if (status == PJ_SUCCESS)
251
if (st->err != PJ_SUCCESS) {
252
pj_ssl_sock_close(newsock);
259
static pj_bool_t ssl_on_data_read(pj_ssl_sock_t *ssock,
263
pj_size_t *remainder)
265
struct test_state *st = (struct test_state*)
266
pj_ssl_sock_get_user_data(ssock);
268
PJ_UNUSED_ARG(remainder);
274
/* Set random remainder */
275
*remainder = pj_rand() % 100;
277
/* Apply zero remainder if:
278
* - remainder is less than size, or
279
* - connection closed/error
280
* - echo/check_eco set
282
if (*remainder > size || status != PJ_SUCCESS || st->echo || st->check_echo)
285
consumed = size - *remainder;
286
st->recv += consumed;
288
//printf("%.*s", consumed, (char*)data);
290
pj_memmove(data, (char*)data + consumed, *remainder);
292
/* Echo data when specified to */
294
pj_ssize_t size_ = consumed;
295
status = pj_ssl_sock_send(ssock, (pj_ioqueue_op_key_t*)&st->send_key, data, &size_, 0);
296
if (status != PJ_SUCCESS && status != PJ_EPENDING) {
297
app_perror("...ERROR pj_ssl_sock_send()", status);
301
if (status == PJ_SUCCESS)
305
/* Verify echoed data when specified to */
306
if (st->check_echo) {
307
if (!st->check_echo_ptr)
308
st->check_echo_ptr = st->send_str;
310
if (pj_memcmp(st->check_echo_ptr, data, consumed)) {
312
app_perror("...ERROR echoed data not exact", status);
315
st->check_echo_ptr += consumed;
317
/* Echo received completely */
318
if (st->send_str_len == st->recv) {
319
pj_ssl_sock_info info;
322
status = pj_ssl_sock_get_info(ssock, &info);
323
if (status != PJ_SUCCESS) {
324
app_perror("...ERROR pj_ssl_sock_get_info()", status);
328
pj_sockaddr_print((pj_sockaddr_t*)&info.local_addr, buf, sizeof(buf), 1);
329
PJ_LOG(3, ("", "...%s successfully recv %d bytes echo", buf, st->recv));
335
if (status != PJ_SUCCESS) {
336
if (status == PJ_EEOF) {
340
app_perror("...ERROR ssl_on_data_read()", status);
347
if (st->err != PJ_SUCCESS || st->done) {
348
pj_ssl_sock_close(ssock);
357
static pj_bool_t ssl_on_data_sent(pj_ssl_sock_t *ssock,
358
pj_ioqueue_op_key_t *op_key,
361
struct test_state *st = (struct test_state*)
362
pj_ssl_sock_get_user_data(ssock);
363
PJ_UNUSED_ARG(op_key);
366
st->err = (pj_status_t)-sent;
370
/* Send more if any */
371
while (st->sent < st->send_str_len) {
375
size = st->send_str_len - st->sent;
376
status = pj_ssl_sock_send(ssock, (pj_ioqueue_op_key_t*)&st->send_key,
377
st->send_str + st->sent, &size, 0);
378
if (status != PJ_SUCCESS && status != PJ_EPENDING) {
379
app_perror("...ERROR pj_ssl_sock_send()", status);
384
if (status == PJ_SUCCESS)
391
if (st->err != PJ_SUCCESS) {
392
pj_ssl_sock_close(ssock);
401
#define HTTP_REQ "GET / HTTP/1.0\r\n\r\n";
402
#define HTTP_SERVER_ADDR "trac.pjsip.org"
403
#define HTTP_SERVER_PORT 443
405
static int https_client_test(unsigned ms_timeout)
407
pj_pool_t *pool = NULL;
408
pj_ioqueue_t *ioqueue = NULL;
409
pj_timer_heap_t *timer = NULL;
410
pj_ssl_sock_t *ssock = NULL;
411
pj_ssl_sock_param param;
413
struct test_state state = {0};
414
pj_sockaddr local_addr, rem_addr;
417
pool = pj_pool_create(mem, "https_get", 256, 256, NULL);
419
status = pj_ioqueue_create(pool, 4, &ioqueue);
420
if (status != PJ_SUCCESS) {
424
status = pj_timer_heap_create(pool, 4, &timer);
425
if (status != PJ_SUCCESS) {
430
state.send_str = HTTP_REQ;
431
state.send_str_len = pj_ansi_strlen(state.send_str);
432
state.is_verbose = PJ_TRUE;
434
pj_ssl_sock_param_default(¶m);
435
param.cb.on_connect_complete = &ssl_on_connect_complete;
436
param.cb.on_data_read = &ssl_on_data_read;
437
param.cb.on_data_sent = &ssl_on_data_sent;
438
param.ioqueue = ioqueue;
439
param.user_data = &state;
440
param.server_name = pj_str((char*)HTTP_SERVER_ADDR);
441
param.timer_heap = timer;
442
param.timeout.sec = 0;
443
param.timeout.msec = ms_timeout;
444
param.proto = PJ_SSL_SOCK_PROTO_SSL23;
445
pj_time_val_normalize(¶m.timeout);
447
status = pj_ssl_sock_create(pool, ¶m, &ssock);
448
if (status != PJ_SUCCESS) {
452
pj_sockaddr_init(PJ_AF_INET, &local_addr, pj_strset2(&tmp_st, "0.0.0.0"), 0);
453
pj_sockaddr_init(PJ_AF_INET, &rem_addr, pj_strset2(&tmp_st, HTTP_SERVER_ADDR), HTTP_SERVER_PORT);
454
status = pj_ssl_sock_start_connect(ssock, pool, &local_addr, &rem_addr, sizeof(rem_addr));
455
if (status == PJ_SUCCESS) {
456
ssl_on_connect_complete(ssock, PJ_SUCCESS);
457
} else if (status == PJ_EPENDING) {
463
/* Wait until everything has been sent/received */
464
while (state.err == PJ_SUCCESS && !state.done) {
466
pj_symbianos_poll(-1, 1000);
468
pj_time_val delay = {0, 100};
469
pj_ioqueue_poll(ioqueue, &delay);
470
pj_timer_heap_poll(timer, &delay);
479
PJ_LOG(3, ("", "...Done!"));
480
PJ_LOG(3, ("", ".....Sent/recv: %d/%d bytes", state.sent, state.recv));
483
if (ssock && !state.err && !state.done)
484
pj_ssl_sock_close(ssock);
486
pj_ioqueue_destroy(ioqueue);
488
pj_timer_heap_destroy(timer);
490
pj_pool_release(pool);
496
static int echo_test(pj_ssl_sock_proto srv_proto, pj_ssl_sock_proto cli_proto,
497
pj_ssl_cipher srv_cipher, pj_ssl_cipher cli_cipher,
498
pj_bool_t req_client_cert, pj_bool_t client_provide_cert)
500
pj_pool_t *pool = NULL;
501
pj_ioqueue_t *ioqueue = NULL;
502
pj_ssl_sock_t *ssock_serv = NULL;
503
pj_ssl_sock_t *ssock_cli = NULL;
504
pj_ssl_sock_param param;
505
struct test_state state_serv = { 0 };
506
struct test_state state_cli = { 0 };
507
pj_sockaddr addr, listen_addr;
508
pj_ssl_cipher ciphers[1];
509
pj_ssl_cert_t *cert = NULL;
512
pool = pj_pool_create(mem, "ssl_echo", 256, 256, NULL);
514
status = pj_ioqueue_create(pool, 4, &ioqueue);
515
if (status != PJ_SUCCESS) {
519
pj_ssl_sock_param_default(¶m);
520
param.cb.on_accept_complete = &ssl_on_accept_complete;
521
param.cb.on_connect_complete = &ssl_on_connect_complete;
522
param.cb.on_data_read = &ssl_on_data_read;
523
param.cb.on_data_sent = &ssl_on_data_sent;
524
param.ioqueue = ioqueue;
525
param.ciphers = ciphers;
527
/* Init default bind address */
530
pj_sockaddr_init(PJ_AF_INET, &addr, pj_strset2(&tmp_st, "127.0.0.1"), 0);
534
param.proto = srv_proto;
535
param.user_data = &state_serv;
536
param.ciphers_num = (srv_cipher == -1)? 0 : 1;
537
param.require_client_cert = req_client_cert;
538
ciphers[0] = srv_cipher;
540
state_serv.pool = pool;
541
state_serv.echo = PJ_TRUE;
542
state_serv.is_server = PJ_TRUE;
543
state_serv.is_verbose = PJ_TRUE;
545
status = pj_ssl_sock_create(pool, ¶m, &ssock_serv);
546
if (status != PJ_SUCCESS) {
550
/* Set server cert */
552
pj_str_t tmp1, tmp2, tmp3, tmp4;
554
status = pj_ssl_cert_load_from_files(pool,
555
pj_strset2(&tmp1, (char*)CERT_CA_FILE),
556
pj_strset2(&tmp2, (char*)CERT_FILE),
557
pj_strset2(&tmp3, (char*)CERT_PRIVKEY_FILE),
558
pj_strset2(&tmp4, (char*)CERT_PRIVKEY_PASS),
560
if (status != PJ_SUCCESS) {
564
status = pj_ssl_sock_set_certificate(ssock_serv, pool, cert);
565
if (status != PJ_SUCCESS) {
570
status = pj_ssl_sock_start_accept(ssock_serv, pool, &addr, pj_sockaddr_get_len(&addr));
571
if (status != PJ_SUCCESS) {
575
/* Get listener address */
577
pj_ssl_sock_info info;
579
pj_ssl_sock_get_info(ssock_serv, &info);
580
pj_sockaddr_cp(&listen_addr, &info.local_addr);
584
param.proto = cli_proto;
585
param.user_data = &state_cli;
586
param.ciphers_num = (cli_cipher == -1)? 0 : 1;
587
ciphers[0] = cli_cipher;
589
state_cli.pool = pool;
590
state_cli.check_echo = PJ_TRUE;
591
state_cli.is_verbose = PJ_TRUE;
596
pj_gettimeofday(&now);
597
pj_srand((unsigned)now.sec);
598
state_cli.send_str_len = (pj_rand() % 5 + 1) * 1024 + pj_rand() % 1024;
600
state_cli.send_str = (char*)pj_pool_alloc(pool, state_cli.send_str_len);
603
for (i = 0; i < state_cli.send_str_len; ++i)
604
state_cli.send_str[i] = (char)(pj_rand() % 256);
607
status = pj_ssl_sock_create(pool, ¶m, &ssock_cli);
608
if (status != PJ_SUCCESS) {
612
/* Set cert for client */
615
if (!client_provide_cert) {
618
pj_strset2(&tmp1, (char*)CERT_CA_FILE);
619
pj_strset2(&tmp2, NULL);
620
status = pj_ssl_cert_load_from_files(pool,
621
&tmp1, &tmp2, &tmp2, &tmp2,
623
if (status != PJ_SUCCESS) {
628
status = pj_ssl_sock_set_certificate(ssock_cli, pool, cert);
629
if (status != PJ_SUCCESS) {
634
status = pj_ssl_sock_start_connect(ssock_cli, pool, &addr, &listen_addr, pj_sockaddr_get_len(&addr));
635
if (status == PJ_SUCCESS) {
636
ssl_on_connect_complete(ssock_cli, PJ_SUCCESS);
637
} else if (status == PJ_EPENDING) {
643
/* Wait until everything has been sent/received or error */
644
while (!state_serv.err && !state_cli.err && !state_serv.done && !state_cli.done)
647
pj_symbianos_poll(-1, 1000);
649
pj_time_val delay = {0, 100};
650
pj_ioqueue_poll(ioqueue, &delay);
654
/* Clean up sockets */
656
pj_time_val delay = {0, 100};
657
while (pj_ioqueue_poll(ioqueue, &delay) > 0);
660
if (state_serv.err || state_cli.err) {
661
if (state_serv.err != PJ_SUCCESS)
662
status = state_serv.err;
664
status = state_cli.err;
669
PJ_LOG(3, ("", "...Done!"));
670
PJ_LOG(3, ("", ".....Sent/recv: %d/%d bytes", state_cli.sent, state_cli.recv));
674
pj_ssl_sock_close(ssock_serv);
675
if (ssock_cli && !state_cli.err && !state_cli.done)
676
pj_ssl_sock_close(ssock_cli);
678
pj_ioqueue_destroy(ioqueue);
680
pj_pool_release(pool);
686
static pj_bool_t asock_on_data_read(pj_activesock_t *asock,
690
pj_size_t *remainder)
692
struct test_state *st = (struct test_state*)
693
pj_activesock_get_user_data(asock);
697
PJ_UNUSED_ARG(remainder);
699
if (status != PJ_SUCCESS) {
700
if (status == PJ_EEOF) {
704
app_perror("...ERROR asock_on_data_read()", status);
710
if (st->err != PJ_SUCCESS || st->done) {
711
pj_activesock_close(asock);
721
static pj_bool_t asock_on_connect_complete(pj_activesock_t *asock,
724
struct test_state *st = (struct test_state*)
725
pj_activesock_get_user_data(asock);
727
if (status == PJ_SUCCESS) {
730
/* Start reading data */
731
read_buf[0] = st->read_buf;
732
status = pj_activesock_start_read2(asock, st->pool, sizeof(st->read_buf), (void**)read_buf, 0);
733
if (status != PJ_SUCCESS) {
734
app_perror("...ERROR pj_ssl_sock_start_read2()", status);
740
if (st->err != PJ_SUCCESS) {
741
pj_activesock_close(asock);
750
static pj_bool_t asock_on_accept_complete(pj_activesock_t *asock,
752
const pj_sockaddr_t *src_addr,
755
struct test_state *st;
757
pj_activesock_t *new_asock;
758
pj_activesock_cb asock_cb = { 0 };
761
PJ_UNUSED_ARG(src_addr);
762
PJ_UNUSED_ARG(src_addr_len);
764
st = (struct test_state*) pj_activesock_get_user_data(asock);
766
asock_cb.on_data_read = &asock_on_data_read;
767
status = pj_activesock_create(st->pool, newsock, pj_SOCK_STREAM(), NULL,
768
st->ioqueue, &asock_cb, st, &new_asock);
769
if (status != PJ_SUCCESS) {
773
/* Start reading data */
774
read_buf[0] = st->read_buf;
775
status = pj_activesock_start_read2(new_asock, st->pool,
776
sizeof(st->read_buf),
777
(void**)read_buf, 0);
778
if (status != PJ_SUCCESS) {
779
app_perror("...ERROR pj_ssl_sock_start_read2()", status);
785
if (st->err != PJ_SUCCESS)
786
pj_activesock_close(new_asock);
792
/* Raw TCP socket try to connect to SSL socket server, once
793
* connection established, it will just do nothing, SSL socket
794
* server should be able to close the connection after specified
795
* timeout period (set ms_timeout to 0 to disable timer).
797
static int client_non_ssl(unsigned ms_timeout)
799
pj_pool_t *pool = NULL;
800
pj_ioqueue_t *ioqueue = NULL;
801
pj_timer_heap_t *timer = NULL;
802
pj_ssl_sock_t *ssock_serv = NULL;
803
pj_activesock_t *asock_cli = NULL;
804
pj_activesock_cb asock_cb = { 0 };
805
pj_sock_t sock = PJ_INVALID_SOCKET;
806
pj_ssl_sock_param param;
807
struct test_state state_serv = { 0 };
808
struct test_state state_cli = { 0 };
809
pj_sockaddr listen_addr;
810
pj_ssl_cert_t *cert = NULL;
813
pool = pj_pool_create(mem, "ssl_accept_raw_tcp", 256, 256, NULL);
815
status = pj_ioqueue_create(pool, 4, &ioqueue);
816
if (status != PJ_SUCCESS) {
820
status = pj_timer_heap_create(pool, 4, &timer);
821
if (status != PJ_SUCCESS) {
827
pj_str_t tmp1, tmp2, tmp3, tmp4;
828
status = pj_ssl_cert_load_from_files(pool,
829
pj_strset2(&tmp1, (char*)CERT_CA_FILE),
830
pj_strset2(&tmp2, (char*)CERT_FILE),
831
pj_strset2(&tmp3, (char*)CERT_PRIVKEY_FILE),
832
pj_strset2(&tmp4, (char*)CERT_PRIVKEY_PASS),
834
if (status != PJ_SUCCESS) {
839
pj_ssl_sock_param_default(¶m);
840
param.cb.on_accept_complete = &ssl_on_accept_complete;
841
param.cb.on_data_read = &ssl_on_data_read;
842
param.cb.on_data_sent = &ssl_on_data_sent;
843
param.ioqueue = ioqueue;
844
param.timer_heap = timer;
845
param.timeout.sec = 0;
846
param.timeout.msec = ms_timeout;
847
pj_time_val_normalize(¶m.timeout);
850
param.user_data = &state_serv;
851
state_serv.pool = pool;
852
state_serv.is_server = PJ_TRUE;
853
state_serv.is_verbose = PJ_TRUE;
855
status = pj_ssl_sock_create(pool, ¶m, &ssock_serv);
856
if (status != PJ_SUCCESS) {
860
status = pj_ssl_sock_set_certificate(ssock_serv, pool, cert);
861
if (status != PJ_SUCCESS) {
865
/* Init bind address */
868
pj_sockaddr_init(PJ_AF_INET, &listen_addr, pj_strset2(&tmp_st, "127.0.0.1"), 0);
871
status = pj_ssl_sock_start_accept(ssock_serv, pool, &listen_addr, pj_sockaddr_get_len(&listen_addr));
872
if (status != PJ_SUCCESS) {
876
/* Update listener address */
878
pj_ssl_sock_info info;
880
pj_ssl_sock_get_info(ssock_serv, &info);
881
pj_sockaddr_cp(&listen_addr, &info.local_addr);
885
state_cli.pool = pool;
886
status = pj_sock_socket(pj_AF_INET(), pj_SOCK_STREAM(), 0, &sock);
887
if (status != PJ_SUCCESS) {
891
asock_cb.on_connect_complete = &asock_on_connect_complete;
892
asock_cb.on_data_read = &asock_on_data_read;
893
status = pj_activesock_create(pool, sock, pj_SOCK_STREAM(), NULL,
894
ioqueue, &asock_cb, &state_cli, &asock_cli);
895
if (status != PJ_SUCCESS) {
899
status = pj_activesock_start_connect(asock_cli, pool, (pj_sockaddr_t*)&listen_addr,
900
pj_sockaddr_get_len(&listen_addr));
901
if (status == PJ_SUCCESS) {
902
asock_on_connect_complete(asock_cli, PJ_SUCCESS);
903
} else if (status == PJ_EPENDING) {
909
/* Wait until everything has been sent/received or error */
910
while (!state_serv.err && !state_cli.err && !state_serv.done && !state_cli.done)
913
pj_symbianos_poll(-1, 1000);
915
pj_time_val delay = {0, 100};
916
pj_ioqueue_poll(ioqueue, &delay);
917
pj_timer_heap_poll(timer, &delay);
921
if (state_serv.err || state_cli.err) {
922
if (state_serv.err != PJ_SUCCESS)
923
status = state_serv.err;
925
status = state_cli.err;
930
PJ_LOG(3, ("", "...Done!"));
934
pj_ssl_sock_close(ssock_serv);
935
if (asock_cli && !state_cli.err && !state_cli.done)
936
pj_activesock_close(asock_cli);
938
pj_timer_heap_destroy(timer);
940
pj_ioqueue_destroy(ioqueue);
942
pj_pool_release(pool);
948
/* SSL socket try to connect to raw TCP socket server, once
949
* connection established, SSL socket will try to perform SSL
950
* handshake. SSL client socket should be able to close the
951
* connection after specified timeout period (set ms_timeout to
952
* 0 to disable timer).
954
static int server_non_ssl(unsigned ms_timeout)
956
pj_pool_t *pool = NULL;
957
pj_ioqueue_t *ioqueue = NULL;
958
pj_timer_heap_t *timer = NULL;
959
pj_activesock_t *asock_serv = NULL;
960
pj_ssl_sock_t *ssock_cli = NULL;
961
pj_activesock_cb asock_cb = { 0 };
962
pj_sock_t sock = PJ_INVALID_SOCKET;
963
pj_ssl_sock_param param;
964
struct test_state state_serv = { 0 };
965
struct test_state state_cli = { 0 };
966
pj_sockaddr addr, listen_addr;
969
pool = pj_pool_create(mem, "ssl_connect_raw_tcp", 256, 256, NULL);
971
status = pj_ioqueue_create(pool, 4, &ioqueue);
972
if (status != PJ_SUCCESS) {
976
status = pj_timer_heap_create(pool, 4, &timer);
977
if (status != PJ_SUCCESS) {
982
state_serv.pool = pool;
983
state_serv.ioqueue = ioqueue;
985
status = pj_sock_socket(pj_AF_INET(), pj_SOCK_STREAM(), 0, &sock);
986
if (status != PJ_SUCCESS) {
990
/* Init bind address */
993
pj_sockaddr_init(PJ_AF_INET, &listen_addr, pj_strset2(&tmp_st, "127.0.0.1"), 0);
996
status = pj_sock_bind(sock, (pj_sockaddr_t*)&listen_addr,
997
pj_sockaddr_get_len((pj_sockaddr_t*)&listen_addr));
998
if (status != PJ_SUCCESS) {
1002
status = pj_sock_listen(sock, PJ_SOMAXCONN);
1003
if (status != PJ_SUCCESS) {
1007
asock_cb.on_accept_complete = &asock_on_accept_complete;
1008
status = pj_activesock_create(pool, sock, pj_SOCK_STREAM(), NULL,
1009
ioqueue, &asock_cb, &state_serv, &asock_serv);
1010
if (status != PJ_SUCCESS) {
1014
status = pj_activesock_start_accept(asock_serv, pool);
1015
if (status != PJ_SUCCESS)
1018
/* Update listener address */
1022
addr_len = sizeof(listen_addr);
1023
pj_sock_getsockname(sock, (pj_sockaddr_t*)&listen_addr, &addr_len);
1027
pj_ssl_sock_param_default(¶m);
1028
param.cb.on_connect_complete = &ssl_on_connect_complete;
1029
param.cb.on_data_read = &ssl_on_data_read;
1030
param.cb.on_data_sent = &ssl_on_data_sent;
1031
param.ioqueue = ioqueue;
1032
param.timer_heap = timer;
1033
param.timeout.sec = 0;
1034
param.timeout.msec = ms_timeout;
1035
pj_time_val_normalize(¶m.timeout);
1036
param.user_data = &state_cli;
1038
state_cli.pool = pool;
1039
state_cli.is_server = PJ_FALSE;
1040
state_cli.is_verbose = PJ_TRUE;
1042
status = pj_ssl_sock_create(pool, ¶m, &ssock_cli);
1043
if (status != PJ_SUCCESS) {
1047
/* Init default bind address */
1050
pj_sockaddr_init(PJ_AF_INET, &addr, pj_strset2(&tmp_st, "127.0.0.1"), 0);
1053
status = pj_ssl_sock_start_connect(ssock_cli, pool,
1054
(pj_sockaddr_t*)&addr,
1055
(pj_sockaddr_t*)&listen_addr,
1056
pj_sockaddr_get_len(&listen_addr));
1057
if (status != PJ_EPENDING) {
1061
/* Wait until everything has been sent/received or error */
1062
while ((!state_serv.err && !state_serv.done) || (!state_cli.err && !state_cli.done))
1065
pj_symbianos_poll(-1, 1000);
1067
pj_time_val delay = {0, 100};
1068
pj_ioqueue_poll(ioqueue, &delay);
1069
pj_timer_heap_poll(timer, &delay);
1073
if (state_serv.err || state_cli.err) {
1074
if (state_cli.err != PJ_SUCCESS)
1075
status = state_cli.err;
1077
status = state_serv.err;
1082
PJ_LOG(3, ("", "...Done!"));
1086
pj_activesock_close(asock_serv);
1087
if (ssock_cli && !state_cli.err && !state_cli.done)
1088
pj_ssl_sock_close(ssock_cli);
1090
pj_timer_heap_destroy(timer);
1092
pj_ioqueue_destroy(ioqueue);
1094
pj_pool_release(pool);
1100
/* Test will perform multiple clients trying to connect to single server.
1101
* Once SSL connection established, echo test will be performed.
1103
static int perf_test(unsigned clients, unsigned ms_handshake_timeout)
1105
pj_pool_t *pool = NULL;
1106
pj_ioqueue_t *ioqueue = NULL;
1107
pj_timer_heap_t *timer = NULL;
1108
pj_ssl_sock_t *ssock_serv = NULL;
1109
pj_ssl_sock_t **ssock_cli = NULL;
1110
pj_ssl_sock_param param;
1111
struct test_state state_serv = { 0 };
1112
struct test_state *state_cli = NULL;
1113
pj_sockaddr addr, listen_addr;
1114
pj_ssl_cert_t *cert = NULL;
1116
unsigned i, cli_err = 0;
1117
pj_size_t tot_sent = 0, tot_recv = 0;
1120
pool = pj_pool_create(mem, "ssl_perf", 256, 256, NULL);
1122
status = pj_ioqueue_create(pool, PJ_IOQUEUE_MAX_HANDLES, &ioqueue);
1123
if (status != PJ_SUCCESS) {
1127
status = pj_timer_heap_create(pool, PJ_IOQUEUE_MAX_HANDLES, &timer);
1128
if (status != PJ_SUCCESS) {
1134
pj_str_t tmp1, tmp2, tmp3, tmp4;
1136
status = pj_ssl_cert_load_from_files(pool,
1137
pj_strset2(&tmp1, (char*)CERT_CA_FILE),
1138
pj_strset2(&tmp2, (char*)CERT_FILE),
1139
pj_strset2(&tmp3, (char*)CERT_PRIVKEY_FILE),
1140
pj_strset2(&tmp4, (char*)CERT_PRIVKEY_PASS),
1142
if (status != PJ_SUCCESS) {
1147
pj_ssl_sock_param_default(¶m);
1148
param.cb.on_accept_complete = &ssl_on_accept_complete;
1149
param.cb.on_connect_complete = &ssl_on_connect_complete;
1150
param.cb.on_data_read = &ssl_on_data_read;
1151
param.cb.on_data_sent = &ssl_on_data_sent;
1152
param.ioqueue = ioqueue;
1153
param.timer_heap = timer;
1154
param.timeout.sec = 0;
1155
param.timeout.msec = ms_handshake_timeout;
1156
pj_time_val_normalize(¶m.timeout);
1158
/* Init default bind address */
1161
pj_sockaddr_init(PJ_AF_INET, &addr, pj_strset2(&tmp_st, "127.0.0.1"), 0);
1165
param.user_data = &state_serv;
1167
state_serv.pool = pool;
1168
state_serv.echo = PJ_TRUE;
1169
state_serv.is_server = PJ_TRUE;
1171
status = pj_ssl_sock_create(pool, ¶m, &ssock_serv);
1172
if (status != PJ_SUCCESS) {
1176
status = pj_ssl_sock_set_certificate(ssock_serv, pool, cert);
1177
if (status != PJ_SUCCESS) {
1181
status = pj_ssl_sock_start_accept(ssock_serv, pool, &addr, pj_sockaddr_get_len(&addr));
1182
if (status != PJ_SUCCESS) {
1186
/* Get listening address for clients to connect to */
1188
pj_ssl_sock_info info;
1191
pj_ssl_sock_get_info(ssock_serv, &info);
1192
pj_sockaddr_cp(&listen_addr, &info.local_addr);
1194
pj_sockaddr_print((pj_sockaddr_t*)&listen_addr, buf, sizeof(buf), 1);
1195
PJ_LOG(3, ("", "...Listener ready at %s", buf));
1200
clients_num = clients;
1201
param.timeout.sec = 0;
1202
param.timeout.msec = 0;
1204
/* Init random seed */
1208
pj_gettimeofday(&now);
1209
pj_srand((unsigned)now.sec);
1212
/* Allocate SSL socket pointers and test state */
1213
ssock_cli = (pj_ssl_sock_t**)pj_pool_calloc(pool, clients, sizeof(pj_ssl_sock_t*));
1214
state_cli = (struct test_state*)pj_pool_calloc(pool, clients, sizeof(struct test_state));
1216
/* Get start timestamp */
1217
pj_gettimeofday(&start);
1220
for (i = 0; i < clients; ++i) {
1221
param.user_data = &state_cli[i];
1223
state_cli[i].pool = pool;
1224
state_cli[i].check_echo = PJ_TRUE;
1225
state_cli[i].send_str_len = (pj_rand() % 5 + 1) * 1024 + pj_rand() % 1024;
1226
state_cli[i].send_str = (char*)pj_pool_alloc(pool, state_cli[i].send_str_len);
1229
for (j = 0; j < state_cli[i].send_str_len; ++j)
1230
state_cli[i].send_str[j] = (char)(pj_rand() % 256);
1233
status = pj_ssl_sock_create(pool, ¶m, &ssock_cli[i]);
1234
if (status != PJ_SUCCESS) {
1235
app_perror("...ERROR pj_ssl_sock_create()", status);
1241
status = pj_ssl_sock_start_connect(ssock_cli[i], pool, &addr, &listen_addr, pj_sockaddr_get_len(&addr));
1242
if (status == PJ_SUCCESS) {
1243
ssl_on_connect_complete(ssock_cli[i], PJ_SUCCESS);
1244
} else if (status == PJ_EPENDING) {
1245
status = PJ_SUCCESS;
1247
app_perror("...ERROR pj_ssl_sock_create()", status);
1248
pj_ssl_sock_close(ssock_cli[i]);
1249
ssock_cli[i] = NULL;
1255
/* Give chance to server to accept this client */
1260
while(n && pj_symbianos_poll(-1, 1000))
1263
pj_time_val delay = {0, 100};
1264
while(n && pj_ioqueue_poll(ioqueue, &delay) > 0)
1270
/* Wait until everything has been sent/received or error */
1274
pj_symbianos_poll(-1, 1000);
1276
pj_time_val delay = {0, 100};
1277
pj_ioqueue_poll(ioqueue, &delay);
1278
pj_timer_heap_poll(timer, &delay);
1282
/* Clean up sockets */
1284
pj_time_val delay = {0, 500};
1285
while (pj_ioqueue_poll(ioqueue, &delay) > 0);
1288
if (state_serv.err != PJ_SUCCESS) {
1289
status = state_serv.err;
1293
PJ_LOG(3, ("", "...Done!"));
1295
/* SSL setup and data transfer duration */
1299
pj_gettimeofday(&stop);
1300
PJ_TIME_VAL_SUB(stop, start);
1302
PJ_LOG(3, ("", ".....Setup & data transfer duration: %d.%03ds", stop.sec, stop.msec));
1305
/* Check clients status */
1306
for (i = 0; i < clients; ++i) {
1307
if (state_cli[i].err != PJ_SUCCESS)
1310
tot_sent += state_cli[1].sent;
1311
tot_recv += state_cli[1].recv;
1314
PJ_LOG(3, ("", ".....Clients: %d (%d errors)", clients, cli_err));
1315
PJ_LOG(3, ("", ".....Total sent/recv: %d/%d bytes", tot_sent, tot_recv));
1319
pj_ssl_sock_close(ssock_serv);
1321
for (i = 0; i < clients; ++i) {
1322
if (ssock_cli[i] && !state_cli[i].err && !state_cli[i].done)
1323
pj_ssl_sock_close(ssock_cli[i]);
1326
pj_ioqueue_destroy(ioqueue);
1328
pj_pool_release(pool);
1333
#if 0 && (!defined(PJ_SYMBIAN) || PJ_SYMBIAN==0)
1334
pj_status_t pj_ssl_sock_ossl_test_send_buf(pj_pool_t *pool);
1335
static int ossl_test_send_buf()
1340
pool = pj_pool_create(mem, "send_buf", 256, 256, NULL);
1341
status = pj_ssl_sock_ossl_test_send_buf(pool);
1342
pj_pool_release(pool);
1346
static int ossl_test_send_buf()
1352
int ssl_sock_test(void)
1356
PJ_LOG(3,("", "..test ossl send buf"));
1357
ret = ossl_test_send_buf();
1361
PJ_LOG(3,("", "..get cipher list test"));
1362
ret = get_cipher_list();
1366
PJ_LOG(3,("", "..https client test"));
1367
ret = https_client_test(30000);
1368
// Ignore test result as internet connection may not be available.
1374
/* On Symbian platforms, SSL socket is implemented using CSecureSocket,
1375
* and it hasn't supported server mode, so exclude the following tests,
1376
* which require SSL server, for now.
1379
PJ_LOG(3,("", "..echo test w/ TLSv1 and PJ_TLS_RSA_WITH_DES_CBC_SHA cipher"));
1380
ret = echo_test(PJ_SSL_SOCK_PROTO_TLS1, PJ_SSL_SOCK_PROTO_TLS1,
1381
PJ_TLS_RSA_WITH_DES_CBC_SHA, PJ_TLS_RSA_WITH_DES_CBC_SHA,
1382
PJ_FALSE, PJ_FALSE);
1386
PJ_LOG(3,("", "..echo test w/ SSLv23 and PJ_TLS_RSA_WITH_AES_256_CBC_SHA cipher"));
1387
ret = echo_test(PJ_SSL_SOCK_PROTO_SSL23, PJ_SSL_SOCK_PROTO_SSL23,
1388
PJ_TLS_RSA_WITH_AES_256_CBC_SHA, PJ_TLS_RSA_WITH_AES_256_CBC_SHA,
1389
PJ_FALSE, PJ_FALSE);
1393
PJ_LOG(3,("", "..echo test w/ incompatible proto"));
1394
ret = echo_test(PJ_SSL_SOCK_PROTO_TLS1, PJ_SSL_SOCK_PROTO_SSL3,
1395
PJ_TLS_RSA_WITH_DES_CBC_SHA, PJ_TLS_RSA_WITH_DES_CBC_SHA,
1396
PJ_FALSE, PJ_FALSE);
1400
PJ_LOG(3,("", "..echo test w/ incompatible ciphers"));
1401
ret = echo_test(PJ_SSL_SOCK_PROTO_DEFAULT, PJ_SSL_SOCK_PROTO_DEFAULT,
1402
PJ_TLS_RSA_WITH_DES_CBC_SHA, PJ_TLS_RSA_WITH_AES_256_CBC_SHA,
1403
PJ_FALSE, PJ_FALSE);
1407
PJ_LOG(3,("", "..echo test w/ client cert required but not provided"));
1408
ret = echo_test(PJ_SSL_SOCK_PROTO_DEFAULT, PJ_SSL_SOCK_PROTO_DEFAULT,
1409
PJ_TLS_RSA_WITH_AES_256_CBC_SHA, PJ_TLS_RSA_WITH_AES_256_CBC_SHA,
1414
PJ_LOG(3,("", "..echo test w/ client cert required and provided"));
1415
ret = echo_test(PJ_SSL_SOCK_PROTO_DEFAULT, PJ_SSL_SOCK_PROTO_DEFAULT,
1416
PJ_TLS_RSA_WITH_AES_256_CBC_SHA, PJ_TLS_RSA_WITH_AES_256_CBC_SHA,
1421
PJ_LOG(3,("", "..performance test"));
1422
ret = perf_test(PJ_IOQUEUE_MAX_HANDLES/2 - 1, 0);
1426
PJ_LOG(3,("", "..client non-SSL (handshake timeout 5 secs)"));
1427
ret = client_non_ssl(5000);
1428
/* PJ_TIMEDOUT won't be returned as accepted socket is deleted silently */
1434
PJ_LOG(3,("", "..server non-SSL (handshake timeout 5 secs)"));
1435
ret = server_non_ssl(5000);
1436
if (ret != PJ_ETIMEDOUT)
1442
#else /* INCLUDE_SSLSOCK_TEST */
1443
/* To prevent warning about "translation unit is empty"
1444
* when this test is disabled.
1446
int dummy_ssl_sock_test;
1447
#endif /* INCLUDE_SSLSOCK_TEST */