int ipfix_ssl_init_con( SSL *con ) { extern FILE *mlog_fp; // todo: see if this is working int i; char *str; long verify_error; char buf[100]; if ((i=SSL_accept(con)) <= 0) { if (BIO_sock_should_retry(i)) { mlogf( 0, "[ipfix_ssl_init] DELAY\n"); return -1; } mlogf( 0, "[ipfix_ssl_init] ERROR\n"); verify_error=SSL_get_verify_result( con ); if (verify_error != X509_V_OK) { mlogf( 0, "[ipfix_ssl_init] verify error: %s\n", X509_verify_cert_error_string(verify_error)); } else ERR_print_errors_fp( mlog_fp ); return -1; } if ( 1 <= mlog_get_vlevel() ) { PEM_write_SSL_SESSION( mlog_fp, SSL_get_session(con)); if ( SSL_get_shared_ciphers(con, buf, sizeof buf) != NULL) { mlogf( 3, "[ipfix] Shared ciphers:%s\n", buf); } str=(char*)SSL_CIPHER_get_name( SSL_get_current_cipher(con) ); mlogf( 3, "[ipfix] CIPHER is %s\n",(str != NULL)?str:"(NONE)"); if (SSL_ctrl(con,SSL_CTRL_GET_FLAGS,0,NULL) & TLS1_FLAGS_TLS_PADDING_BUG) { mlogf( 1, "[ipfix] Peer has incorrect TLSv1 block padding\n"); } } return 0; }
void logsslstats(SSL *reference) { char sglobal[1024]; p_log(LOG_INFO,-1, lngtxt(613)); if(reference==NULL) p_log(LOG_INFO,-1,lngtxt(614)); else { if(SSL_get_shared_ciphers(reference,sglobal,1023)==NULL) strmncpy(sglobal,lngtxt(615),sizeof(sglobal)); p_log(LOG_INFO,-1,lngtxt(616),sglobal); } p_log(LOG_INFO,-1, lngtxt(617), SSL_CTX_sess_number(srvctx)+SSL_CTX_sess_number(clnctx)); p_log(LOG_INFO,-1, lngtxt(618), SSL_CTX_sess_connect(srvctx)+SSL_CTX_sess_connect(clnctx)); p_log(LOG_INFO,-1, lngtxt(619), SSL_CTX_sess_connect_good(srvctx)+SSL_CTX_sess_connect_good(clnctx)); #if SSLEAY_VERSION_NUMBER >= 0x0922 p_log(LOG_INFO,-1, lngtxt(620), SSL_CTX_sess_connect_renegotiate(srvctx)+SSL_CTX_sess_connect_renegotiate(clnctx)); #endif p_log(LOG_INFO,-1, lngtxt(621), SSL_CTX_sess_accept(srvctx)+SSL_CTX_sess_accept(clnctx)); p_log(LOG_INFO,-1, lngtxt(622), SSL_CTX_sess_accept_good(srvctx)+SSL_CTX_sess_accept_good(clnctx)); #if SSLEAY_VERSION_NUMBER >= 0x0922 p_log(LOG_INFO,-1, lngtxt(623), SSL_CTX_sess_accept_renegotiate(srvctx)+SSL_CTX_sess_accept_renegotiate(clnctx)); #endif p_log(LOG_INFO,-1, lngtxt(624), SSL_CTX_sess_hits(srvctx)+SSL_CTX_sess_hits(clnctx)); p_log(LOG_INFO,-1, lngtxt(625), SSL_CTX_sess_misses(srvctx)+SSL_CTX_sess_misses(clnctx)); p_log(LOG_INFO,-1, lngtxt(626), SSL_CTX_sess_timeouts(srvctx)+SSL_CTX_sess_timeouts(clnctx)); p_log(LOG_INFO,-1, lngtxt(627)); return; }
static void print_stuff(BIO *bio, SSL *s, int full) { X509 *peer=NULL; char *p; static const char *space=" "; char buf[BUFSIZ]; STACK_OF(X509) *sk; STACK_OF(X509_NAME) *sk2; SSL_CIPHER *c; X509_NAME *xn; int j,i; #ifndef OPENSSL_NO_COMP const COMP_METHOD *comp, *expansion; #endif if (full) { int got_a_chain = 0; sk=SSL_get_peer_cert_chain(s); if (sk != NULL) { got_a_chain = 1; /* we don't have it for SSL2 (yet) */ BIO_printf(bio,"---\nCertificate chain\n"); for (i=0; i<sk_X509_num(sk); i++) { X509_NAME_oneline(X509_get_subject_name( sk_X509_value(sk,i)),buf,sizeof buf); BIO_printf(bio,"%2d s:%s\n",i,buf); X509_NAME_oneline(X509_get_issuer_name( sk_X509_value(sk,i)),buf,sizeof buf); BIO_printf(bio," i:%s\n",buf); if (c_showcerts) PEM_write_bio_X509(bio,sk_X509_value(sk,i)); } } BIO_printf(bio,"---\n"); peer=SSL_get_peer_certificate(s); if (peer != NULL) { BIO_printf(bio,"Server certificate\n"); if (!(c_showcerts && got_a_chain)) /* Redundant if we showed the whole chain */ PEM_write_bio_X509(bio,peer); X509_NAME_oneline(X509_get_subject_name(peer), buf,sizeof buf); BIO_printf(bio,"subject=%s\n",buf); X509_NAME_oneline(X509_get_issuer_name(peer), buf,sizeof buf); BIO_printf(bio,"issuer=%s\n",buf); } else BIO_printf(bio,"no peer certificate available\n"); sk2=SSL_get_client_CA_list(s); if ((sk2 != NULL) && (sk_X509_NAME_num(sk2) > 0)) { BIO_printf(bio,"---\nAcceptable client certificate CA names\n"); for (i=0; i<sk_X509_NAME_num(sk2); i++) { xn=sk_X509_NAME_value(sk2,i); X509_NAME_oneline(xn,buf,sizeof(buf)); BIO_write(bio,buf,strlen(buf)); BIO_write(bio,"\n",1); } } else { BIO_printf(bio,"---\nNo client certificate CA names sent\n"); } p=SSL_get_shared_ciphers(s,buf,sizeof buf); if (p != NULL) { /* This works only for SSL 2. In later protocol * versions, the client does not know what other * ciphers (in addition to the one to be used * in the current connection) the server supports. */ BIO_printf(bio,"---\nCiphers common between both SSL endpoints:\n"); j=i=0; while (*p) { if (*p == ':') { BIO_write(bio,space,15-j%25); i++; j=0; BIO_write(bio,((i%3)?" ":"\n"),1); } else { BIO_write(bio,p,1); j++; } p++; } BIO_write(bio,"\n",1); } BIO_printf(bio,"---\nSSL handshake has read %ld bytes and written %ld bytes\n", BIO_number_read(SSL_get_rbio(s)), BIO_number_written(SSL_get_wbio(s))); } BIO_printf(bio,((s->hit)?"---\nReused, ":"---\nNew, ")); c=SSL_get_current_cipher(s); BIO_printf(bio,"%s, Cipher is %s\n", SSL_CIPHER_get_version(c), SSL_CIPHER_get_name(c)); if (peer != NULL) { EVP_PKEY *pktmp; pktmp = X509_get_pubkey(peer); BIO_printf(bio,"Server public key is %d bit\n", EVP_PKEY_bits(pktmp)); EVP_PKEY_free(pktmp); } #ifndef OPENSSL_NO_COMP comp=SSL_get_current_compression(s); expansion=SSL_get_current_expansion(s); BIO_printf(bio,"Compression: %s\n", comp ? SSL_COMP_get_name(comp) : "NONE"); BIO_printf(bio,"Expansion: %s\n", expansion ? SSL_COMP_get_name(expansion) : "NONE"); #endif SSL_SESSION_print(bio,SSL_get_session(s)); BIO_printf(bio,"---\n"); if (peer != NULL) X509_free(peer); /* flush, or debugging output gets mixed with http response */ (void)BIO_flush(bio); }
static int ssl_do(struct st_VioSSLFd *ptr, Vio *vio, long timeout, ssl_handshake_func_t func, unsigned long *ssl_errno_holder) { int r; SSL *ssl; my_socket sd= mysql_socket_getfd(vio->mysql_socket); DBUG_ENTER("ssl_do"); DBUG_PRINT("enter", ("ptr: 0x%lx, sd: %d ctx: 0x%lx", (long) ptr, sd, (long) ptr->ssl_context)); if (!(ssl= SSL_new(ptr->ssl_context))) { DBUG_PRINT("error", ("SSL_new failure")); *ssl_errno_holder= ERR_get_error(); DBUG_RETURN(1); } DBUG_PRINT("info", ("ssl: 0x%lx timeout: %ld", (long) ssl, timeout)); SSL_clear(ssl); SSL_SESSION_set_timeout(SSL_get_session(ssl), timeout); SSL_set_fd(ssl, sd); #ifndef HAVE_YASSL SSL_set_options(ssl, SSL_OP_NO_COMPRESSION); #endif /* Since yaSSL does not support non-blocking send operations, use special transport functions that properly handles non-blocking sockets. These functions emulate the behavior of blocking I/O operations by waiting for I/O to become available. */ #ifdef HAVE_YASSL /* Set first argument of the transport functions. */ yaSSL_transport_set_ptr(ssl, vio); /* Set functions to use in order to send and receive data. */ yaSSL_transport_set_recv_function(ssl, yassl_recv); yaSSL_transport_set_send_function(ssl, yassl_send); #endif if ((r= ssl_handshake_loop(vio, ssl, func, ssl_errno_holder)) < 1) { DBUG_PRINT("error", ("SSL_connect/accept failure")); SSL_free(ssl); DBUG_RETURN(1); } /* Connection succeeded. Install new function handlers, change type, set sd to the fd used when connecting and set pointer to the SSL structure */ if (vio_reset(vio, VIO_TYPE_SSL, SSL_get_fd(ssl), ssl, 0)) DBUG_RETURN(1); #ifndef DBUG_OFF { /* Print some info about the peer */ X509 *cert; char buf[512]; DBUG_PRINT("info",("SSL connection succeeded")); DBUG_PRINT("info",("Using cipher: '%s'" , SSL_get_cipher_name(ssl))); if ((cert= SSL_get_peer_certificate (ssl))) { DBUG_PRINT("info",("Peer certificate:")); X509_NAME_oneline(X509_get_subject_name(cert), buf, sizeof(buf)); DBUG_PRINT("info",("\t subject: '%s'", buf)); X509_NAME_oneline(X509_get_issuer_name(cert), buf, sizeof(buf)); DBUG_PRINT("info",("\t issuer: '%s'", buf)); X509_free(cert); } else DBUG_PRINT("info",("Peer does not have certificate.")); if (SSL_get_shared_ciphers(ssl, buf, sizeof(buf))) { DBUG_PRINT("info",("shared_ciphers: '%s'", buf)); } else DBUG_PRINT("info",("no shared ciphers!")); } #endif DBUG_RETURN(0); }
static int ssl_do(struct st_VioSSLFd *ptr, Vio *vio, long timeout, int (*connect_accept_func)(SSL*), unsigned long *errptr) { int r; SSL *ssl; my_bool unused; my_bool was_blocking; DBUG_ENTER("ssl_do"); DBUG_PRINT("enter", ("ptr: 0x%lx, sd: %d ctx: 0x%lx", (long) ptr, vio->sd, (long) ptr->ssl_context)); /* Set socket to blocking if not already set */ vio_blocking(vio, 1, &was_blocking); if (!(ssl= SSL_new(ptr->ssl_context))) { DBUG_PRINT("error", ("SSL_new failure")); *errptr= ERR_get_error(); vio_blocking(vio, was_blocking, &unused); DBUG_RETURN(1); } DBUG_PRINT("info", ("ssl: 0x%lx timeout: %ld", (long) ssl, timeout)); SSL_clear(ssl); SSL_SESSION_set_timeout(SSL_get_session(ssl), timeout); SSL_set_fd(ssl, vio->sd); #if !defined(HAVE_YASSL) && defined(SSL_OP_NO_COMPRESSION) SSL_set_options(ssl, SSL_OP_NO_COMPRESSION); #endif if ((r= connect_accept_func(ssl)) < 1) { DBUG_PRINT("error", ("SSL_connect/accept failure")); *errptr= SSL_get_error(ssl, r); SSL_free(ssl); vio_blocking(vio, was_blocking, &unused); DBUG_RETURN(1); } /* Connection succeeded. Install new function handlers, change type, set sd to the fd used when connecting and set pointer to the SSL structure */ vio_reset(vio, VIO_TYPE_SSL, SSL_get_fd(ssl), 0, 0); vio->ssl_arg= (void*)ssl; #ifndef DBUG_OFF { /* Print some info about the peer */ X509 *cert; char buf[512]; DBUG_PRINT("info",("SSL connection succeeded")); DBUG_PRINT("info",("Using cipher: '%s'" , SSL_get_cipher_name(ssl))); if ((cert= SSL_get_peer_certificate (ssl))) { DBUG_PRINT("info",("Peer certificate:")); X509_NAME_oneline(X509_get_subject_name(cert), buf, sizeof(buf)); DBUG_PRINT("info",("\t subject: '%s'", buf)); X509_NAME_oneline(X509_get_issuer_name(cert), buf, sizeof(buf)); DBUG_PRINT("info",("\t issuer: '%s'", buf)); X509_free(cert); } else DBUG_PRINT("info",("Peer does not have certificate.")); if (SSL_get_shared_ciphers(ssl, buf, sizeof(buf))) { DBUG_PRINT("info",("shared_ciphers: '%s'", buf)); } else DBUG_PRINT("info",("no shared ciphers!")); } #endif DBUG_RETURN(0); }
/* Switch on a filedescriptor */ int ggz_tls_enable_fd(int fd, GGZTLSType mode, GGZTLSVerificationType verify) { int ret, ret2; STACK_OF(SSL_CIPHER) *stack; SSL_CIPHER *cipher; int bits; char *cipherlist; SSL *_tls; int _tls_active; struct list_entry *entry; _state = 1; _tls_active = 0; if((mode != GGZ_TLS_CLIENT) && (mode != GGZ_TLS_SERVER)) { TLSERROR("Wrong mode."); return 0; } if(!_tlsctx) tls_init(verify); _tls = SSL_new(_tlsctx); if(_tls) { cipherlist = NULL; stack = SSL_get_ciphers(_tls); while((cipher = (SSL_CIPHER*)sk_pop(stack)) != NULL) { printf("* Cipher: %s\n", SSL_CIPHER_get_name(cipher)); printf(" Bits: %i\n", SSL_CIPHER_get_bits(cipher, &bits)); printf(" Used bits: %i\n", bits); printf(" Version: %s\n", SSL_CIPHER_get_version(cipher)); printf(" Description: %s\n", SSL_CIPHER_description(cipher, NULL, 0)); if(cipherlist) { cipherlist = (char*)realloc(cipherlist, (strlen(cipherlist) + 1) + strlen(SSL_CIPHER_get_name(cipher)) + 1); strcat(cipherlist, ":"); strcat(cipherlist, SSL_CIPHER_get_name(cipher)); } else { cipherlist = (char*)malloc(strlen(SSL_CIPHER_get_name(cipher)) + 1); strcpy(cipherlist, SSL_CIPHER_get_name(cipher)); } } printf("Available ciphers: %s\n", cipherlist); ret = SSL_set_cipher_list(_tls, cipherlist); if(!ret) TLSERROR("Cipher selection failed."); ret = SSL_set_fd(_tls, fd); if(!ret) TLSERROR("Assignment to connection failed."); else { SSL_set_read_ahead(_tls, 1); if(mode == GGZ_TLS_SERVER) { tls_certkey(_tls); if(_state) { SSL_set_accept_state(_tls); ret = SSL_accept(_tls); } } else { SSL_set_connect_state(_tls); ret = SSL_connect(_tls); } if((ret != 1) || (!_state)) { printf("Ret: %i, State: %i\n", ret, _state); TLSERROR("Handshake failed."); ret2 = ERR_get_error(); printf("EXT: %s\n%s\n%s\n%s\n%s\n", tls_exterror(_tls, ret), ERR_error_string(ret2, NULL), ERR_lib_error_string(ret2), ERR_func_error_string(ret2), ERR_reason_error_string(ret2)); } else { printf(">>>>> Handshake successful.\n"); if((mode == GGZ_TLS_SERVER) || (verify == GGZ_TLS_VERIFY_NONE)) _tls_active = 1; else { printf(">>>>> Client side, thus checking Certificate.\n"); printf("Negotiated cipher: %s\n", SSL_get_cipher(_tls)); printf("Shared ciphers: %s\n", SSL_get_shared_ciphers(_tls, NULL, 0)); if(SSL_get_peer_certificate(_tls)) { if(SSL_get_verify_result(_tls) == X509_V_OK) { _tls_active = 1; } else { printf("Error code: %li\n", SSL_get_verify_result(_tls)); TLSERROR("Invalid certificate, or certificate is not self-signed."); } } else TLSERROR("Couldn't get certificate."); } } entry = (struct list_entry*)ggz_malloc(sizeof(struct list_entry)); entry->tls = _tls; entry->fd = fd; entry->active = _tls_active; ggz_list_insert(openssllist, entry); return 1; } } return 0; }
static int openssl_ssl_get(lua_State*L) { SSL* s = CHECK_OBJECT(1, SSL, "openssl.ssl"); int i; int top = lua_gettop(L); for (i = 2; i <= top; i++) { const char* what = luaL_checklstring(L, i, NULL); if (strcmp(what, "fd") == 0) { lua_pushinteger(L, SSL_get_fd(s)); } else if (strcmp(what, "rfd") == 0) { lua_pushinteger(L, SSL_get_rfd(s)); } else if (strcmp(what, "wfd") == 0) { lua_pushinteger(L, SSL_get_wfd(s)); } else if (strcmp(what, "client_CA_list") == 0) { STACK_OF(X509_NAME)* sn = SSL_get_client_CA_list(s); PUSH_OBJECT(sn, "openssl.sk_x509_name"); } else if (strcmp(what, "read_ahead") == 0) { lua_pushboolean(L, SSL_get_read_ahead(s)); } else if (strcmp(what, "shared_ciphers") == 0) { char buf[LUAL_BUFFERSIZE] = {0}; lua_pushstring(L, SSL_get_shared_ciphers(s, buf, sizeof(buf))); } else if (strcmp(what, "cipher_list") == 0) { //TODO FIX lua_pushstring(L, SSL_get_cipher_list(s, 0)); } else if (strcmp(what, "verify_mode") == 0) { //FIX lua_pushinteger(L, SSL_get_verify_mode(s)); } else if (strcmp(what, "verify_depth") == 0) { lua_pushinteger(L, SSL_get_verify_depth(s)); } else if (strcmp(what, "state_string") == 0) { lua_pushstring(L, SSL_state_string(s)); } else if (strcmp(what, "state_string_long") == 0) { lua_pushstring(L, SSL_state_string_long(s)); } else if (strcmp(what, "rstate_string") == 0) { lua_pushstring(L, SSL_rstate_string(s)); } else if (strcmp(what, "rstate_string_long") == 0) { lua_pushstring(L, SSL_rstate_string_long(s)); } else if (strcmp(what, "version") == 0) { lua_pushstring(L, SSL_get_version(s)); } else if (strcmp(what, "iversion") == 0) { lua_pushinteger(L, SSL_version(s)); } else if (strcmp(what, "default_timeout") == 0) { lua_pushinteger(L, SSL_get_default_timeout(s)); } else if (strcmp(what, "certificate") == 0) { X509* cert = SSL_get_certificate(s); PUSH_OBJECT(cert, "openssl.x509"); } else if (strcmp(what, "verify_result") == 0) { long l = SSL_get_verify_result(s); lua_pushinteger(L, l); } else if (strcmp(what, "version") == 0) { lua_pushstring(L, SSL_get_version(s)); } else if (strcmp(what, "state") == 0) { lua_pushinteger(L, SSL_state(s)); } else if (strcmp(what, "hostname") == 0) { lua_pushstring(L, SSL_get_servername(s, TLSEXT_NAMETYPE_host_name)); } else luaL_argerror(L, i, "can't understant"); } return top - 1; }
static void print_stuff(BIO * bio, SSL * s, int full) { X509 *peer = NULL; char *p; static const char *space = " "; char buf[BUFSIZ]; STACK_OF(X509) * sk; STACK_OF(X509_NAME) * sk2; const SSL_CIPHER *c; X509_NAME *xn; int j, i; unsigned char *exportedkeymat; if (full) { int got_a_chain = 0; sk = SSL_get_peer_cert_chain(s); if (sk != NULL) { got_a_chain = 1; /* we don't have it for SSL2 * (yet) */ BIO_printf(bio, "---\nCertificate chain\n"); for (i = 0; i < sk_X509_num(sk); i++) { X509_NAME_oneline(X509_get_subject_name( sk_X509_value(sk, i)), buf, sizeof buf); BIO_printf(bio, "%2d s:%s\n", i, buf); X509_NAME_oneline(X509_get_issuer_name( sk_X509_value(sk, i)), buf, sizeof buf); BIO_printf(bio, " i:%s\n", buf); if (c_showcerts) PEM_write_bio_X509(bio, sk_X509_value(sk, i)); } } BIO_printf(bio, "---\n"); peer = SSL_get_peer_certificate(s); if (peer != NULL) { BIO_printf(bio, "Server certificate\n"); if (!(c_showcerts && got_a_chain)) /* Redundant if we * showed the whole * chain */ PEM_write_bio_X509(bio, peer); X509_NAME_oneline(X509_get_subject_name(peer), buf, sizeof buf); BIO_printf(bio, "subject=%s\n", buf); X509_NAME_oneline(X509_get_issuer_name(peer), buf, sizeof buf); BIO_printf(bio, "issuer=%s\n", buf); } else BIO_printf(bio, "no peer certificate available\n"); sk2 = SSL_get_client_CA_list(s); if ((sk2 != NULL) && (sk_X509_NAME_num(sk2) > 0)) { BIO_printf(bio, "---\nAcceptable client certificate CA names\n"); for (i = 0; i < sk_X509_NAME_num(sk2); i++) { xn = sk_X509_NAME_value(sk2, i); X509_NAME_oneline(xn, buf, sizeof(buf)); BIO_write(bio, buf, strlen(buf)); BIO_write(bio, "\n", 1); } } else { BIO_printf(bio, "---\nNo client certificate CA names sent\n"); } p = SSL_get_shared_ciphers(s, buf, sizeof buf); if (p != NULL) { /* * This works only for SSL 2. In later protocol * versions, the client does not know what other * ciphers (in addition to the one to be used in the * current connection) the server supports. */ BIO_printf(bio, "---\nCiphers common between both SSL endpoints:\n"); j = i = 0; while (*p) { if (*p == ':') { BIO_write(bio, space, 15 - j % 25); i++; j = 0; BIO_write(bio, ((i % 3) ? " " : "\n"), 1); } else { BIO_write(bio, p, 1); j++; } p++; } BIO_write(bio, "\n", 1); } BIO_printf(bio, "---\nSSL handshake has read %ld bytes and written %ld bytes\n", BIO_number_read(SSL_get_rbio(s)), BIO_number_written(SSL_get_wbio(s))); } BIO_printf(bio, (SSL_cache_hit(s) ? "---\nReused, " : "---\nNew, ")); c = SSL_get_current_cipher(s); BIO_printf(bio, "%s, Cipher is %s\n", SSL_CIPHER_get_version(c), SSL_CIPHER_get_name(c)); if (peer != NULL) { EVP_PKEY *pktmp; pktmp = X509_get_pubkey(peer); BIO_printf(bio, "Server public key is %d bit\n", EVP_PKEY_bits(pktmp)); EVP_PKEY_free(pktmp); } BIO_printf(bio, "Secure Renegotiation IS%s supported\n", SSL_get_secure_renegotiation_support(s) ? "" : " NOT"); /* Compression is not supported and will always be none. */ BIO_printf(bio, "Compression: NONE\n"); BIO_printf(bio, "Expansion: NONE\n"); #ifdef SSL_DEBUG { /* Print out local port of connection: useful for debugging */ int sock; struct sockaddr_in ladd; socklen_t ladd_size = sizeof(ladd); sock = SSL_get_fd(s); getsockname(sock, (struct sockaddr *) & ladd, &ladd_size); BIO_printf(bio_c_out, "LOCAL PORT is %u\n", ntohs(ladd.sin_port)); } #endif #if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) if (next_proto.status != -1) { const unsigned char *proto; unsigned int proto_len; SSL_get0_next_proto_negotiated(s, &proto, &proto_len); BIO_printf(bio, "Next protocol: (%d) ", next_proto.status); BIO_write(bio, proto, proto_len); BIO_write(bio, "\n", 1); } #endif #ifndef OPENSSL_NO_SRTP { SRTP_PROTECTION_PROFILE *srtp_profile = SSL_get_selected_srtp_profile(s); if (srtp_profile) BIO_printf(bio, "SRTP Extension negotiated, profile=%s\n", srtp_profile->name); } #endif SSL_SESSION_print(bio, SSL_get_session(s)); if (keymatexportlabel != NULL) { BIO_printf(bio, "Keying material exporter:\n"); BIO_printf(bio, " Label: '%s'\n", keymatexportlabel); BIO_printf(bio, " Length: %i bytes\n", keymatexportlen); exportedkeymat = malloc(keymatexportlen); if (exportedkeymat != NULL) { if (!SSL_export_keying_material(s, exportedkeymat, keymatexportlen, keymatexportlabel, strlen(keymatexportlabel), NULL, 0, 0)) { BIO_printf(bio, " Error\n"); } else { BIO_printf(bio, " Keying material: "); for (i = 0; i < keymatexportlen; i++) BIO_printf(bio, "%02X", exportedkeymat[i]); BIO_printf(bio, "\n"); } free(exportedkeymat); } } BIO_printf(bio, "---\n"); if (peer != NULL) X509_free(peer); /* flush, or debugging output gets mixed with http response */ (void) BIO_flush(bio); }
static int ssl_do(struct st_VioSSLFd *ptr, Vio *vio, long timeout, ssl_handshake_func_t func, unsigned long *ssl_errno_holder) { int r; SSL *ssl; my_socket sd= mysql_socket_getfd(vio->mysql_socket); /* Declared here to make compiler happy */ #if !defined(HAVE_YASSL) && !defined(DBUG_OFF) int j, n; #endif DBUG_ENTER("ssl_do"); DBUG_PRINT("enter", ("ptr: 0x%lx, sd: %d ctx: 0x%lx", (long) ptr, sd, (long) ptr->ssl_context)); if (!(ssl= SSL_new(ptr->ssl_context))) { DBUG_PRINT("error", ("SSL_new failure")); *ssl_errno_holder= ERR_get_error(); DBUG_RETURN(1); } DBUG_PRINT("info", ("ssl: 0x%lx timeout: %ld", (long) ssl, timeout)); SSL_clear(ssl); SSL_SESSION_set_timeout(SSL_get_session(ssl), timeout); SSL_set_fd(ssl, sd); #if !defined(HAVE_YASSL) && defined(SSL_OP_NO_COMPRESSION) SSL_set_options(ssl, SSL_OP_NO_COMPRESSION); /* OpenSSL >= 1.0 only */ #elif OPENSSL_VERSION_NUMBER >= 0x00908000L /* workaround for OpenSSL 0.9.8 */ sk_SSL_COMP_zero(SSL_COMP_get_compression_methods()); #endif #if !defined(HAVE_YASSL) && !defined(DBUG_OFF) { STACK_OF(SSL_COMP) *ssl_comp_methods = NULL; ssl_comp_methods = SSL_COMP_get_compression_methods(); n= sk_SSL_COMP_num(ssl_comp_methods); DBUG_PRINT("info", ("Available compression methods:\n")); if (n == 0) DBUG_PRINT("info", ("NONE\n")); else for (j = 0; j < n; j++) { SSL_COMP *c = sk_SSL_COMP_value(ssl_comp_methods, j); DBUG_PRINT("info", (" %d: %s\n", c->id, c->name)); } } #endif /* Since yaSSL does not support non-blocking send operations, use special transport functions that properly handles non-blocking sockets. These functions emulate the behavior of blocking I/O operations by waiting for I/O to become available. */ #ifdef HAVE_YASSL /* Set first argument of the transport functions. */ yaSSL_transport_set_ptr(ssl, vio); /* Set functions to use in order to send and receive data. */ yaSSL_transport_set_recv_function(ssl, yassl_recv); yaSSL_transport_set_send_function(ssl, yassl_send); #endif if ((r= ssl_handshake_loop(vio, ssl, func, ssl_errno_holder)) < 1) { DBUG_PRINT("error", ("SSL_connect/accept failure")); SSL_free(ssl); DBUG_RETURN(1); } /* Connection succeeded. Install new function handlers, change type, set sd to the fd used when connecting and set pointer to the SSL structure */ if (vio_reset(vio, VIO_TYPE_SSL, SSL_get_fd(ssl), ssl, 0)) DBUG_RETURN(1); #ifndef DBUG_OFF { /* Print some info about the peer */ X509 *cert; char buf[512]; DBUG_PRINT("info",("SSL connection succeeded")); DBUG_PRINT("info",("Using cipher: '%s'" , SSL_get_cipher_name(ssl))); if ((cert= SSL_get_peer_certificate (ssl))) { DBUG_PRINT("info",("Peer certificate:")); X509_NAME_oneline(X509_get_subject_name(cert), buf, sizeof(buf)); DBUG_PRINT("info",("\t subject: '%s'", buf)); X509_NAME_oneline(X509_get_issuer_name(cert), buf, sizeof(buf)); DBUG_PRINT("info",("\t issuer: '%s'", buf)); X509_free(cert); } else DBUG_PRINT("info",("Peer does not have certificate.")); if (SSL_get_shared_ciphers(ssl, buf, sizeof(buf))) { DBUG_PRINT("info",("shared_ciphers: '%s'", buf)); } else DBUG_PRINT("info",("no shared ciphers!")); } #endif DBUG_RETURN(0); }
int sslconnect(struct st_VioSSLFd *ptr, Vio *vio, long timeout) { SSL *ssl; my_bool unused; my_bool was_blocking; DBUG_ENTER("sslconnect"); DBUG_PRINT("enter", ("ptr: 0x%lx, sd: %d ctx: 0x%lx", (long) ptr, vio->sd, (long) ptr->ssl_context)); /* Set socket to blocking if not already set */ vio_blocking(vio, 1, &was_blocking); if (!(ssl= SSL_new(ptr->ssl_context))) { DBUG_PRINT("error", ("SSL_new failure")); report_errors(ssl); vio_blocking(vio, was_blocking, &unused); DBUG_RETURN(1); } DBUG_PRINT("info", ("ssl: 0x%lx timeout: %ld", (long) ssl, timeout)); SSL_clear(ssl); SSL_SESSION_set_timeout(SSL_get_session(ssl), timeout); SSL_set_fd(ssl, vio->sd); /* SSL_do_handshake will select between SSL_connect or SSL_accept depending on server or client side */ if (SSL_do_handshake(ssl) < 1) { DBUG_PRINT("error", ("SSL_do_handshake failure")); report_errors(ssl); SSL_free(ssl); vio_blocking(vio, was_blocking, &unused); DBUG_RETURN(1); } /* Connection succeeded. Install new function handlers, change type, set sd to the fd used when connecting and set pointer to the SSL structure */ vio_reset(vio, VIO_TYPE_SSL, SSL_get_fd(ssl), 0, 0); vio->ssl_arg= (void*)ssl; #ifndef DBUG_OFF { /* Print some info about the peer */ X509 *cert; char buf[512]; DBUG_PRINT("info",("SSL connection succeeded")); DBUG_PRINT("info",("Using cipher: '%s'" , SSL_get_cipher_name(ssl))); if ((cert= SSL_get_peer_certificate (ssl))) { DBUG_PRINT("info",("Peer certificate:")); X509_NAME_oneline(X509_get_subject_name(cert), buf, sizeof(buf)); DBUG_PRINT("info",("\t subject: '%s'", buf)); X509_NAME_oneline(X509_get_issuer_name(cert), buf, sizeof(buf)); DBUG_PRINT("info",("\t issuer: '%s'", buf)); X509_free(cert); } else DBUG_PRINT("info",("Peer does not have certificate.")); if (SSL_get_shared_ciphers(ssl, buf, sizeof(buf))) { DBUG_PRINT("info",("shared_ciphers: '%s'", buf)); } else DBUG_PRINT("info",("no shared ciphers!")); } #endif DBUG_RETURN(0); }
void ssl_barf_out(Socket_t S) { BIO *ebio; char buf[BUFSIZ], *p; sock_ssl_t m = XSsl(S); if (tb_errorlevel >= TB_NOTICE) { STACK * sk; if ((ebio=BIO_new(BIO_s_file())) == NULL) { tb_warn("Cannot create new BIO\n"); ERR_print_errors_fp(stderr); return; } BIO_set_fp(ebio,stderr,BIO_NOCLOSE); if ((sk=(STACK *)SSL_get_peer_cert_chain(m->cx)) != NULL) { int i; BIO_printf(ebio,"---\nCertificate chain\n"); for (i=0; i<sk_num(sk); i++) { X509_NAME_oneline(X509_get_subject_name((X509*)sk_value(sk,i)),buf,BUFSIZ); BIO_printf(ebio,"%2d s:%s\n",i,buf); X509_NAME_oneline(X509_get_issuer_name((X509 *)sk_value(sk,i)),buf,BUFSIZ); BIO_printf(ebio," i:%s\n",buf); } } BIO_printf(ebio,"---\n"); if ((m->peer=SSL_get_peer_certificate(m->cx)) != NULL) { BIO_printf(ebio,"Peer certificate\n"); PEM_write_bio_X509(ebio,m->peer); X509_NAME_oneline(X509_get_subject_name(m->peer),buf,BUFSIZ); BIO_printf(ebio,"subject=%s\n",buf); X509_NAME_oneline(X509_get_issuer_name(m->peer),buf,BUFSIZ); BIO_printf(ebio,"issuer=%s\n",buf); } else BIO_printf(ebio,"no peer certificate available\n"); if (((sk=SSL_get_client_CA_list(m->cx)) != NULL) && (sk_num(sk) > 0)) { int i; BIO_printf(ebio,"---\nAcceptable peer certificate CA names\n"); for (i=0; i<sk_num(sk); i++) { m->xn=(X509_NAME *)sk_value(sk,i); X509_NAME_oneline(m->xn,buf,sizeof(buf)); BIO_write(ebio,buf,strlen(buf)); BIO_write(ebio,"\n",1); } } else { BIO_printf(ebio,"---\nNo peer certificate CA names sent\n"); } if ((p=SSL_get_shared_ciphers(m->cx,buf,BUFSIZ)) != NULL) { int i, j; BIO_printf(ebio,"---\nCiphers common between both SSL endpoints:\n"); j=i=0; while (*p) { if (*p != ':') { BIO_write(ebio,p,1);j++; } else { BIO_write(ebio," ",15-j%25);i++;j=0; BIO_write(ebio,((i%3)?" ":"\n"),1); } p++; } BIO_write(ebio,"\n",1); } BIO_printf(ebio, "---\nSSL handshake has read %ld bytes and written %ld bytes\n", BIO_number_read(SSL_get_rbio(m->cx)), BIO_number_written(SSL_get_wbio(m->cx))); BIO_printf(ebio,((m->cx->hit)?"---\nReused, ":"---\nNew, ")); m->sc=SSL_get_current_cipher(m->cx); BIO_printf(ebio,"%s, Cipher is %s\n", SSL_CIPHER_get_version(m->sc),SSL_CIPHER_get_name(m->sc)); if(m->peer != NULL) { EVP_PKEY *pktmp; pktmp = X509_get_pubkey(m->peer); BIO_printf(ebio,"Server public key is %d bit\n", EVP_PKEY_bits(pktmp)); EVP_PKEY_free(pktmp); } SSL_SESSION_print(ebio,SSL_get_session(m->cx)); BIO_printf(ebio,"---\n"); if(m->peer != NULL) X509_free(m->peer); BIO_free(ebio); } }
static int init_ssl_connection(SSL *con) { int i; #ifdef DEBUG const char *str; X509 *peer; static char buf[BUFSIZ]; #endif long verify_error; int err = 0; if ((i = SSL_accept(con)) <= 0) { err = SSL_get_error (con, i); if ((SSL_ERROR_WANT_READ == err) || (SSL_ERROR_WANT_WRITE == err)) fprintf (stderr, "%s: %s(): Error [SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE]\n", \ __FILE__, __func__); if (BIO_sock_should_retry (i)) { BIO_printf(bio_s_out, "DELAY\n"); return 1; } BIO_printf(bio_err, "ERROR\n"); verify_error = SSL_get_verify_result (con); if (verify_error != X509_V_OK) { BIO_printf(bio_err,"verify error:%s\n", X509_verify_cert_error_string(verify_error)); } else { fprintf (stderr, "%s: %s(): X509_V_OK but error\n", __FILE__, __func__); ERR_print_errors (bio_err); } return 0; } #ifdef DEBUG PEM_write_bio_SSL_SESSION (bio_s_out, SSL_get_session (con)); peer = SSL_get_peer_certificate (con); if (NULL != peer) { BIO_printf (bio_s_out, "Client certificate\n"); PEM_write_bio_X509 (bio_s_out, peer); X509_NAME_oneline (X509_get_subject_name (peer), buf, sizeof buf); BIO_printf (bio_s_out, "subject = %s\n", buf); X509_NAME_oneline (X509_get_issuer_name (peer), buf, sizeof buf); BIO_printf (bio_s_out, "issuer = %s\n", buf); X509_free(peer); } if (SSL_get_shared_ciphers (con, buf, sizeof buf) != NULL) BIO_printf (bio_s_out, "Shared ciphers: %s\n", buf); str = SSL_CIPHER_get_name (SSL_get_current_cipher (con)); BIO_printf (bio_s_out, "CIPHER is %s\n", (str != NULL) ? str : "(NONE)"); #endif if (con->hit) BIO_printf (bio_s_out, "Reused session-id\n"); if (SSL_ctrl (con, SSL_CTRL_GET_FLAGS, 0, NULL) & TLS1_FLAGS_TLS_PADDING_BUG) BIO_printf (bio_s_out, "Peer has incorrect TLSv1 block padding\n"); return 1; }