- Timestamp:
- Dec 24, 2006 4:34:50 AM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip/src/pjsip/sip_transport_tls_ossl.c
r852 r858 26 26 #include <pj/os.h> 27 27 #include <pj/pool.h> 28 #include <pj/sock_select.h> 28 29 #include <pj/string.h> 30 #include <pj/compat/socket.h> 29 31 30 32 … … 61 63 /** 62 64 * @hideinitializer 65 * Error creating SSL context. 66 */ 67 #define PJSIP_TLS_ECTX PJ_EUNKNOWN 68 /** 69 * @hideinitializer 63 70 * Unable to list SSL CA list. 64 71 */ … … 104 111 pj_sock_t sock; 105 112 SSL *ssl; 106 BIO *bio;107 113 108 114 pjsip_rx_data rdata; … … 146 152 static int tls_init_count; 147 153 148 /* ssl_perror() */ 149 #if 0 150 #define ssl_perror(level,obj,title) \ 151 { \ 152 unsigned long ssl_err = ERR_get_error(); \ 153 char errmsg[200]; \ 154 ERR_error_string_n(ssl_err, errmsg, sizeof(errmsg)); \ 155 PJ_LOG(level,(obj, "%s: %s", title, errmsg)); \ 156 } 157 #elif 1 158 struct err_data 159 { 160 int lvl; 161 const char *snd; 162 const char *ttl; 163 }; 164 165 static int ssl_print_err_count; 166 static int ssl_print_err_cb(const char *str, size_t len, void *u) 167 { 168 struct err_data *e = (struct err_data *)u; 169 switch (e->lvl) { 170 case 1: 171 PJ_LOG(1,(e->snd, "%s: %.*s", e->ttl, len-1, str)); 172 break; 173 case 2: 174 PJ_LOG(2,(e->snd, "%s: %.*s", e->ttl, len-1, str)); 175 break; 176 case 3: 177 PJ_LOG(3,(e->snd, "%s: %.*s", e->ttl, len-1, str)); 178 break; 179 default: 180 PJ_LOG(4,(e->snd, "%s: %.*s", e->ttl, len-1, str)); 181 break; 182 } 183 ++ssl_print_err_count; 184 return len; 185 } 186 187 static void ssl_perror(int level, const char *sender, const char *title) 188 { 189 struct err_data e; 190 int count = ssl_print_err_count; 191 e.lvl = level; e.snd = sender; e.ttl = title; 192 ERR_print_errors_cb(&ssl_print_err_cb, &e); 193 194 if (count==ssl_print_err_count) 195 ssl_print_err_cb(" ", 1, &e); 196 } 197 #else 198 static void ssl_perror(int level, const char *sender, const char *title) 199 { 200 static BIO *bio_err; 201 202 if (!bio_err) { 203 bio_err = BIO_new_fp(stderr,BIO_NOCLOSE); 204 } 205 ERR_print_errors(bio_err); 206 } 207 208 #endif 154 /* ssl_report_error() */ 155 static void ssl_report_error(int level, const char *sender, 156 const char *format, ...) 157 { 158 va_list arg; 159 unsigned long ssl_err; 160 161 va_start(arg, format); 162 ssl_err = ERR_get_error(); 163 164 if (ssl_err == 0) { 165 pj_log(sender, level, format, arg); 166 } else { 167 char err_format[512]; 168 int len; 169 170 len = pj_ansi_snprintf(err_format, sizeof(err_format), 171 "%s: ", format); 172 ERR_error_string(ssl_err, err_format+len); 173 174 pj_log(sender, level, err_format, arg); 175 } 176 177 va_end(arg); 178 } 209 179 210 180 … … 255 225 SSL_CTX *ctx; 256 226 227 *p_ctx = NULL; 228 257 229 /* Create SSL context*/ 258 230 meth = SSLv23_method(); 259 231 ctx = SSL_CTX_new(meth); 232 if (ctx == NULL) 233 return PJSIP_TLS_ECTX; 234 235 /* Load the CAs we trust*/ 236 if (ca_list_file && *ca_list_file) { 237 if(!(SSL_CTX_load_verify_locations(ctx, ca_list_file, 0))) { 238 ssl_report_error(2, lis->base.obj_name, 239 "Error loading/verifying CA list file '%s'", 240 ca_list_file); 241 SSL_CTX_free(ctx); 242 return PJSIP_TLS_ECALIST; 243 } 244 } 245 260 246 261 247 /* Load our keys and certificates */ 262 if(!(SSL_CTX_use_certificate_chain_file(ctx, keyfile))) { 263 ssl_perror(2, lis->base.obj_name, 264 "Error loading keys and certificate file"); 265 SSL_CTX_free(ctx); 266 return PJSIP_TLS_EKEYFILE; 267 } 268 269 /* Set password callback */ 270 SSL_CTX_set_default_passwd_cb(ctx, password_cb); 271 SSL_CTX_set_default_passwd_cb_userdata(ctx, lis); 272 273 if(!(SSL_CTX_use_PrivateKey_file(ctx, keyfile, SSL_FILETYPE_PEM))) { 274 ssl_perror(2, lis->base.obj_name, "Error loading private key file"); 275 SSL_CTX_free(ctx); 276 return PJSIP_TLS_EKEYFILE; 277 } 278 279 /* Load the CAs we trust*/ 280 if(!(SSL_CTX_load_verify_locations(ctx, ca_list_file, 0))) { 281 ssl_perror(2, lis->base.obj_name, 282 "Error loading/verifying CA list file"); 283 SSL_CTX_free(ctx); 284 return PJSIP_TLS_ECALIST; 248 if (keyfile && *keyfile) { 249 if(!(SSL_CTX_use_certificate_chain_file(ctx, keyfile))) { 250 ssl_report_error(2, lis->base.obj_name, 251 "Error loading keys and certificate file '%s'", 252 keyfile); 253 SSL_CTX_free(ctx); 254 return PJSIP_TLS_EKEYFILE; 255 } 256 257 /* Set password callback */ 258 SSL_CTX_set_default_passwd_cb(ctx, password_cb); 259 SSL_CTX_set_default_passwd_cb_userdata(ctx, lis); 260 261 if(!(SSL_CTX_use_PrivateKey_file(ctx, keyfile, SSL_FILETYPE_PEM))) { 262 ssl_report_error(2, lis->base.obj_name, 263 "Error loading private key file '%s'", 264 keyfile); 265 SSL_CTX_free(ctx); 266 return PJSIP_TLS_EKEYFILE; 267 } 285 268 } 286 269 … … 498 481 499 482 while (!tls_tp->quitting) { 483 pj_fd_set_t rd_set; 484 pj_time_val timeout; 500 485 int len; 501 486 pj_size_t size_eaten; 487 488 PJ_FD_ZERO(&rd_set); 489 PJ_FD_SET(tls_tp->sock, &rd_set); 490 491 timeout.sec = 1; 492 timeout.msec = 0; 493 494 len = pj_sock_select(tls_tp->sock, &rd_set, NULL, NULL, &timeout); 495 if (len < 1) 496 continue; 502 497 503 498 /* Start blocking read to SSL socket */ … … 535 530 case SSL_ERROR_ZERO_RETURN: 536 531 PJ_LOG(4,(tls_tp->base.obj_name, "SSL transport shutdodwn by remote")); 537 pjsip_transport_shutdown(&tls_tp->base); 532 if (!tls_tp->quitting) 533 pjsip_transport_shutdown(&tls_tp->base); 538 534 goto done; 539 535 540 536 case SSL_ERROR_SYSCALL: 541 537 PJ_LOG(2,(tls_tp->base.obj_name, "SSL Error: Premature close")); 542 pjsip_transport_shutdown(&tls_tp->base); 538 if (!tls_tp->quitting) 539 pjsip_transport_shutdown(&tls_tp->base); 543 540 goto done; 544 541 545 542 default: 546 543 PJ_LOG(2,(tls_tp->base.obj_name, "SSL read problem")); 547 pjsip_transport_shutdown(&tls_tp->base); 544 if (!tls_tp->quitting) 545 pjsip_transport_shutdown(&tls_tp->base); 548 546 goto done; 549 547 } 550 551 548 } 552 549 553 550 done: 554 551 return 0; 552 } 553 554 555 PJ_DECL(pj_size_t) PJ_FD_COUNT(const pj_fd_set_t *fdsetp); 556 557 /* 558 * Perform SSL_connect upon completion of socket connect() 559 */ 560 static pj_status_t perform_ssl_connect(SSL *ssl, pj_sock_t sock) 561 { 562 int status; 563 564 if (SSL_is_init_finished (ssl)) 565 return PJ_SUCCESS; 566 567 SSL_set_fd(ssl, (int)sock); 568 569 if (!SSL_in_connect_init (ssl)) 570 SSL_set_connect_state (ssl); 571 572 do { 573 /* These handle sets are used to set up for whatever SSL_connect 574 * says it wants next. They're reset on each pass around the loop. 575 */ 576 pj_fd_set_t rd_set; 577 pj_fd_set_t wr_set; 578 579 PJ_FD_ZERO(&rd_set); 580 PJ_FD_ZERO(&wr_set); 581 582 status = SSL_connect (ssl); 583 switch (SSL_get_error (ssl, status)) { 584 case SSL_ERROR_NONE: 585 /* Success */ 586 status = 0; 587 break; 588 589 case SSL_ERROR_WANT_WRITE: 590 /* Wait for more activity */ 591 PJ_FD_SET(sock, &wr_set); 592 status = 1; 593 break; 594 595 case SSL_ERROR_WANT_READ: 596 /* Wait for more activity */ 597 PJ_FD_SET(sock, &rd_set); 598 status = 1; 599 break; 600 601 case SSL_ERROR_ZERO_RETURN: 602 /* The peer has notified us that it is shutting down via 603 * the SSL "close_notify" message so we need to 604 * shutdown, too. 605 */ 606 PJ_LOG(4,(THIS_FILE, "SSL connect() failed, remote has" 607 "shutdown connection.")); 608 status = -1; 609 break; 610 611 case SSL_ERROR_SYSCALL: 612 /* On some platforms (e.g. MS Windows) OpenSSL does not 613 * store the last error in errno so explicitly do so. 614 * 615 * Explicitly check for EWOULDBLOCK since it doesn't get 616 * converted to an SSL_ERROR_WANT_{READ,WRITE} on some 617 * platforms. If SSL_connect failed outright, though, don't 618 * bother checking more. This can happen if the socket gets 619 * closed during the handshake. 620 */ 621 if (pj_get_netos_error() == PJ_STATUS_FROM_OS(OSERR_EWOULDBLOCK) && 622 status == -1) 623 { 624 /* Although the SSL_ERROR_WANT_READ/WRITE isn't getting 625 * set correctly, the read/write state should be valid. 626 * Use that to decide what to do. 627 */ 628 status = 1; /* Wait for more activity */ 629 if (SSL_want_write (ssl)) 630 PJ_FD_SET(sock, &wr_set); 631 else if (SSL_want_read (ssl)) 632 PJ_FD_SET(sock, &rd_set); 633 else 634 status = -1; /* Doesn't want anything - bail out */ 635 } 636 else { 637 status = -1; 638 } 639 break; 640 641 default: 642 ssl_report_error(4, THIS_FILE, "SSL_connect() error"); 643 status = -1; 644 break; 645 } 646 647 if (status == 1) { 648 /* Must have at least one handle to wait for at this point. */ 649 pj_assert(PJ_FD_COUNT(&rd_set) == 1 || 650 PJ_FD_COUNT(&wr_set) == 1); 651 652 /* Block indefinitely if timeout pointer is zero. */ 653 status = pj_sock_select(FD_SETSIZE, &rd_set, &wr_set, 654 NULL, NULL); 655 656 /* 0 is timeout, so we're done. 657 * -1 is error, so we're done. 658 * Could be both handles set (same handle in both masks) so set to 1. 659 */ 660 if (status >= 1) 661 status = 1; 662 else /* Timeout or socket failure */ 663 status = -1; 664 } 665 666 } while (status == 1 && !SSL_is_init_finished (ssl)); 667 668 return (status == -1 ? PJSIP_TLS_ECONNECT : PJ_SUCCESS); 555 669 } 556 670 … … 658 772 /* Create SSL object and BIO */ 659 773 tls_tp->ssl = SSL_new(lis->ctx); 660 tls_tp->bio = BIO_new_socket(sock, BIO_NOCLOSE); 661 SSL_set_bio(tls_tp->ssl, tls_tp->bio, tls_tp->bio); 774 SSL_set_verify (tls_tp->ssl, 0, 0); 662 775 663 776 /* Connect SSL */ 664 if (SSL_connect(tls_tp->ssl) <= 0) { 665 ssl_perror(4, tls_tp->base.obj_name, "SSL_connect() error"); 666 status = PJSIP_TLS_ECONNECT; 777 status = perform_ssl_connect(tls_tp->ssl, sock); 778 if (status != PJ_SUCCESS) 667 779 goto on_error; 668 }669 780 670 781 /* TODO: check server cert. */ … … 840 951 { 841 952 struct tls_transport *tls_tp = (struct tls_transport*) transport; 953 int bytes_sent; 842 954 843 955 /* This is a connection oriented protocol, so rem_addr is not used */ … … 845 957 PJ_UNUSED_ARG(addr_len); 846 958 847 /* Write to TLS */848 if (BIO_write(tls_tp->bio, tdata->buf.start ,849 tdata->buf.cur - tdata->buf.start) <= 0)850 {851 if(! BIO_should_retry(tls_tp->bio)) {852 ssl_perror(4, transport->obj_name, "SSL send error");853 return PJSIP_TLS_ESEND;854 }855 856 /* Do something to handle the retry */857 }858 859 959 /* Data written immediately, no need to call callback */ 860 960 PJ_UNUSED_ARG(callback); 861 961 PJ_UNUSED_ARG(token); 862 962 863 return PJ_SUCCESS; 963 /* Write to TLS */ 964 bytes_sent = SSL_write (tls_tp->ssl, tdata->buf.start, 965 tdata->buf.cur - tdata->buf.start); 966 967 switch (SSL_get_error (tls_tp->ssl, bytes_sent)) { 968 case SSL_ERROR_NONE: 969 pj_assert(bytes_sent == tdata->buf.cur - tdata->buf.start); 970 return PJ_SUCCESS; 971 972 case SSL_ERROR_WANT_READ: 973 case SSL_ERROR_WANT_WRITE: 974 return PJ_RETURN_OS_ERROR(OSERR_EWOULDBLOCK); 975 976 case SSL_ERROR_ZERO_RETURN: 977 /* The peer has notified us that it is shutting down via the SSL 978 * "close_notify" message so we need to shutdown, too. 979 */ 980 pj_assert(bytes_sent == tdata->buf.cur - tdata->buf.start); 981 SSL_shutdown (tls_tp->ssl); 982 pjsip_transport_shutdown(transport); 983 return PJ_SUCCESS; 984 985 case SSL_ERROR_SYSCALL: 986 if (bytes_sent == 0) { 987 /* An EOF occured but the SSL "close_notify" message was not 988 * sent. This is a protocol error, but we ignore it. 989 */ 990 pjsip_transport_shutdown(transport); 991 return 0; 992 } 993 return pj_get_netos_error(); 994 995 default: 996 /* Reset errno to prevent previous values (e.g. EWOULDBLOCK) 997 * from being associated with fatal SSL errors. 998 */ 999 pj_set_netos_error(0); 1000 ssl_report_error(4, transport->obj_name, "SSL_write error"); 1001 return PJSIP_TLS_ESEND; 1002 } 864 1003 } 865 1004 … … 906 1045 SSL_free(tls_tp->ssl); 907 1046 tls_tp->ssl = NULL; 908 tls_tp->bio = NULL;909 1047 tls_tp->sock = PJ_INVALID_SOCKET; 910 1048
Note: See TracChangeset
for help on using the changeset viewer.