blob: 01dd1cedb8da28caf03d716fd04ddd21a47c6a87 [file] [log] [blame]
Nanang Izzuddin006cc012009-10-16 03:06:13 +00001/* $Id$ */
2/*
3 * Copyright (C) 2009 Teluu Inc. (http://www.teluu.com)
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19#include <pj/ssl_sock.h>
20#include <pj/activesock.h>
21#include <pj/compat/socket.h>
22#include <pj/assert.h>
23#include <pj/errno.h>
24#include <pj/list.h>
25#include <pj/lock.h>
26#include <pj/log.h>
27#include <pj/math.h>
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +000028#include <pj/os.h>
Nanang Izzuddin006cc012009-10-16 03:06:13 +000029#include <pj/pool.h>
30#include <pj/string.h>
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +000031#include <pj/timer.h>
Nanang Izzuddin006cc012009-10-16 03:06:13 +000032
33
34/* Only build when PJ_HAS_SSL_SOCK is enabled */
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +000035#if defined(PJ_HAS_SSL_SOCK) && PJ_HAS_SSL_SOCK!=0
Nanang Izzuddin006cc012009-10-16 03:06:13 +000036
37#define THIS_FILE "ssl_sock_ossl.c"
38
39/*
40 * Include OpenSSL headers
41 */
42#include <openssl/bio.h>
43#include <openssl/ssl.h>
44#include <openssl/err.h>
45
46
47#ifdef _MSC_VER
48# ifdef _DEBUG
49# pragma comment( lib, "libeay32MTd")
50# pragma comment( lib, "ssleay32MTd")
51#else
52# pragma comment( lib, "libeay32MT")
53# pragma comment( lib, "ssleay32MT")
54# endif
55#endif
56
57
58/*
59 * SSL/TLS state enumeration.
60 */
61enum ssl_state {
62 SSL_STATE_NULL,
63 SSL_STATE_HANDSHAKING,
64 SSL_STATE_ESTABLISHED
65};
66
67/*
68 * Structure of SSL socket read buffer.
69 */
70typedef struct read_data_t
71{
72 void *data;
73 pj_size_t len;
74} read_data_t;
75
76/*
77 * Get the offset of pointer to read-buffer of SSL socket from read-buffer
78 * of active socket. Note that both SSL socket and active socket employ
79 * different but correlated read-buffers (as much as async_cnt for each),
80 * and to make it easier/faster to find corresponding SSL socket's read-buffer
81 * from known active socket's read-buffer, the pointer of corresponding
82 * SSL socket's read-buffer is stored right after the end of active socket's
83 * read-buffer.
84 */
85#define OFFSET_OF_READ_DATA_PTR(ssock, asock_rbuf) \
86 (read_data_t**) \
87 ((pj_int8_t*)(asock_rbuf) + \
88 ssock->param.read_buffer_size)
89
90/*
91 * Structure of SSL socket write buffer.
92 */
93typedef struct write_data_t {
94 pj_ioqueue_op_key_t key;
95 pj_size_t record_len;
96 pj_ioqueue_op_key_t *app_key;
97 pj_size_t plain_data_len;
98 pj_size_t data_len;
99 union {
100 char content[1];
101 const char *ptr;
102 } data;
103 unsigned flags;
104} write_data_t;
105
106/*
107 * Structure of SSL socket write state.
108 */
109typedef struct write_state_t {
110 char *buf;
111 pj_size_t max_len;
112 char *start;
113 pj_size_t len;
114 write_data_t *last_data;
115} write_state_t;
116
117/*
118 * Structure of write data pending.
119 */
120typedef struct write_pending_t {
121 PJ_DECL_LIST_MEMBER(struct write_pending_t);
122 write_data_t data;
123} write_pending_t;
124
125/*
126 * Secure socket structure definition.
127 */
128struct pj_ssl_sock_t
129{
130 pj_pool_t *pool;
131 pj_ssl_sock_t *parent;
132 pj_ssl_sock_param param;
133 pj_ssl_cert_t *cert;
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +0000134
135 pj_ssl_cert_info local_cert_info;
136 pj_ssl_cert_info remote_cert_info;
Nanang Izzuddin006cc012009-10-16 03:06:13 +0000137
138 pj_bool_t is_server;
139 enum ssl_state ssl_state;
140 pj_ioqueue_op_key_t handshake_op_key;
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +0000141 pj_timer_entry handshake_timer;
Nanang Izzuddin006cc012009-10-16 03:06:13 +0000142
143 pj_sock_t sock;
144 pj_activesock_t *asock;
145
146 pj_sockaddr local_addr;
147 pj_sockaddr rem_addr;
148 int addr_len;
149
150 pj_bool_t read_started;
151 pj_size_t read_size;
152 pj_uint32_t read_flags;
153 void **asock_rbuf;
154 read_data_t *ssock_rbuf;
155
156 write_state_t write_state;
157 write_pending_t write_pending;
158 write_pending_t write_pending_empty;
159 pj_lock_t *write_mutex; /* protect write BIO and write_state */
160
161 SSL_CTX *ossl_ctx;
162 SSL *ossl_ssl;
163 BIO *ossl_rbio;
164 BIO *ossl_wbio;
165};
166
167
168/*
169 * Certificate/credential structure definition.
170 */
171struct pj_ssl_cert_t
172{
173 pj_str_t CA_file;
174 pj_str_t cert_file;
175 pj_str_t privkey_file;
176 pj_str_t privkey_pass;
177};
178
179
180static pj_status_t flush_delayed_send(pj_ssl_sock_t *ssock);
181
182/*
183 *******************************************************************
184 * Static/internal functions.
185 *******************************************************************
186 */
187
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +0000188/**
189 * Mapping from OpenSSL error codes to pjlib error space.
190 */
191
192#define PJ_SSL_ERRNO_START (PJ_ERRNO_START_USER + \
193 PJ_ERRNO_SPACE_SIZE*6)
194
195#define PJ_SSL_ERRNO_SPACE_SIZE 5000
196
197#define PJ_STATUS_FROM_OSSL(ossl_err) (ossl_err == SSL_ERROR_NONE? \
198 PJ_SUCCESS : \
199 (PJ_SSL_ERRNO_START + ossl_err))
200
201#define PJ_STATUS_TO_OSSL(status) (status == PJ_SUCCESS? \
202 SSL_ERROR_NONE : \
203 (status - PJ_SSL_ERRNO_START))
204
205
206/*
207 * Get error string of OpenSSL.
208 */
209static pj_str_t ssl_strerror(pj_status_t status,
210 char *buf, pj_size_t bufsize)
Nanang Izzuddin006cc012009-10-16 03:06:13 +0000211{
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +0000212 pj_str_t errstr;
213 unsigned long ssl_err = PJ_STATUS_TO_OSSL(status);
Nanang Izzuddin006cc012009-10-16 03:06:13 +0000214
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +0000215#if defined(PJ_HAS_ERROR_STRING) && (PJ_HAS_ERROR_STRING != 0)
Nanang Izzuddin006cc012009-10-16 03:06:13 +0000216
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +0000217 ERR_error_string_n(ssl_err, buf, bufsize);
218 errstr = pj_str(buf);
Nanang Izzuddin006cc012009-10-16 03:06:13 +0000219
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +0000220#else
Nanang Izzuddin006cc012009-10-16 03:06:13 +0000221
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +0000222 errstr.ptr = buf;
223 errstr.slen = pj_ansi_snprintf(buf, bufsize,
224 "Unknown OpenSSL error %d",
225 ssl_err);
Nanang Izzuddin006cc012009-10-16 03:06:13 +0000226
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +0000227#endif /* PJ_HAS_ERROR_STRING */
Nanang Izzuddin006cc012009-10-16 03:06:13 +0000228
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +0000229 return errstr;
Nanang Izzuddin006cc012009-10-16 03:06:13 +0000230}
231
232
Nanang Izzuddin006cc012009-10-16 03:06:13 +0000233/* OpenSSL library initialization counter */
234static int openssl_init_count;
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +0000235static int openssl_reg_strerr;
Nanang Izzuddin006cc012009-10-16 03:06:13 +0000236
237/* OpenSSL available ciphers */
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +0000238static pj_ssl_cipher openssl_ciphers[100];
Nanang Izzuddin006cc012009-10-16 03:06:13 +0000239static unsigned openssl_cipher_num;
240
241
242/* Initialize OpenSSL */
243static pj_status_t init_openssl(void)
244{
245 if (++openssl_init_count != 1)
246 return PJ_SUCCESS;
247
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +0000248 /* Register error subsystem */
249 if (!openssl_reg_strerr) {
250 pj_status_t status;
251
252 openssl_reg_strerr = 1;
253 status = pj_register_strerror(PJ_SSL_ERRNO_START,
254 PJ_SSL_ERRNO_SPACE_SIZE,
255 &ssl_strerror);
256 pj_assert(status == PJ_SUCCESS);
257 }
258
259 /* Init OpenSSL lib */
Nanang Izzuddin006cc012009-10-16 03:06:13 +0000260 SSL_library_init();
261 SSL_load_error_strings();
262 OpenSSL_add_all_algorithms();
263
264 /* Init available ciphers */
265 if (openssl_cipher_num == 0) {
266 SSL_METHOD *meth = NULL;
267 SSL_CTX *ctx;
268 SSL *ssl;
269 STACK_OF(SSL_CIPHER) *sk_cipher;
270 unsigned i, n;
271
272 meth = (SSL_METHOD*)SSLv23_server_method();
273 if (!meth)
274 meth = (SSL_METHOD*)TLSv1_server_method();
275 if (!meth)
276 meth = (SSL_METHOD*)SSLv3_server_method();
277 if (!meth)
278 meth = (SSL_METHOD*)SSLv2_server_method();
279 pj_assert(meth);
280
281 ctx=SSL_CTX_new(meth);
282 SSL_CTX_set_cipher_list(ctx, "ALL");
283
284 ssl = SSL_new(ctx);
285 sk_cipher = SSL_get_ciphers(ssl);
286
287 n = sk_SSL_CIPHER_num(sk_cipher);
288 if (n > PJ_ARRAY_SIZE(openssl_ciphers))
289 n = PJ_ARRAY_SIZE(openssl_ciphers);
290
291 for (i = 0; i < n; ++i) {
292 SSL_CIPHER *c;
293 c = sk_SSL_CIPHER_value(sk_cipher,i);
294 openssl_ciphers[i] = (pj_ssl_cipher)
295 (pj_uint32_t)c->id & 0x00FFFFFF;
296 //printf("%3u: %08x=%s\n", i+1, c->id, SSL_CIPHER_get_name(c));
297 }
298
299 SSL_free(ssl);
300 SSL_CTX_free(ctx);
301
302 openssl_cipher_num = n;
303 }
304
305 return PJ_SUCCESS;
306}
307
308
309/* Shutdown OpenSSL */
310static void shutdown_openssl(void)
311{
312 if (--openssl_init_count != 0)
313 return;
314}
315
316
317/* SSL password callback. */
318static int password_cb(char *buf, int num, int rwflag, void *user_data)
319{
320 pj_ssl_cert_t *cert = (pj_ssl_cert_t*) user_data;
321
322 PJ_UNUSED_ARG(rwflag);
323
324 if(num < cert->privkey_pass.slen)
325 return 0;
326
327 pj_memcpy(buf, cert->privkey_pass.ptr, cert->privkey_pass.slen);
328 return cert->privkey_pass.slen;
329}
330
331
332/* Create and initialize new SSL context */
333static pj_status_t create_ssl_ctx(pj_ssl_sock_t *ssock, SSL_CTX **p_ctx)
334{
335 SSL_METHOD *ssl_method;
336 SSL_CTX *ctx;
337 pj_ssl_cert_t *cert;
338 int mode, rc;
339
340 pj_assert(ssock && p_ctx);
341
342 cert = ssock->cert;
343
344 /* Make sure OpenSSL library has been initialized */
345 init_openssl();
346
347 /* Determine SSL method to use */
348 switch (ssock->param.proto) {
349 case PJ_SSL_SOCK_PROTO_DEFAULT:
350 case PJ_SSL_SOCK_PROTO_TLS1:
351 ssl_method = (SSL_METHOD*)TLSv1_method();
352 break;
353 case PJ_SSL_SOCK_PROTO_SSL2:
354 ssl_method = (SSL_METHOD*)SSLv2_method();
355 break;
356 case PJ_SSL_SOCK_PROTO_SSL3:
357 ssl_method = (SSL_METHOD*)SSLv3_method();
358 break;
359 case PJ_SSL_SOCK_PROTO_SSL23:
360 ssl_method = (SSL_METHOD*)SSLv23_method();
361 break;
362 case PJ_SSL_SOCK_PROTO_DTLS1:
363 ssl_method = (SSL_METHOD*)DTLSv1_method();
364 break;
365 default:
Nanang Izzuddin006cc012009-10-16 03:06:13 +0000366 return PJ_EINVAL;
367 }
368
369 /* Create SSL context for the listener */
370 ctx = SSL_CTX_new(ssl_method);
371 if (ctx == NULL) {
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +0000372 PJ_LOG(1,(ssock->pool->obj_name, "Error creating OpenSSL context"));
373 return PJ_STATUS_FROM_OSSL(ERR_get_error());
Nanang Izzuddin006cc012009-10-16 03:06:13 +0000374 }
375
376 /* Apply credentials */
377 if (cert) {
378 /* Load CA list if one is specified. */
379 if (cert->CA_file.slen) {
380
381 rc = SSL_CTX_load_verify_locations(ctx, cert->CA_file.ptr, NULL);
382
383 if (rc != 1) {
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +0000384 PJ_LOG(1,(ssock->pool->obj_name, "Error loading CA list file "
385 "'%s'", cert->CA_file.ptr));
Nanang Izzuddin006cc012009-10-16 03:06:13 +0000386 SSL_CTX_free(ctx);
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +0000387 return PJ_STATUS_FROM_OSSL(ERR_get_error());
Nanang Izzuddin006cc012009-10-16 03:06:13 +0000388 }
Nanang Izzuddin006cc012009-10-16 03:06:13 +0000389 }
390
391 /* Set password callback */
392 if (cert->privkey_pass.slen) {
393 SSL_CTX_set_default_passwd_cb(ctx, password_cb);
394 SSL_CTX_set_default_passwd_cb_userdata(ctx, cert);
395 }
396
397
398 /* Load certificate if one is specified */
399 if (cert->cert_file.slen) {
400
401 /* Load certificate chain from file into ctx */
402 rc = SSL_CTX_use_certificate_chain_file(ctx, cert->cert_file.ptr);
403
404 if(rc != 1) {
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +0000405 PJ_LOG(1,(ssock->pool->obj_name, "Error loading certificate "
406 "chain file '%s'", cert->cert_file.ptr));
Nanang Izzuddin006cc012009-10-16 03:06:13 +0000407 SSL_CTX_free(ctx);
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +0000408 return PJ_STATUS_FROM_OSSL(ERR_get_error());
Nanang Izzuddin006cc012009-10-16 03:06:13 +0000409 }
Nanang Izzuddin006cc012009-10-16 03:06:13 +0000410 }
411
412
413 /* Load private key if one is specified */
414 if (cert->privkey_file.slen) {
415 /* Adds the first private key found in file to ctx */
416 rc = SSL_CTX_use_PrivateKey_file(ctx, cert->privkey_file.ptr,
417 SSL_FILETYPE_PEM);
418
419 if(rc != 1) {
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +0000420 PJ_LOG(1,(ssock->pool->obj_name, "Error adding private key "
421 "from '%s'", cert->privkey_file.ptr));
Nanang Izzuddin006cc012009-10-16 03:06:13 +0000422 SSL_CTX_free(ctx);
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +0000423 return PJ_STATUS_FROM_OSSL(ERR_get_error());
Nanang Izzuddin006cc012009-10-16 03:06:13 +0000424 }
Nanang Izzuddin006cc012009-10-16 03:06:13 +0000425 }
426 }
427
428
429 /* SSL verification options */
430 if (ssock->param.verify_peer) {
431 mode = SSL_VERIFY_PEER;
432 } else {
433 mode = SSL_VERIFY_NONE;
434 }
435
436 if (ssock->is_server && ssock->param.require_client_cert)
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +0000437 mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT | SSL_VERIFY_PEER;
Nanang Izzuddin006cc012009-10-16 03:06:13 +0000438
439 SSL_CTX_set_verify(ctx, mode, NULL);
440
Nanang Izzuddin006cc012009-10-16 03:06:13 +0000441 *p_ctx = ctx;
442
443 return PJ_SUCCESS;
444}
445
446
447/* Destroy SSL context */
448static void destroy_ssl_ctx(SSL_CTX *ctx)
449{
450 SSL_CTX_free(ctx);
451
452 /* Potentially shutdown OpenSSL library if this is the last
453 * context exists.
454 */
455 shutdown_openssl();
456}
457
458
459/* Reset SSL socket state */
460static void reset_ssl_sock_state(pj_ssl_sock_t *ssock)
461{
462 ssock->ssl_state = SSL_STATE_NULL;
463
464 if (ssock->ossl_ssl) {
465 SSL_shutdown(ssock->ossl_ssl);
466 SSL_free(ssock->ossl_ssl); /* this will also close BIOs */
467 ssock->ossl_ssl = NULL;
468 }
469 if (ssock->ossl_ctx) {
470 destroy_ssl_ctx(ssock->ossl_ctx);
471 ssock->ossl_ctx = NULL;
472 }
473 if (ssock->asock) {
474 pj_activesock_close(ssock->asock);
475 ssock->asock = NULL;
476 ssock->sock = PJ_INVALID_SOCKET;
477 }
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +0000478 if (ssock->sock != PJ_INVALID_SOCKET) {
479 pj_sock_close(ssock->sock);
480 ssock->sock = PJ_INVALID_SOCKET;
481 }
Nanang Izzuddin6cfc6d52009-10-27 02:21:28 +0000482
483 /* Upon error, OpenSSL may leave any error description in the thread
484 * error queue, which sometime may cause next call to SSL API returning
485 * false error alarm, e.g: in Linux, SSL_CTX_use_certificate_chain_file()
486 * returning false error after a handshake error (in different SSL_CTX!).
487 * For now, just clear thread error queue here.
488 */
489 ERR_clear_error();
Nanang Izzuddin006cc012009-10-16 03:06:13 +0000490}
491
492
493/* Generate cipher list with user preference order in OpenSSL format */
494static pj_status_t set_cipher_list(pj_ssl_sock_t *ssock)
495{
496 char buf[1024];
497 pj_str_t cipher_list;
498 STACK_OF(SSL_CIPHER) *sk_cipher;
499 unsigned i;
500 int j, ret;
501
502 if (ssock->param.ciphers_num == 0)
503 return PJ_SUCCESS;
504
505 pj_strset(&cipher_list, buf, 0);
506
507 /* Set SSL with ALL available ciphers */
508 SSL_set_cipher_list(ssock->ossl_ssl, "ALL");
509
510 /* Generate user specified cipher list in OpenSSL format */
511 sk_cipher = SSL_get_ciphers(ssock->ossl_ssl);
512 for (i = 0; i < ssock->param.ciphers_num; ++i) {
513 for (j = 0; j < sk_SSL_CIPHER_num(sk_cipher); ++j) {
514 SSL_CIPHER *c;
515 c = sk_SSL_CIPHER_value(sk_cipher, j);
516 if (ssock->param.ciphers[i] == (pj_ssl_cipher)
517 ((pj_uint32_t)c->id & 0x00FFFFFF))
518 {
519 const char *c_name;
520
521 c_name = SSL_CIPHER_get_name(c);
522
523 /* Check buffer size */
524 if (cipher_list.slen + pj_ansi_strlen(c_name) + 2 > sizeof(buf)) {
525 pj_assert(!"Insufficient temporary buffer for cipher");
526 return PJ_ETOOMANY;
527 }
528
529 /* Add colon separator */
530 if (cipher_list.slen)
531 pj_strcat2(&cipher_list, ":");
532
533 /* Add the cipher */
534 pj_strcat2(&cipher_list, c_name);
535 break;
536 }
537 }
538 }
539
540 /* Put NULL termination in the generated cipher list */
541 cipher_list.ptr[cipher_list.slen] = '\0';
542
543 /* Finally, set chosen cipher list */
544 ret = SSL_set_cipher_list(ssock->ossl_ssl, buf);
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +0000545 if (ret < 1)
546 return PJ_STATUS_FROM_OSSL(SSL_get_error(ssock->ossl_ssl, ret));
Nanang Izzuddin006cc012009-10-16 03:06:13 +0000547
548 return PJ_SUCCESS;
549}
550
551
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +0000552/* Parse OpenSSL ASN1_TIME to pj_time_val and GMT info */
553static pj_bool_t parse_ossl_asn1_time(pj_time_val *tv, pj_bool_t *gmt,
554 const ASN1_TIME *tm)
555{
556 unsigned long parts[7] = {0};
557 char *p, *end;
558 unsigned len;
559 pj_bool_t utc;
560 pj_parsed_time pt;
561 int i;
562
563 utc = tm->type == V_ASN1_UTCTIME;
564 p = (char*)tm->data;
565 len = tm->length;
566 end = p + len - 1;
567
568 /* GMT */
569 *gmt = (*end == 'Z');
570
571 /* parse parts */
572 for (i = 0; i < 7 && p < end; ++i) {
573 pj_str_t st;
574
575 if (i==0 && !utc) {
576 /* 4 digits year part for non-UTC time format */
577 st.slen = 4;
578 } else if (i==6) {
579 /* fraction of seconds */
580 if (*p == '.') ++p;
581 st.slen = end - p + 1;
582 } else {
583 /* other parts always 2 digits length */
584 st.slen = 2;
585 }
586 st.ptr = p;
587
588 parts[i] = pj_strtoul(&st);
589 p += st.slen;
590 }
591
592 /* encode parts to pj_time_val */
593 pt.year = parts[0];
594 if (utc)
595 pt.year += (pt.year < 50)? 2000:1900;
596 pt.mon = parts[1] - 1;
597 pt.day = parts[2];
598 pt.hour = parts[3];
599 pt.min = parts[4];
600 pt.sec = parts[5];
601 pt.msec = parts[6];
602
603 pj_time_encode(&pt, tv);
604
605 return PJ_TRUE;
606}
607
608
609/* Get certificate info from OpenSSL X509 */
610static void get_cert_info(pj_pool_t *pool, pj_ssl_cert_info *ci, X509 *x)
611{
612 pj_ssl_cert_info info;
613 char buf1[256];
614 char buf2[256];
615
616 pj_assert(pool && ci);
617
618 if (!x) {
619 pj_bzero(ci, sizeof(pj_ssl_cert_info));
620 return;
621 }
622
623 pj_bzero(&info, sizeof(info));
624
625 /* Populate cert info */
626 info.subject = pj_str(X509_NAME_oneline(X509_get_subject_name(x),buf1,
627 sizeof(buf1)));
628 info.issuer = pj_str(X509_NAME_oneline(X509_get_issuer_name(x), buf2,
629 sizeof(buf2)));
630 info.version = X509_get_version(x) + 1;
631 parse_ossl_asn1_time(&info.validity_start, &info.validity_use_gmt,
632 X509_get_notBefore(x));
633 parse_ossl_asn1_time(&info.validity_end, &info.validity_use_gmt,
634 X509_get_notAfter(x));
635
636 /* Update certificate info */
637 if (pj_strcmp(&ci->subject, &info.subject))
638 pj_strdup(pool, &ci->subject, &info.subject);
639 if (pj_strcmp(&ci->issuer, &info.issuer))
640 pj_strdup(pool, &ci->issuer, &info.issuer);
641 ci->version = info.version;
642 ci->validity_start = info.validity_start;
643 ci->validity_end = info.validity_end;
644 ci->validity_use_gmt = info.validity_use_gmt;
645}
646
647
648/* Update local & remote certificates info. This function should be
649 * called after handshake or renegotiation successfully completed.
650 */
651static void update_certs_info(pj_ssl_sock_t *ssock)
652{
653 X509 *x;
654
655 pj_assert(ssock->ssl_state == SSL_STATE_ESTABLISHED);
656
657 /* Active local certificate */
658 x = SSL_get_certificate(ssock->ossl_ssl);
659 get_cert_info(ssock->pool, &ssock->local_cert_info, x);
660 /* Don't free local's X509! */
661
662 /* Active remote certificate */
663 x = SSL_get_peer_certificate(ssock->ossl_ssl);
664 get_cert_info(ssock->pool, &ssock->remote_cert_info, x);
665 /* Free peer's X509 */
666 X509_free(x);
667}
668
669
Nanang Izzuddin006cc012009-10-16 03:06:13 +0000670/* When handshake completed:
671 * - notify application
672 * - if handshake failed, reset SSL state
673 * - return PJ_FALSE when SSL socket instance is destroyed by application.
674 */
675static pj_bool_t on_handshake_complete(pj_ssl_sock_t *ssock,
676 pj_status_t status)
677{
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +0000678 /* Cancel handshake timer */
679 if (ssock->param.timer_heap)
680 pj_timer_heap_cancel(ssock->param.timer_heap, &ssock->handshake_timer);
681
682 /* Update certificates info on successful handshake */
683 if (status == PJ_SUCCESS)
684 update_certs_info(ssock);
685
Nanang Izzuddin006cc012009-10-16 03:06:13 +0000686 /* Accepting */
687 if (ssock->is_server) {
688 if (status != PJ_SUCCESS) {
689 /* Handshake failed in accepting, destroy our self silently. */
690 pj_ssl_sock_close(ssock);
691 return PJ_FALSE;
692 }
693 /* Notify application the newly accepted SSL socket */
694 if (ssock->param.cb.on_accept_complete) {
695 pj_bool_t ret;
696 ret = (*ssock->param.cb.on_accept_complete)
697 (ssock->parent, ssock, (pj_sockaddr_t*)&ssock->rem_addr,
698 pj_sockaddr_get_len((pj_sockaddr_t*)&ssock->rem_addr));
699 if (ret == PJ_FALSE)
700 return PJ_FALSE;
701 }
702 }
703
704 /* Connecting */
705 else {
706 if (ssock->param.cb.on_connect_complete) {
707 pj_bool_t ret;
708 ret = (*ssock->param.cb.on_connect_complete)(ssock, status);
709 if (ret == PJ_FALSE)
710 return PJ_FALSE;
711 }
712 if (status != PJ_SUCCESS) {
713 /* Reset SSL socket state */
714 reset_ssl_sock_state(ssock);
715 }
716 }
717
718 return PJ_TRUE;
719}
720
721/* Flush write BIO to network socket. Note that any access to write BIO
722 * MUST be serialized, so mutex protection must cover any call to OpenSSL
723 * API (that possibly generate data for write BIO) along with the call to
724 * this function (flushing all data in write BIO generated by above
725 * OpenSSL API call).
726 */
727static pj_status_t flush_write_bio(pj_ssl_sock_t *ssock,
728 pj_ioqueue_op_key_t *send_key,
729 pj_size_t orig_len,
730 unsigned flags)
731{
732 char *data;
733 pj_ssize_t len;
734
735 write_state_t *write_st = &ssock->write_state;
736 write_data_t *wdata;
737 pj_size_t avail_len, needed_len, skipped_len = 0;
738 pj_status_t status;
739
740 /* Check if there is data in write BIO, flush it if any */
741 if (!BIO_pending(ssock->ossl_wbio))
742 return PJ_SUCCESS;
743
744 /* Get data and its length */
745 len = BIO_get_mem_data(ssock->ossl_wbio, &data);
746 if (len == 0)
747 return PJ_SUCCESS;
748
749 /* Calculate buffer size needed, and align it to 8 */
750 needed_len = len + sizeof(write_data_t);
751 needed_len = ((needed_len + 7) >> 3) << 3;
752
753 /* Check buffer availability */
754 avail_len = write_st->max_len - write_st->len;
755 if (avail_len < needed_len)
756 return PJ_ENOMEM;
757
758 /* More buffer availability check, note that the write data must be in
759 * a contigue buffer.
760 */
761 if (write_st->len == 0) {
762
763 write_st->start = write_st->buf;
764 wdata = (write_data_t*)write_st->start;
765
766 } else {
767
768 char *reg1, *reg2;
769 pj_size_t reg1_len, reg2_len;
770
771 /* Unused slots may be wrapped/splitted into two regions, so let's
772 * analyze them if any region can hold the write data.
773 */
774 reg1 = write_st->start + write_st->len;
775 if (reg1 >= write_st->buf + write_st->max_len)
776 reg1 -= write_st->max_len;
777 reg1_len = write_st->max_len - write_st->len;
778 if (reg1 + reg1_len > write_st->buf + write_st->max_len) {
779 reg1_len = write_st->buf + write_st->max_len - reg1;
780 reg2 = write_st->buf;
781 reg2_len = write_st->start - write_st->buf;
782 } else {
783 reg2 = NULL;
784 reg2_len = 0;
785 }
786 avail_len = PJ_MAX(reg1_len, reg2_len);
787 if (avail_len < needed_len)
788 return PJ_ENOMEM;
789
790 /* Get write data pointer and update buffer length */
791 if (reg1_len >= needed_len) {
792 wdata = (write_data_t*)reg1;
793 } else {
794 wdata = (write_data_t*)reg2;
795 /* Unused slot in region 1 is skipped as current write data
796 * doesn't fit it.
797 */
798 skipped_len = reg1_len;
799 }
800 }
801
802 /* Copy the data and set its properties into the buffer */
803 pj_bzero(wdata, sizeof(write_data_t));
804 wdata->app_key = send_key;
805 wdata->record_len = needed_len;
806 wdata->data_len = len;
807 wdata->plain_data_len = orig_len;
808 wdata->flags = flags;
809 pj_memcpy(&wdata->data, data, len);
810
811 /* Send it */
812 if (ssock->param.sock_type == pj_SOCK_STREAM()) {
813 status = pj_activesock_send(ssock->asock, &wdata->key,
814 wdata->data.content, &len,
815 flags);
816 } else {
817 status = pj_activesock_sendto(ssock->asock, &wdata->key,
818 wdata->data.content, &len,
819 flags,
820 (pj_sockaddr_t*)&ssock->rem_addr,
821 ssock->addr_len);
822 }
823
824 /* Oh no, EWOULDBLOCK! */
825 if (status == PJ_STATUS_FROM_OS(OSERR_EWOULDBLOCK)) {
826 /* Just return PJ_SUCCESS here, the pending data will be sent in next
827 * call of this function since the data is still stored in write BIO.
828 */
829 return PJ_SUCCESS;
830 }
831
832 /* Reset write BIO after flushed */
833 BIO_reset(ssock->ossl_wbio);
834
835 if (status == PJ_EPENDING) {
836 /* Update write state */
837 pj_assert(skipped_len==0 || write_st->last_data);
838 write_st->len += needed_len + skipped_len;
839 if (write_st->last_data)
840 write_st->last_data->record_len += skipped_len;
841 write_st->last_data = wdata;
842 }
843
844 return status;
845}
846
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +0000847
848static void handshake_timeout_cb(pj_timer_heap_t *th,
849 struct pj_timer_entry *te)
850{
851 pj_ssl_sock_t *ssock = (pj_ssl_sock_t*)te->user_data;
852
853 PJ_UNUSED_ARG(th);
854
855 PJ_LOG(1,(ssock->pool->obj_name, "SSL handshake timeout after %d.%ds",
856 ssock->param.timeout.sec, ssock->param.timeout.msec));
857
858 on_handshake_complete(ssock, PJ_ETIMEDOUT);
859}
860
861
862/* Asynchronouse handshake */
Nanang Izzuddin006cc012009-10-16 03:06:13 +0000863static pj_status_t do_handshake(pj_ssl_sock_t *ssock)
864{
865 pj_status_t status;
866 int err;
867
868 pj_lock_acquire(ssock->write_mutex);
869
870 /* Perform SSL handshake */
871 err = SSL_do_handshake(ssock->ossl_ssl);
872 if (err < 0) {
873 err = SSL_get_error(ssock->ossl_ssl, err);
874 if (err != SSL_ERROR_NONE && err != SSL_ERROR_WANT_READ)
875 {
876 /* Handshake fails */
Nanang Izzuddin006cc012009-10-16 03:06:13 +0000877 pj_lock_release(ssock->write_mutex);
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +0000878 return PJ_STATUS_FROM_OSSL(err);
Nanang Izzuddin006cc012009-10-16 03:06:13 +0000879 }
880 }
881
882 /* SSL_do_handshake() may put some pending data into SSL write BIO,
883 * flush it if any.
884 */
885 status = flush_write_bio(ssock, &ssock->handshake_op_key, 0, 0);
886 if (status != PJ_SUCCESS && status != PJ_EPENDING) {
887 pj_lock_release(ssock->write_mutex);
888 return status;
889 }
890
891 pj_lock_release(ssock->write_mutex);
892
893 /* Check if handshake has been completed */
894 if (SSL_is_init_finished(ssock->ossl_ssl)) {
895 ssock->ssl_state = SSL_STATE_ESTABLISHED;
896 return PJ_SUCCESS;
897 }
898
899 return PJ_EPENDING;
900}
901
902
903/*
904 *******************************************************************
905 * Active socket callbacks.
906 *******************************************************************
907 */
908
909static pj_bool_t asock_on_data_read (pj_activesock_t *asock,
910 void *data,
911 pj_size_t size,
912 pj_status_t status,
913 pj_size_t *remainder)
914{
915 pj_ssl_sock_t *ssock = (pj_ssl_sock_t*)
916 pj_activesock_get_user_data(asock);
917 pj_size_t nwritten;
918
919 /* Socket error or closed */
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +0000920 if (data && size > 0) {
921 /* Consume the whole data */
922 nwritten = BIO_write(ssock->ossl_rbio, data, size);
923 if (nwritten < size) {
924 status = PJ_STATUS_FROM_OSSL(ERR_get_error());
925 goto on_error;
926 }
Nanang Izzuddin006cc012009-10-16 03:06:13 +0000927 }
928
929 /* Check if SSL handshake hasn't finished yet */
930 if (ssock->ssl_state == SSL_STATE_HANDSHAKING) {
931 pj_bool_t ret = PJ_TRUE;
932
933 if (status == PJ_SUCCESS)
934 status = do_handshake(ssock);
935
936 /* Not pending is either success or failed */
937 if (status != PJ_EPENDING)
938 ret = on_handshake_complete(ssock, status);
939
940 return ret;
941 }
942
943 /* See if there is any decrypted data for the application */
944 if (ssock->read_started) {
945 do {
946 read_data_t *buf = *(OFFSET_OF_READ_DATA_PTR(ssock, data));
947 void *data_ = (pj_int8_t*)buf->data + buf->len;
948 int size_ = ssock->read_size - buf->len;
949
950 /* SSL_read() may write some data to BIO write when re-negotiation
951 * is on progress, so let's protect it with write mutex.
952 */
953 pj_lock_acquire(ssock->write_mutex);
Nanang Izzuddin006cc012009-10-16 03:06:13 +0000954 size_ = SSL_read(ssock->ossl_ssl, data_, size_);
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +0000955 pj_lock_release(ssock->write_mutex);
956
957 if (size_ > 0 || status != PJ_SUCCESS) {
Nanang Izzuddin006cc012009-10-16 03:06:13 +0000958 if (ssock->param.cb.on_data_read) {
959 pj_bool_t ret;
960 pj_size_t remainder_ = 0;
961
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +0000962 if (size_ > 0)
963 buf->len += size_;
Nanang Izzuddin006cc012009-10-16 03:06:13 +0000964
965 ret = (*ssock->param.cb.on_data_read)(ssock, buf->data,
966 buf->len, status,
967 &remainder_);
968 if (!ret) {
969 /* We've been destroyed */
970 return PJ_FALSE;
971 }
972
973 /* Application may have left some data to be consumed
974 * later.
975 */
976 buf->len = remainder_;
977 }
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +0000978
979 /* Active socket signalled connection closed/error, this has
980 * been signalled to the application along with any remaining
981 * buffer. So, let's just reset SSL socket now.
982 */
983 if (status != PJ_SUCCESS) {
984 reset_ssl_sock_state(ssock);
985 return PJ_FALSE;
986 }
987
Nanang Izzuddin006cc012009-10-16 03:06:13 +0000988 } else {
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +0000989
Nanang Izzuddin006cc012009-10-16 03:06:13 +0000990 int err = SSL_get_error(ssock->ossl_ssl, size);
991
992 /* SSL might just return SSL_ERROR_WANT_READ in
993 * re-negotiation.
994 */
995 if (err != SSL_ERROR_NONE && err != SSL_ERROR_WANT_READ)
996 {
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +0000997 char errmsg[PJ_ERR_MSG_SIZE];
998
999 pj_strerror(status, errmsg, sizeof(errmsg));
1000 PJ_LOG(1,(ssock->pool->obj_name, "SSL_read() failed: %s",
1001 errmsg));
1002
Nanang Izzuddin006cc012009-10-16 03:06:13 +00001003 /* Reset SSL socket state, then return PJ_FALSE */
Nanang Izzuddin006cc012009-10-16 03:06:13 +00001004 reset_ssl_sock_state(ssock);
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +00001005 goto on_error;
Nanang Izzuddin006cc012009-10-16 03:06:13 +00001006 }
1007
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +00001008 status = do_handshake(ssock);
1009 if (status == PJ_SUCCESS) {
1010 /* Renegotiation completed */
Nanang Izzuddin006cc012009-10-16 03:06:13 +00001011
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +00001012 /* Update certificates */
1013 update_certs_info(ssock);
1014
1015 pj_lock_acquire(ssock->write_mutex);
Nanang Izzuddin006cc012009-10-16 03:06:13 +00001016 status = flush_delayed_send(ssock);
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +00001017 pj_lock_release(ssock->write_mutex);
1018
1019 if (status != PJ_SUCCESS && status != PJ_EPENDING) {
1020 char errmsg[PJ_ERR_MSG_SIZE];
1021
1022 pj_strerror(status, errmsg, sizeof(errmsg));
1023 PJ_LOG(1,(ssock->pool->obj_name, "Failed to flush "
1024 "delayed send: %s", errmsg));
Nanang Izzuddin006cc012009-10-16 03:06:13 +00001025 goto on_error;
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +00001026 }
1027 } else if (status != PJ_EPENDING) {
1028 char errmsg[PJ_ERR_MSG_SIZE];
1029
1030 pj_strerror(status, errmsg, sizeof(errmsg));
1031 PJ_LOG(1,(ssock->pool->obj_name, "Renegotiation failed: "
1032 "%s", errmsg));
1033 goto on_error;
Nanang Izzuddin006cc012009-10-16 03:06:13 +00001034 }
1035
1036 break;
1037 }
1038 } while (1);
1039 }
1040
1041 return PJ_TRUE;
1042
1043on_error:
1044 if (ssock->ssl_state == SSL_STATE_HANDSHAKING)
1045 return on_handshake_complete(ssock, status);
1046
1047 if (ssock->read_started && ssock->param.cb.on_data_read) {
1048 pj_bool_t ret;
1049 ret = (*ssock->param.cb.on_data_read)(ssock, NULL, 0, status,
1050 remainder);
1051 if (!ret) {
1052 /* We've been destroyed */
1053 return PJ_FALSE;
1054 }
1055 }
1056
1057 reset_ssl_sock_state(ssock);
1058 return PJ_FALSE;
1059}
1060
1061
1062static pj_bool_t asock_on_data_sent (pj_activesock_t *asock,
1063 pj_ioqueue_op_key_t *send_key,
1064 pj_ssize_t sent)
1065{
1066 pj_ssl_sock_t *ssock = (pj_ssl_sock_t*)
1067 pj_activesock_get_user_data(asock);
1068
1069 PJ_UNUSED_ARG(send_key);
1070 PJ_UNUSED_ARG(sent);
1071
1072 if (ssock->ssl_state == SSL_STATE_HANDSHAKING) {
1073 /* Initial handshaking */
1074 pj_status_t status;
1075
1076 status = do_handshake(ssock);
1077 /* Not pending is either success or failed */
1078 if (status != PJ_EPENDING)
1079 return on_handshake_complete(ssock, status);
1080
1081 } else if (send_key != &ssock->handshake_op_key) {
1082 /* Some data has been sent, notify application */
1083 write_data_t *wdata = (write_data_t*)send_key;
1084 if (ssock->param.cb.on_data_sent) {
1085 pj_bool_t ret;
1086 ret = (*ssock->param.cb.on_data_sent)(ssock, wdata->app_key,
1087 wdata->plain_data_len);
1088 if (!ret) {
1089 /* We've been destroyed */
1090 return PJ_FALSE;
1091 }
1092 }
1093
1094 /* Update write buffer state */
1095 pj_lock_acquire(ssock->write_mutex);
1096 ssock->write_state.start += wdata->record_len;
1097 ssock->write_state.len -= wdata->record_len;
1098 if (ssock->write_state.last_data == wdata) {
1099 pj_assert(ssock->write_state.len == 0);
1100 ssock->write_state.last_data = NULL;
1101 }
1102 pj_lock_release(ssock->write_mutex);
1103
1104 } else {
1105 /* SSL re-negotiation is on-progress, just do nothing */
1106 }
1107
1108 return PJ_TRUE;
1109}
1110
1111
1112static pj_bool_t asock_on_accept_complete (pj_activesock_t *asock,
1113 pj_sock_t newsock,
1114 const pj_sockaddr_t *src_addr,
1115 int src_addr_len)
1116{
1117 pj_ssl_sock_t *ssock_parent = (pj_ssl_sock_t*)
1118 pj_activesock_get_user_data(asock);
1119 pj_ssl_sock_t *ssock;
1120 pj_activesock_cb asock_cb;
1121 pj_activesock_cfg asock_cfg;
1122 unsigned i;
1123 pj_status_t status;
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +00001124 char buf[64];
Nanang Izzuddin006cc012009-10-16 03:06:13 +00001125
1126 PJ_UNUSED_ARG(src_addr_len);
1127
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +00001128 PJ_LOG(4,(ssock_parent->pool->obj_name, "Incoming connection from %s",
1129 pj_sockaddr_print(src_addr, buf, sizeof(buf), 3)));
1130
Nanang Izzuddin006cc012009-10-16 03:06:13 +00001131 /* Create new SSL socket instance */
1132 status = pj_ssl_sock_create(ssock_parent->pool, &ssock_parent->param,
1133 &ssock);
1134 if (status != PJ_SUCCESS)
1135 goto on_return;
1136
1137 /* Update new SSL socket attributes */
1138 ssock->sock = newsock;
1139 ssock->parent = ssock_parent;
1140 ssock->is_server = PJ_TRUE;
1141 if (ssock_parent->cert) {
1142 status = pj_ssl_sock_set_certificate(ssock, ssock->pool,
1143 ssock_parent->cert);
1144 if (status != PJ_SUCCESS)
1145 goto on_return;
1146 }
1147
1148 /* Update local address */
1149 ssock->addr_len = src_addr_len;
1150 status = pj_sock_getsockname(ssock->sock, &ssock->local_addr,
1151 &ssock->addr_len);
1152 if (status != PJ_SUCCESS)
1153 goto on_return;
1154
1155 /* Set remote address */
1156 pj_sockaddr_cp(&ssock->rem_addr, src_addr);
1157
1158 /* Create SSL context */
1159 status = create_ssl_ctx(ssock, &ssock->ossl_ctx);
1160 if (status != PJ_SUCCESS)
1161 goto on_return;
1162
1163 /* Create SSL instance */
1164 ssock->ossl_ssl = SSL_new(ssock->ossl_ctx);
1165 if (ssock->ossl_ssl == NULL) {
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +00001166 PJ_LOG(1,(ssock->pool->obj_name, "Error creating SSL instance"));
1167 status = PJ_STATUS_FROM_OSSL(ERR_get_error());
Nanang Izzuddin006cc012009-10-16 03:06:13 +00001168 goto on_return;
1169 }
1170
1171 /* Set cipher list */
1172 status = set_cipher_list(ssock);
1173 if (status != PJ_SUCCESS)
1174 goto on_return;
1175
1176 /* Setup SSL BIOs */
1177 ssock->ossl_rbio = BIO_new(BIO_s_mem());
1178 ssock->ossl_wbio = BIO_new(BIO_s_mem());
1179 BIO_set_close(ssock->ossl_rbio, BIO_CLOSE);
1180 BIO_set_close(ssock->ossl_wbio, BIO_CLOSE);
1181 SSL_set_bio(ssock->ossl_ssl, ssock->ossl_rbio, ssock->ossl_wbio);
1182
1183 /* Prepare read buffer */
1184 ssock->asock_rbuf = (void**)pj_pool_calloc(ssock->pool,
1185 ssock->param.async_cnt,
1186 sizeof(void*));
1187 for (i = 0; i<ssock->param.async_cnt; ++i) {
1188 ssock->asock_rbuf[i] = (void*) pj_pool_alloc(
1189 ssock->pool,
1190 ssock->param.read_buffer_size +
1191 sizeof(read_data_t*));
1192 }
1193
1194 /* Create active socket */
1195 pj_activesock_cfg_default(&asock_cfg);
1196 asock_cfg.async_cnt = ssock->param.async_cnt;
1197 asock_cfg.concurrency = ssock->param.concurrency;
1198 asock_cfg.whole_data = PJ_TRUE;
1199
1200 pj_bzero(&asock_cb, sizeof(asock_cb));
1201 asock_cb.on_data_read = asock_on_data_read;
1202 asock_cb.on_data_sent = asock_on_data_sent;
1203
1204 status = pj_activesock_create(ssock->pool,
1205 ssock->sock,
1206 ssock->param.sock_type,
1207 &asock_cfg,
1208 ssock->param.ioqueue,
1209 &asock_cb,
1210 ssock,
1211 &ssock->asock);
1212
1213 if (status != PJ_SUCCESS)
1214 goto on_return;
1215
1216 /* Start read */
1217 status = pj_activesock_start_read2(ssock->asock, ssock->pool,
1218 ssock->param.read_buffer_size,
1219 ssock->asock_rbuf,
1220 PJ_IOQUEUE_ALWAYS_ASYNC);
1221 if (status != PJ_SUCCESS)
1222 goto on_return;
1223
1224 /* Prepare write/send state */
1225 pj_assert(ssock->write_state.max_len == 0);
1226 ssock->write_state.buf = (char*)
1227 pj_pool_alloc(ssock->pool,
1228 ssock->param.send_buffer_size);
1229 ssock->write_state.max_len = ssock->param.send_buffer_size;
1230 ssock->write_state.start = ssock->write_state.buf;
1231 ssock->write_state.len = 0;
1232
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +00001233 /* Start handshake timer */
1234 if (ssock->param.timer_heap && (ssock->param.timeout.sec != 0 ||
1235 ssock->param.timeout.msec != 0))
1236 {
1237 pj_timer_entry_init(&ssock->handshake_timer, 0, ssock,
1238 &handshake_timeout_cb);
1239 pj_timer_heap_schedule(ssock->param.timer_heap, &ssock->handshake_timer,
1240 &ssock->param.timeout);
1241 }
1242
Nanang Izzuddin006cc012009-10-16 03:06:13 +00001243 /* Start SSL handshake */
1244 ssock->ssl_state = SSL_STATE_HANDSHAKING;
1245 SSL_set_accept_state(ssock->ossl_ssl);
1246 status = do_handshake(ssock);
1247 if (status != PJ_EPENDING)
1248 goto on_return;
1249
1250 return PJ_TRUE;
1251
1252on_return:
1253 return on_handshake_complete(ssock, status);
1254}
1255
1256
1257static pj_bool_t asock_on_connect_complete (pj_activesock_t *asock,
1258 pj_status_t status)
1259{
1260 pj_ssl_sock_t *ssock = (pj_ssl_sock_t*)
1261 pj_activesock_get_user_data(asock);
1262 unsigned i;
1263
1264 if (status != PJ_SUCCESS)
1265 goto on_return;
1266
1267 /* Update local address */
1268 ssock->addr_len = sizeof(pj_sockaddr);
1269 status = pj_sock_getsockname(ssock->sock, &ssock->local_addr,
1270 &ssock->addr_len);
1271 if (status != PJ_SUCCESS)
1272 goto on_return;
1273
1274 /* Create SSL context */
1275 status = create_ssl_ctx(ssock, &ssock->ossl_ctx);
1276 if (status != PJ_SUCCESS)
1277 goto on_return;
1278
1279 /* Create SSL instance */
1280 ssock->ossl_ssl = SSL_new(ssock->ossl_ctx);
1281 if (ssock->ossl_ssl == NULL) {
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +00001282 PJ_LOG(1,(ssock->pool->obj_name, "Error creating SSL instance"));
1283 status = PJ_STATUS_FROM_OSSL(ERR_get_error());
Nanang Izzuddin006cc012009-10-16 03:06:13 +00001284 goto on_return;
1285 }
1286
1287 /* Set cipher list */
1288 status = set_cipher_list(ssock);
1289 if (status != PJ_SUCCESS)
1290 goto on_return;
1291
1292 /* Setup SSL BIOs */
1293 ssock->ossl_rbio = BIO_new(BIO_s_mem());
1294 ssock->ossl_wbio = BIO_new(BIO_s_mem());
1295 BIO_set_close(ssock->ossl_rbio, BIO_CLOSE);
1296 BIO_set_close(ssock->ossl_wbio, BIO_CLOSE);
1297 SSL_set_bio(ssock->ossl_ssl, ssock->ossl_rbio, ssock->ossl_wbio);
1298
1299 /* Prepare read buffer */
1300 ssock->asock_rbuf = (void**)pj_pool_calloc(ssock->pool,
1301 ssock->param.async_cnt,
1302 sizeof(void*));
1303 for (i = 0; i<ssock->param.async_cnt; ++i) {
1304 ssock->asock_rbuf[i] = (void*) pj_pool_alloc(
1305 ssock->pool,
1306 ssock->param.read_buffer_size +
1307 sizeof(read_data_t*));
1308 }
1309
1310 /* Start read */
1311 status = pj_activesock_start_read2(ssock->asock, ssock->pool,
1312 ssock->param.read_buffer_size,
1313 ssock->asock_rbuf,
1314 PJ_IOQUEUE_ALWAYS_ASYNC);
1315 if (status != PJ_SUCCESS)
1316 goto on_return;
1317
1318 /* Prepare write/send state */
1319 pj_assert(ssock->write_state.max_len == 0);
1320 ssock->write_state.buf = (char*)
1321 pj_pool_alloc(ssock->pool,
1322 ssock->param.send_buffer_size);
1323 ssock->write_state.max_len = ssock->param.send_buffer_size;
1324 ssock->write_state.start = ssock->write_state.buf;
1325 ssock->write_state.len = 0;
1326
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +00001327 /* Start handshake timer */
1328 if (ssock->param.timer_heap && (ssock->param.timeout.sec != 0 ||
1329 ssock->param.timeout.msec != 0))
1330 {
1331 pj_timer_entry_init(&ssock->handshake_timer, 0, ssock,
1332 &handshake_timeout_cb);
1333 pj_timer_heap_schedule(ssock->param.timer_heap,
1334 &ssock->handshake_timer,
1335 &ssock->param.timeout);
1336 }
1337
1338#ifdef SSL_set_tlsext_host_name
1339 /* Set server name to connect */
1340 if (ssock->param.server_name.slen) {
1341 /* Server name is null terminated already */
1342 if (!SSL_set_tlsext_host_name(ssock->ossl_ssl,
1343 ssock->param.server_name.ptr))
1344 {
1345 char err_str[PJ_ERR_MSG_SIZE];
1346
1347 ERR_error_string_n(ERR_get_error(), err_str, sizeof(err_str));
1348 PJ_LOG(3,(ssock->pool->obj_name, "SSL_set_tlsext_host_name() "
1349 "failed: %s", err_str));
1350 }
1351 }
1352#endif
1353
Nanang Izzuddin006cc012009-10-16 03:06:13 +00001354 /* Start SSL handshake */
1355 ssock->ssl_state = SSL_STATE_HANDSHAKING;
1356 SSL_set_connect_state(ssock->ossl_ssl);
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +00001357
Nanang Izzuddin006cc012009-10-16 03:06:13 +00001358 status = do_handshake(ssock);
1359 if (status != PJ_EPENDING)
1360 goto on_return;
1361
1362 return PJ_TRUE;
1363
1364on_return:
1365 return on_handshake_complete(ssock, status);
1366}
1367
1368
1369
1370/*
1371 *******************************************************************
1372 * API
1373 *******************************************************************
1374 */
1375
1376/* Load credentials from files. */
1377PJ_DEF(pj_status_t) pj_ssl_cert_load_from_files (pj_pool_t *pool,
1378 const pj_str_t *CA_file,
1379 const pj_str_t *cert_file,
1380 const pj_str_t *privkey_file,
1381 const pj_str_t *privkey_pass,
1382 pj_ssl_cert_t **p_cert)
1383{
1384 pj_ssl_cert_t *cert;
1385
1386 PJ_ASSERT_RETURN(pool && CA_file && cert_file && privkey_file, PJ_EINVAL);
1387
1388 cert = PJ_POOL_ZALLOC_T(pool, pj_ssl_cert_t);
1389 pj_strdup_with_null(pool, &cert->CA_file, CA_file);
1390 pj_strdup_with_null(pool, &cert->cert_file, cert_file);
1391 pj_strdup_with_null(pool, &cert->privkey_file, privkey_file);
1392 pj_strdup_with_null(pool, &cert->privkey_pass, privkey_pass);
1393
1394 *p_cert = cert;
1395
1396 return PJ_SUCCESS;
1397}
1398
1399
1400/* Set SSL socket credentials. */
1401PJ_DECL(pj_status_t) pj_ssl_sock_set_certificate(
1402 pj_ssl_sock_t *ssock,
1403 pj_pool_t *pool,
1404 const pj_ssl_cert_t *cert)
1405{
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +00001406 pj_ssl_cert_t *cert_;
1407
Nanang Izzuddin006cc012009-10-16 03:06:13 +00001408 PJ_ASSERT_RETURN(ssock && pool && cert, PJ_EINVAL);
1409
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +00001410 cert_ = PJ_POOL_ZALLOC_T(pool, pj_ssl_cert_t);
1411 pj_memcpy(cert_, cert, sizeof(cert));
1412 pj_strdup_with_null(pool, &cert_->CA_file, &cert->CA_file);
1413 pj_strdup_with_null(pool, &cert_->cert_file, &cert->cert_file);
1414 pj_strdup_with_null(pool, &cert_->privkey_file, &cert->privkey_file);
1415 pj_strdup_with_null(pool, &cert_->privkey_pass, &cert->privkey_pass);
1416
1417 ssock->cert = cert_;
Nanang Izzuddin006cc012009-10-16 03:06:13 +00001418
1419 return PJ_SUCCESS;
1420}
1421
1422
1423/* Get available ciphers. */
1424PJ_DEF(pj_status_t) pj_ssl_cipher_get_availables(pj_ssl_cipher ciphers[],
1425 unsigned *cipher_num)
1426{
1427 unsigned i;
1428
1429 PJ_ASSERT_RETURN(ciphers && cipher_num, PJ_EINVAL);
1430
1431 if (openssl_cipher_num == 0) {
1432 init_openssl();
1433 shutdown_openssl();
1434 }
1435
1436 if (openssl_cipher_num == 0)
1437 return PJ_ENOTFOUND;
1438
1439 *cipher_num = PJ_MIN(*cipher_num, openssl_cipher_num);
1440
1441 for (i = 0; i < *cipher_num; ++i)
1442 ciphers[i] = openssl_ciphers[i];
1443
1444 return PJ_SUCCESS;
1445}
1446
1447
1448/*
1449 * Create SSL socket instance.
1450 */
1451PJ_DEF(pj_status_t) pj_ssl_sock_create (pj_pool_t *pool,
1452 const pj_ssl_sock_param *param,
1453 pj_ssl_sock_t **p_ssock)
1454{
1455 pj_ssl_sock_t *ssock;
1456 pj_status_t status;
1457
1458 PJ_ASSERT_RETURN(pool && param && p_ssock, PJ_EINVAL);
1459 PJ_ASSERT_RETURN(param->sock_type == pj_SOCK_STREAM(), PJ_ENOTSUP);
1460
1461 pool = pj_pool_create(pool->factory, "ssl%p", 512, 512, NULL);
1462
1463 /* Create secure socket */
1464 ssock = PJ_POOL_ZALLOC_T(pool, pj_ssl_sock_t);
1465 ssock->pool = pool;
1466 ssock->sock = PJ_INVALID_SOCKET;
1467 ssock->ssl_state = SSL_STATE_NULL;
1468 pj_list_init(&ssock->write_pending);
1469 pj_list_init(&ssock->write_pending_empty);
1470
1471 /* Create secure socket mutex */
1472 status = pj_lock_create_recursive_mutex(pool, pool->obj_name,
1473 &ssock->write_mutex);
1474 if (status != PJ_SUCCESS)
1475 return status;
1476
1477 /* Init secure socket param */
1478 ssock->param = *param;
1479 ssock->param.read_buffer_size = ((ssock->param.read_buffer_size+7)>>3)<<3;
1480 if (param->ciphers_num > 0) {
1481 unsigned i;
1482 ssock->param.ciphers = (pj_ssl_cipher*)
1483 pj_pool_calloc(pool, param->ciphers_num,
1484 sizeof(pj_ssl_cipher));
1485 for (i = 0; i < param->ciphers_num; ++i)
1486 ssock->param.ciphers[i] = param->ciphers[i];
1487 }
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +00001488
1489 /* Server name must be null-terminated */
1490 pj_strdup_with_null(pool, &ssock->param.server_name,
1491 &param->server_name);
Nanang Izzuddin006cc012009-10-16 03:06:13 +00001492
1493 /* Finally */
1494 *p_ssock = ssock;
1495
1496 return PJ_SUCCESS;
1497}
1498
1499
1500/*
1501 * Close the secure socket. This will unregister the socket from the
1502 * ioqueue and ultimately close the socket.
1503 */
1504PJ_DEF(pj_status_t) pj_ssl_sock_close(pj_ssl_sock_t *ssock)
1505{
1506 pj_pool_t *pool;
1507
1508 PJ_ASSERT_RETURN(ssock, PJ_EINVAL);
1509
1510 reset_ssl_sock_state(ssock);
1511 pj_lock_destroy(ssock->write_mutex);
1512
1513 pool = ssock->pool;
1514 ssock->pool = NULL;
1515 if (pool)
1516 pj_pool_release(pool);
1517
1518 return PJ_SUCCESS;
1519}
1520
1521
1522/*
1523 * Associate arbitrary data with the secure socket.
1524 */
1525PJ_DEF(pj_status_t) pj_ssl_sock_set_user_data(pj_ssl_sock_t *ssock,
1526 void *user_data)
1527{
1528 PJ_ASSERT_RETURN(ssock, PJ_EINVAL);
1529
1530 ssock->param.user_data = user_data;
1531 return PJ_SUCCESS;
1532}
1533
1534
1535/*
1536 * Retrieve the user data previously associated with this secure
1537 * socket.
1538 */
1539PJ_DEF(void*) pj_ssl_sock_get_user_data(pj_ssl_sock_t *ssock)
1540{
1541 PJ_ASSERT_RETURN(ssock, NULL);
1542
1543 return ssock->param.user_data;
1544}
1545
1546
1547/*
1548 * Retrieve the local address and port used by specified SSL socket.
1549 */
1550PJ_DEF(pj_status_t) pj_ssl_sock_get_info (pj_ssl_sock_t *ssock,
1551 pj_ssl_sock_info *info)
1552{
1553 pj_bzero(info, sizeof(*info));
1554
1555 /* Established flag */
1556 info->established = (ssock->ssl_state == SSL_STATE_ESTABLISHED);
1557
1558 /* Protocol */
1559 info->proto = ssock->param.proto;
1560
1561 /* Local address */
1562 pj_sockaddr_cp(&info->local_addr, &ssock->local_addr);
1563
1564 if (info->established) {
1565 /* Current cipher */
1566 const SSL_CIPHER *cipher;
1567
1568 cipher = SSL_get_current_cipher(ssock->ossl_ssl);
1569 info->cipher = (cipher->id & 0x00FFFFFF);
1570
1571 /* Remote address */
1572 pj_sockaddr_cp(&info->remote_addr, &ssock->rem_addr);
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +00001573
1574 /* Certificates info */
1575 info->local_cert_info = ssock->local_cert_info;
1576 info->remote_cert_info = ssock->remote_cert_info;
Nanang Izzuddin006cc012009-10-16 03:06:13 +00001577 }
1578
1579 return PJ_SUCCESS;
1580}
1581
1582
1583/*
1584 * Starts read operation on this secure socket.
1585 */
1586PJ_DEF(pj_status_t) pj_ssl_sock_start_read (pj_ssl_sock_t *ssock,
1587 pj_pool_t *pool,
1588 unsigned buff_size,
1589 pj_uint32_t flags)
1590{
1591 void **readbuf;
1592 unsigned i;
1593
1594 PJ_ASSERT_RETURN(ssock && pool && buff_size, PJ_EINVAL);
1595 PJ_ASSERT_RETURN(ssock->ssl_state==SSL_STATE_ESTABLISHED, PJ_EINVALIDOP);
1596
1597 readbuf = (void**) pj_pool_calloc(pool, ssock->param.async_cnt,
1598 sizeof(void*));
1599
1600 for (i=0; i<ssock->param.async_cnt; ++i) {
1601 readbuf[i] = pj_pool_alloc(pool, buff_size);
1602 }
1603
1604 return pj_ssl_sock_start_read2(ssock, pool, buff_size,
1605 readbuf, flags);
1606}
1607
1608
1609/*
1610 * Same as #pj_ssl_sock_start_read(), except that the application
1611 * supplies the buffers for the read operation so that the acive socket
1612 * does not have to allocate the buffers.
1613 */
1614PJ_DEF(pj_status_t) pj_ssl_sock_start_read2 (pj_ssl_sock_t *ssock,
1615 pj_pool_t *pool,
1616 unsigned buff_size,
1617 void *readbuf[],
1618 pj_uint32_t flags)
1619{
1620 unsigned i;
1621
1622 PJ_ASSERT_RETURN(ssock && pool && buff_size && readbuf, PJ_EINVAL);
1623 PJ_ASSERT_RETURN(ssock->ssl_state==SSL_STATE_ESTABLISHED, PJ_EINVALIDOP);
1624
1625 /* Create SSL socket read buffer */
1626 ssock->ssock_rbuf = (read_data_t*)pj_pool_calloc(pool,
1627 ssock->param.async_cnt,
1628 sizeof(read_data_t));
1629
1630 /* Store SSL socket read buffer pointer in the activesock read buffer */
1631 for (i=0; i<ssock->param.async_cnt; ++i) {
1632 read_data_t **p_ssock_rbuf =
1633 OFFSET_OF_READ_DATA_PTR(ssock, ssock->asock_rbuf[i]);
1634
1635 ssock->ssock_rbuf[i].data = readbuf[i];
1636 ssock->ssock_rbuf[i].len = 0;
1637
1638 *p_ssock_rbuf = &ssock->ssock_rbuf[i];
1639 }
1640
1641 ssock->read_size = buff_size;
1642 ssock->read_started = PJ_TRUE;
1643 ssock->read_flags = flags;
1644
1645 return PJ_SUCCESS;
1646}
1647
1648
1649/*
1650 * Same as pj_ssl_sock_start_read(), except that this function is used
1651 * only for datagram sockets, and it will trigger \a on_data_recvfrom()
1652 * callback instead.
1653 */
1654PJ_DEF(pj_status_t) pj_ssl_sock_start_recvfrom (pj_ssl_sock_t *ssock,
1655 pj_pool_t *pool,
1656 unsigned buff_size,
1657 pj_uint32_t flags)
1658{
1659 PJ_UNUSED_ARG(ssock);
1660 PJ_UNUSED_ARG(pool);
1661 PJ_UNUSED_ARG(buff_size);
1662 PJ_UNUSED_ARG(flags);
1663
1664 return PJ_ENOTSUP;
1665}
1666
1667
1668/*
1669 * Same as #pj_ssl_sock_start_recvfrom() except that the recvfrom()
1670 * operation takes the buffer from the argument rather than creating
1671 * new ones.
1672 */
1673PJ_DEF(pj_status_t) pj_ssl_sock_start_recvfrom2 (pj_ssl_sock_t *ssock,
1674 pj_pool_t *pool,
1675 unsigned buff_size,
1676 void *readbuf[],
1677 pj_uint32_t flags)
1678{
1679 PJ_UNUSED_ARG(ssock);
1680 PJ_UNUSED_ARG(pool);
1681 PJ_UNUSED_ARG(buff_size);
1682 PJ_UNUSED_ARG(readbuf);
1683 PJ_UNUSED_ARG(flags);
1684
1685 return PJ_ENOTSUP;
1686}
1687
1688/* Write plain data to SSL and flush write BIO. Note that accessing
1689 * write BIO must be serialized, so a call to this function must be
1690 * protected by write mutex of SSL socket.
1691 */
1692static pj_status_t ssl_write(pj_ssl_sock_t *ssock,
1693 pj_ioqueue_op_key_t *send_key,
1694 const void *data,
1695 pj_ssize_t size,
1696 unsigned flags)
1697{
1698 pj_status_t status;
1699 int nwritten;
1700
1701 /* Write the plain data to SSL, after SSL encrypts it, write BIO will
1702 * contain the secured data to be sent via socket. Note that re-
1703 * negotitation may be on progress, so sending data should be delayed
1704 * until re-negotiation is completed.
1705 */
1706 nwritten = SSL_write(ssock->ossl_ssl, data, size);
1707
1708 if (nwritten == size) {
1709 /* All data written, flush write BIO to network socket */
1710 status = flush_write_bio(ssock, send_key, size, flags);
1711 } else if (nwritten <= 0) {
1712 /* SSL failed to process the data, it may just that re-negotiation
1713 * is on progress.
1714 */
1715 int err;
1716 err = SSL_get_error(ssock->ossl_ssl, nwritten);
1717 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_NONE) {
1718 /* Re-negotiation is on progress, flush re-negotiation data */
1719 status = flush_write_bio(ssock, &ssock->handshake_op_key, 0, 0);
1720 if (status == PJ_SUCCESS || status == PJ_EPENDING)
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +00001721 /* Just return PJ_EBUSY when re-negotiation is on progress */
Nanang Izzuddin006cc012009-10-16 03:06:13 +00001722 status = PJ_EBUSY;
1723 } else {
1724 /* Some problem occured */
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +00001725 status = PJ_STATUS_FROM_OSSL(err);
Nanang Izzuddin006cc012009-10-16 03:06:13 +00001726 }
1727 } else {
1728 /* nwritten < *size, shouldn't happen, unless write BIO cannot hold
1729 * the whole secured data, perhaps because of insufficient memory.
1730 */
1731 status = PJ_ENOMEM;
1732 }
1733
1734 return status;
1735}
1736
1737/* Flush delayed data sending in the write pending list. Note that accessing
1738 * write pending list must be serialized, so a call to this function must be
1739 * protected by write mutex of SSL socket.
1740 */
1741static pj_status_t flush_delayed_send(pj_ssl_sock_t *ssock)
1742{
1743 while (!pj_list_empty(&ssock->write_pending)) {
1744 write_pending_t *wp;
1745 pj_status_t status;
1746
1747 wp = ssock->write_pending.next;
1748
1749 status = ssl_write(ssock, &wp->data.key, wp->data.data.ptr,
1750 wp->data.plain_data_len, wp->data.flags);
1751 if (status != PJ_SUCCESS)
1752 return status;
1753
1754 pj_list_erase(wp);
1755 pj_list_push_back(&ssock->write_pending_empty, wp);
1756 }
1757
1758 return PJ_SUCCESS;
1759}
1760
1761/* Sending is delayed, push back the sending data into pending list. Note that
1762 * accessing write pending list must be serialized, so a call to this function
1763 * must be protected by write mutex of SSL socket.
1764 */
1765static pj_status_t delay_send (pj_ssl_sock_t *ssock,
1766 pj_ioqueue_op_key_t *send_key,
1767 const void *data,
1768 pj_ssize_t size,
1769 unsigned flags)
1770{
1771 write_pending_t *wp;
1772
1773 /* Init write pending instance */
1774 if (!pj_list_empty(&ssock->write_pending_empty)) {
1775 wp = ssock->write_pending_empty.next;
1776 pj_list_erase(wp);
1777 } else {
1778 wp = PJ_POOL_ZALLOC_T(ssock->pool, write_pending_t);
1779 }
1780
1781 wp->data.app_key = send_key;
1782 wp->data.plain_data_len = size;
1783 wp->data.data.ptr = data;
1784 wp->data.flags = flags;
1785
1786 pj_list_push_back(&ssock->write_pending, wp);
1787
1788 /* Must return PJ_EPENDING */
1789 return PJ_EPENDING;
1790}
1791
1792/**
1793 * Send data using the socket.
1794 */
1795PJ_DEF(pj_status_t) pj_ssl_sock_send (pj_ssl_sock_t *ssock,
1796 pj_ioqueue_op_key_t *send_key,
1797 const void *data,
1798 pj_ssize_t *size,
1799 unsigned flags)
1800{
1801 pj_status_t status;
1802
1803 PJ_ASSERT_RETURN(ssock && data && size && (*size>0), PJ_EINVAL);
1804 PJ_ASSERT_RETURN(ssock->ssl_state==SSL_STATE_ESTABLISHED, PJ_EINVALIDOP);
1805
1806 pj_lock_acquire(ssock->write_mutex);
1807
1808 /* Flush delayed send first. Sending data might be delayed when
1809 * re-negotiation is on-progress.
1810 */
1811 status = flush_delayed_send(ssock);
1812 if (status == PJ_EBUSY) {
1813 /* Re-negotiation is on progress, delay sending */
1814 status = delay_send(ssock, send_key, data, *size, flags);
1815 goto on_return;
1816 } else if (status != PJ_SUCCESS) {
1817 goto on_return;
1818 }
1819
1820 /* Write data to SSL */
1821 status = ssl_write(ssock, send_key, data, *size, flags);
1822 if (status == PJ_EBUSY) {
1823 /* Re-negotiation is on progress, delay sending */
1824 status = delay_send(ssock, send_key, data, *size, flags);
1825 }
1826
1827on_return:
1828 pj_lock_release(ssock->write_mutex);
1829 return status;
1830}
1831
1832
1833/**
1834 * Send datagram using the socket.
1835 */
1836PJ_DEF(pj_status_t) pj_ssl_sock_sendto (pj_ssl_sock_t *ssock,
1837 pj_ioqueue_op_key_t *send_key,
1838 const void *data,
1839 pj_ssize_t *size,
1840 unsigned flags,
1841 const pj_sockaddr_t *addr,
1842 int addr_len)
1843{
1844 PJ_UNUSED_ARG(ssock);
1845 PJ_UNUSED_ARG(send_key);
1846 PJ_UNUSED_ARG(data);
1847 PJ_UNUSED_ARG(size);
1848 PJ_UNUSED_ARG(flags);
1849 PJ_UNUSED_ARG(addr);
1850 PJ_UNUSED_ARG(addr_len);
1851
1852 return PJ_ENOTSUP;
1853}
1854
1855
1856/**
1857 * Starts asynchronous socket accept() operations on this secure socket.
1858 */
1859PJ_DEF(pj_status_t) pj_ssl_sock_start_accept (pj_ssl_sock_t *ssock,
1860 pj_pool_t *pool,
1861 const pj_sockaddr_t *localaddr,
1862 int addr_len)
1863{
1864 pj_activesock_cb asock_cb;
1865 pj_activesock_cfg asock_cfg;
1866 pj_status_t status;
1867
1868 PJ_ASSERT_RETURN(ssock && pool && localaddr && addr_len, PJ_EINVAL);
1869
1870 /* Create socket */
1871 status = pj_sock_socket(ssock->param.sock_af, ssock->param.sock_type, 0,
1872 &ssock->sock);
1873 if (status != PJ_SUCCESS)
1874 goto on_error;
1875
1876 /* Bind socket */
1877 status = pj_sock_bind(ssock->sock, localaddr, addr_len);
1878 if (status != PJ_SUCCESS)
1879 goto on_error;
1880
1881 /* Start listening to the address */
1882 status = pj_sock_listen(ssock->sock, PJ_SOMAXCONN);
1883 if (status != PJ_SUCCESS)
1884 goto on_error;
1885
1886 /* Create active socket */
1887 pj_activesock_cfg_default(&asock_cfg);
1888 asock_cfg.async_cnt = ssock->param.async_cnt;
1889 asock_cfg.concurrency = ssock->param.concurrency;
1890 asock_cfg.whole_data = PJ_TRUE;
1891
1892 pj_bzero(&asock_cb, sizeof(asock_cb));
1893 asock_cb.on_accept_complete = asock_on_accept_complete;
1894
1895 status = pj_activesock_create(pool,
1896 ssock->sock,
1897 ssock->param.sock_type,
1898 &asock_cfg,
1899 ssock->param.ioqueue,
1900 &asock_cb,
1901 ssock,
1902 &ssock->asock);
1903
1904 if (status != PJ_SUCCESS)
1905 goto on_error;
1906
1907 /* Start accepting */
1908 status = pj_activesock_start_accept(ssock->asock, pool);
1909 if (status != PJ_SUCCESS)
1910 goto on_error;
1911
1912 /* Update local address */
1913 ssock->addr_len = addr_len;
1914 status = pj_sock_getsockname(ssock->sock, &ssock->local_addr,
1915 &ssock->addr_len);
1916 if (status != PJ_SUCCESS)
1917 pj_sockaddr_cp(&ssock->local_addr, localaddr);
1918
1919 ssock->is_server = PJ_TRUE;
1920
1921 return PJ_SUCCESS;
1922
1923on_error:
1924 reset_ssl_sock_state(ssock);
1925 return status;
1926}
1927
1928
1929/**
1930 * Starts asynchronous socket connect() operation.
1931 */
1932PJ_DECL(pj_status_t) pj_ssl_sock_start_connect(pj_ssl_sock_t *ssock,
1933 pj_pool_t *pool,
1934 const pj_sockaddr_t *localaddr,
1935 const pj_sockaddr_t *remaddr,
1936 int addr_len)
1937{
1938 pj_activesock_cb asock_cb;
1939 pj_activesock_cfg asock_cfg;
1940 pj_status_t status;
1941
1942 PJ_ASSERT_RETURN(ssock && pool && localaddr && remaddr && addr_len,
1943 PJ_EINVAL);
1944
1945 /* Create socket */
1946 status = pj_sock_socket(ssock->param.sock_af, ssock->param.sock_type, 0,
1947 &ssock->sock);
1948 if (status != PJ_SUCCESS)
1949 goto on_error;
1950
1951 /* Bind socket */
1952 status = pj_sock_bind(ssock->sock, localaddr, addr_len);
1953 if (status != PJ_SUCCESS)
1954 goto on_error;
1955
1956 /* Create active socket */
1957 pj_activesock_cfg_default(&asock_cfg);
1958 asock_cfg.async_cnt = ssock->param.async_cnt;
1959 asock_cfg.concurrency = ssock->param.concurrency;
1960 asock_cfg.whole_data = PJ_TRUE;
1961
1962 pj_bzero(&asock_cb, sizeof(asock_cb));
1963 asock_cb.on_connect_complete = asock_on_connect_complete;
1964 asock_cb.on_data_read = asock_on_data_read;
1965 asock_cb.on_data_sent = asock_on_data_sent;
1966
1967 status = pj_activesock_create(pool,
1968 ssock->sock,
1969 ssock->param.sock_type,
1970 &asock_cfg,
1971 ssock->param.ioqueue,
1972 &asock_cb,
1973 ssock,
1974 &ssock->asock);
1975
1976 if (status != PJ_SUCCESS)
1977 goto on_error;
1978
1979 status = pj_activesock_start_connect(ssock->asock, pool, remaddr,
1980 addr_len);
1981
1982 if (status == PJ_SUCCESS)
1983 asock_on_connect_complete(ssock->asock, PJ_SUCCESS);
1984 else if (status != PJ_EPENDING)
1985 goto on_error;
1986
1987 /* Update local address */
1988 ssock->addr_len = addr_len;
1989 status = pj_sock_getsockname(ssock->sock, &ssock->local_addr,
1990 &ssock->addr_len);
1991 if (status != PJ_SUCCESS)
1992 pj_sockaddr_cp(&ssock->local_addr, localaddr);
1993
1994 /* Set remote address */
1995 pj_sockaddr_cp(&ssock->rem_addr, remaddr);
1996
1997 /* Update SSL state */
1998 ssock->is_server = PJ_FALSE;
1999
2000 return PJ_EPENDING;
2001
2002on_error:
2003 reset_ssl_sock_state(ssock);
2004 return status;
2005}
2006
2007
Nanang Izzuddinea6d3c42009-10-26 15:47:52 +00002008PJ_DEF(pj_status_t) pj_ssl_sock_renegotiate(pj_ssl_sock_t *ssock)
2009{
2010 int ret;
2011 pj_status_t status;
2012
2013 PJ_ASSERT_RETURN(ssock->ssl_state == SSL_STATE_ESTABLISHED, PJ_EINVALIDOP);
2014
2015 if (SSL_renegotiate_pending(ssock->ossl_ssl))
2016 return PJ_EPENDING;
2017
2018 ret = SSL_renegotiate(ssock->ossl_ssl);
2019 if (ret <= 0) {
2020 status = PJ_STATUS_FROM_OSSL(SSL_get_error(ssock->ossl_ssl, ret));
2021 } else {
2022 status = do_handshake(ssock);
2023 }
2024
2025 return status;
2026}
2027
2028#endif /* PJ_HAS_SSL_SOCK */
Nanang Izzuddin006cc012009-10-16 03:06:13 +00002029