Newer
Older
goto end;
}
if (key_file == NULL)
key_file = cert_file;
if (key_file)
key = load_key(bio_err, key_file, key_format, 0, pass, e,
"client certificate private key file");
if (!key)
{
ERR_print_errors(bio_err);
goto end;
}
if (cert_file)
cert = load_cert(bio_err,cert_file,cert_format,
NULL, e, "client certificate file");
if (!cert)
{
ERR_print_errors(bio_err);
goto end;
}
Richard Levitte
committed
if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL
&& !RAND_status())
{
BIO_printf(bio_err,"warning, not much extra random data, consider using the -rand option\n");
}
if (inrand != NULL)
BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
app_RAND_load_files(inrand));
if (bio_c_out == NULL)
{
if (c_quiet && !c_debug && !c_msg)
{
bio_c_out=BIO_new(BIO_s_null());
}
else
{
if (bio_c_out == NULL)
bio_c_out=BIO_new_fp(stdout,BIO_NOCLOSE);
}
}
#ifndef OPENSSL_NO_SRP
if(!app_passwd(bio_err, srppass, NULL, &srp_arg.srppassin, NULL))
{
BIO_printf(bio_err, "Error getting password\n");
goto end;
}
#endif
ctx=SSL_CTX_new(meth);
if (ctx == NULL)
{
ERR_print_errors(bio_err);
goto end;
}
if (vpm)
SSL_CTX_set1_param(ctx, vpm);
#ifndef OPENSSL_NO_ENGINE
if (ssl_client_engine)
{
if (!SSL_CTX_set_client_cert_engine(ctx, ssl_client_engine))
{
BIO_puts(bio_err, "Error setting client auth engine\n");
ERR_print_errors(bio_err);
ENGINE_free(ssl_client_engine);
goto end;
}
ENGINE_free(ssl_client_engine);
}
#endif
#ifndef OPENSSL_NO_PSK
#ifdef OPENSSL_NO_JPAKE
if (psk_key != NULL)
#else
if (psk_key != NULL || jpake_secret)
{
if (c_debug)
BIO_printf(bio_c_out, "PSK key given or JPAKE in use, setting client callback\n");
SSL_CTX_set_psk_client_callback(ctx, psk_client_cb);
}
#endif
if (bugs)
SSL_CTX_set_options(ctx,SSL_OP_ALL|off);
else
SSL_CTX_set_options(ctx,off);
if (clr)
SSL_CTX_clear_options(ctx, clr);
/* DTLS: partial reads end up discarding unread UDP bytes :-(
* Setting read ahead solves this problem.
*/
if (socket_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx, 1);
#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
if (next_proto.data)
SSL_CTX_set_next_proto_select_cb(ctx, next_proto_cb, &next_proto);
#endif
if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback);
if (cipher != NULL)
if(!SSL_CTX_set_cipher_list(ctx,cipher)) {
BIO_printf(bio_err,"error setting cipher list\n");
ERR_print_errors(bio_err);
goto end;
}
#if 0
else
SSL_CTX_set_cipher_list(ctx,getenv("SSL_CIPHER"));
#endif
SSL_CTX_set_verify(ctx,verify,verify_callback);
goto end;
if ((!SSL_CTX_load_verify_locations(ctx,CAfile,CApath)) ||
(!SSL_CTX_set_default_verify_paths(ctx)))
{
/* BIO_printf(bio_err,"error setting default verify locations\n"); */
ERR_print_errors(bio_err);
#ifndef OPENSSL_NO_TLSEXT
tlsextcbp.biodebug = bio_err;
SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
SSL_CTX_set_tlsext_servername_arg(ctx, &tlsextcbp);
#ifndef OPENSSL_NO_SRP
if (srp_arg.srplogin)
{
if (srp_lateuser)
SSL_CTX_set_srp_missing_srp_username_callback(ctx,missing_srp_username_callback);
else if (!SSL_CTX_set_srp_username(ctx, srp_arg.srplogin))
{
BIO_printf(bio_err,"Unable to set SRP username\n");
goto end;
}
srp_arg.msg = c_msg;
srp_arg.debug = c_debug ;
SSL_CTX_set_srp_cb_arg(ctx,&srp_arg);
SSL_CTX_set_srp_client_pwd_callback(ctx, ssl_give_srp_client_pwd_cb);
SSL_CTX_set_srp_strength(ctx, srp_arg.strength);
if (c_msg || c_debug || srp_arg.amp == 0)
SSL_CTX_set_srp_verify_param_callback(ctx, ssl_srp_verify_param_cb);
}
#endif
Dr. Stephen Henson
committed
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
if (sess_in)
{
SSL_SESSION *sess;
BIO *stmp = BIO_new_file(sess_in, "r");
if (!stmp)
{
BIO_printf(bio_err, "Can't open session file %s\n",
sess_in);
ERR_print_errors(bio_err);
goto end;
}
sess = PEM_read_bio_SSL_SESSION(stmp, NULL, 0, NULL);
BIO_free(stmp);
if (!sess)
{
BIO_printf(bio_err, "Can't open session file %s\n",
sess_in);
ERR_print_errors(bio_err);
goto end;
}
SSL_set_session(con, sess);
SSL_SESSION_free(sess);
}
#ifndef OPENSSL_NO_TLSEXT
if (!SSL_set_tlsext_host_name(con,servername))
BIO_printf(bio_err,"Unable to set TLS servername extension.\n");
ERR_print_errors(bio_err);
goto end;
#ifndef OPENSSL_NO_KRB5
Richard Levitte
committed
if (con && (con->kssl_ctx = kssl_ctx_new()) != NULL)
{
kssl_ctx_setstring(con->kssl_ctx, KSSL_SERVER, host);
}
#endif /* OPENSSL_NO_KRB5 */
/* SSL_set_cipher_list(con,"RC4-MD5"); */
#if 0
#ifdef TLSEXT_TYPE_opaque_prf_input
SSL_set_tlsext_opaque_prf_input(con, "Test client", 11);
BIO_printf(bio_err,"connect:errno=%d\n",get_last_socket_error());
SHUTDOWN(s);
goto end;
}
BIO_printf(bio_c_out,"CONNECTED(%08X)\n",s);
#ifdef FIONBIO
if (c_nbio)
{
unsigned long l=1;
BIO_printf(bio_c_out,"turning on non blocking io\n");
if (BIO_socket_ioctl(s,FIONBIO,&l) < 0)
{
ERR_print_errors(bio_err);
goto end;
}
if (c_Pause & 0x01) SSL_set_debug(con, 1);
if ( SSL_version(con) == DTLS1_VERSION)
{
sbio=BIO_new_dgram(s,BIO_NOCLOSE);
if (getsockname(s, &peer, (void *)&peerlen) < 0)
{
BIO_printf(bio_err, "getsockname:errno=%d\n",
get_last_socket_error());
SHUTDOWN(s);
goto end;
}
{
timeout.tv_sec = 0;
timeout.tv_usec = DGRAM_RCV_TIMEOUT;
BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);
timeout.tv_sec = 0;
timeout.tv_usec = DGRAM_SND_TIMEOUT;
BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout);
}
}
else
/* want to do MTU discovery */
BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL);
}
else
sbio=BIO_new_socket(s,BIO_NOCLOSE);
if (nbio_test)
{
BIO *test;
test=BIO_new(BIO_f_nbio_test());
sbio=BIO_push(test,sbio);
}
if (c_debug)
{
SSL_set_debug(con, 1);
BIO_set_callback(sbio,bio_dump_callback);
BIO_set_callback_arg(sbio,(char *)bio_c_out);
if (c_msg)
{
SSL_set_msg_callback(con, msg_cb);
SSL_set_msg_callback_arg(con, bio_c_out);
}
Dr. Stephen Henson
committed
#ifndef OPENSSL_NO_TLSEXT
if (c_tlsextdebug)
{
SSL_set_tlsext_debug_callback(con, tlsext_cb);
SSL_set_tlsext_debug_arg(con, bio_c_out);
}
if (c_status_req)
{
SSL_set_tlsext_status_type(con, TLSEXT_STATUSTYPE_ocsp);
SSL_CTX_set_tlsext_status_cb(ctx, ocsp_resp_cb);
SSL_CTX_set_tlsext_status_arg(ctx, bio_c_out);
#if 0
{
STACK_OF(OCSP_RESPID) *ids = sk_OCSP_RESPID_new_null();
OCSP_RESPID *id = OCSP_RESPID_new();
id->value.byKey = ASN1_OCTET_STRING_new();
id->type = V_OCSP_RESPID_KEY;
ASN1_STRING_set(id->value.byKey, "Hello World", -1);
sk_OCSP_RESPID_push(ids, id);
SSL_set_tlsext_status_ids(con, ids);
}
#endif
}
Dr. Stephen Henson
committed
#endif
if (jpake_secret)
jpake_client_auth(bio_c_out, sbio, jpake_secret);
SSL_set_bio(con,sbio,sbio);
SSL_set_connect_state(con);
/* ok, lets connect */
width=SSL_get_fd(con)+1;
read_tty=1;
write_tty=0;
tty_on=0;
read_ssl=1;
write_ssl=1;
cbuf_len=0;
cbuf_off=0;
sbuf_len=0;
sbuf_off=0;
/* This is an ugly hack that does a lot of assumptions */
/* We do have to handle multi-line responses which may come
in a single packet or not. We therefore have to use
BIO_gets() which does need a buffering BIO. So during
the initial chitchat we do push a buffering BIO into the
chain that is removed again later on to not disturb the
rest of the s_client operation. */
if (starttls_proto == PROTO_SMTP)
{
int foundit=0;
BIO *fbio = BIO_new(BIO_f_buffer());
BIO_push(fbio, sbio);
/* wait for multi-line response to end from SMTP */
do
{
mbuf_len = BIO_gets(fbio,mbuf,BUFSIZZ);
}
while (mbuf_len>3 && mbuf[3]=='-');
/* STARTTLS command requires EHLO... */
BIO_printf(fbio,"EHLO openssl.client.net\r\n");
/* wait for multi-line response to end EHLO SMTP response */
do
{
mbuf_len = BIO_gets(fbio,mbuf,BUFSIZZ);
if (strstr(mbuf,"STARTTLS"))
foundit=1;
}
while (mbuf_len>3 && mbuf[3]=='-');
BIO_pop(fbio);
BIO_free(fbio);
if (!foundit)
BIO_printf(bio_err,
"didn't found starttls in server response,"
" try anyway...\n");
BIO_printf(sbio,"STARTTLS\r\n");
BIO_read(sbio,sbuf,BUFSIZZ);
}
else if (starttls_proto == PROTO_POP3)
Lutz Jänicke
committed
{
BIO_read(sbio,mbuf,BUFSIZZ);
BIO_printf(sbio,"STLS\r\n");
BIO_read(sbio,sbuf,BUFSIZZ);
}
else if (starttls_proto == PROTO_IMAP)
{
int foundit=0;
BIO *fbio = BIO_new(BIO_f_buffer());
BIO_push(fbio, sbio);
BIO_gets(fbio,mbuf,BUFSIZZ);
/* STARTTLS command requires CAPABILITY... */
BIO_printf(fbio,". CAPABILITY\r\n");
/* wait for multi-line CAPABILITY response */
do
{
mbuf_len = BIO_gets(fbio,mbuf,BUFSIZZ);
if (strstr(mbuf,"STARTTLS"))
foundit=1;
}
while (mbuf_len>3 && mbuf[0]!='.');
BIO_pop(fbio);
BIO_free(fbio);
if (!foundit)
BIO_printf(bio_err,
"didn't found STARTTLS in server response,"
" try anyway...\n");
BIO_printf(sbio,". STARTTLS\r\n");
BIO_read(sbio,sbuf,BUFSIZZ);
}
else if (starttls_proto == PROTO_FTP)
{
BIO *fbio = BIO_new(BIO_f_buffer());
BIO_push(fbio, sbio);
/* wait for multi-line response to end from FTP */
do
{
mbuf_len = BIO_gets(fbio,mbuf,BUFSIZZ);
}
while (mbuf_len>3 && mbuf[3]=='-');
BIO_pop(fbio);
BIO_free(fbio);
BIO_printf(sbio,"AUTH TLS\r\n");
BIO_read(sbio,sbuf,BUFSIZZ);
}
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
if (starttls_proto == PROTO_XMPP)
{
int seen = 0;
BIO_printf(sbio,"<stream:stream "
"xmlns:stream='http://etherx.jabber.org/streams' "
"xmlns='jabber:client' to='%s' version='1.0'>", host);
seen = BIO_read(sbio,mbuf,BUFSIZZ);
mbuf[seen] = 0;
while (!strstr(mbuf, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'"))
{
if (strstr(mbuf, "/stream:features>"))
goto shut;
seen = BIO_read(sbio,mbuf,BUFSIZZ);
mbuf[seen] = 0;
}
BIO_printf(sbio, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>");
seen = BIO_read(sbio,sbuf,BUFSIZZ);
sbuf[seen] = 0;
if (!strstr(sbuf, "<proceed"))
goto shut;
mbuf[0] = 0;
}
for (;;)
{
FD_ZERO(&readfds);
FD_ZERO(&writefds);
if ((SSL_version(con) == DTLS1_VERSION) &&
DTLSv1_get_timeout(con, &timeout))
timeoutp = &timeout;
else
timeoutp = NULL;
if (SSL_in_init(con) && !SSL_total_renegotiations(con))
{
in_init=1;
tty_on=0;
}
else
{
tty_on=1;
if (in_init)
{
in_init=0;
#if 0 /* This test doesn't really work as intended (needs to be fixed) */
#ifndef OPENSSL_NO_TLSEXT
if (servername != NULL && !SSL_session_reused(con))
{
BIO_printf(bio_c_out,"Server did %sacknowledge servername extension.\n",tlsextcbp.ack?"":"not ");
}
Dr. Stephen Henson
committed
if (sess_out)
{
BIO *stmp = BIO_new_file(sess_out, "w");
if (stmp)
{
PEM_write_bio_SSL_SESSION(stmp, SSL_get_session(con));
BIO_free(stmp);
}
else
BIO_printf(bio_err, "Error writing session file %s\n", sess_out);
}
print_stuff(bio_c_out,con,full_log);
if (full_log > 0) full_log--;
Lutz Jänicke
committed
if (starttls_proto)
{
BIO_printf(bio_err,"%s",mbuf);
/* We don't need to know any more */
}
if (reconnect)
{
reconnect--;
BIO_printf(bio_c_out,"drop connection and then reconnect\n");
SSL_shutdown(con);
SSL_set_connect_state(con);
SHUTDOWN(SSL_get_fd(con));
goto re_start;
}
}
}
ssl_pending = read_ssl && SSL_pending(con);
if (!ssl_pending)
#if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_NETWARE) && !defined (OPENSSL_SYS_BEOS_R5)
if (tty_on)
{
if (read_tty) openssl_fdset(fileno(stdin),&readfds);
if (write_tty) openssl_fdset(fileno(stdout),&writefds);
}
if (read_ssl)
openssl_fdset(SSL_get_fd(con),&readfds);
if (write_ssl)
openssl_fdset(SSL_get_fd(con),&writefds);
Dr. Stephen Henson
committed
#else
if(!tty_on || !write_tty) {
if (read_ssl)
openssl_fdset(SSL_get_fd(con),&readfds);
Dr. Stephen Henson
committed
if (write_ssl)
openssl_fdset(SSL_get_fd(con),&writefds);
Dr. Stephen Henson
committed
}
#endif
/* printf("mode tty(%d %d%d) ssl(%d%d)\n",
tty_on,read_tty,write_tty,read_ssl,write_ssl);*/
/* Note: under VMS with SOCKETSHR the second parameter
* is currently of type (int *) whereas under other
* systems it is (void *) if you don't have a cast it
* will choke the compiler: if you do have a cast then
* you can either go for (int *) or (void *).
*/
#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
/* Under Windows/DOS we make the assumption that we can
Dr. Stephen Henson
committed
* always write to the tty: therefore if we need to
* write to the tty we just fall through. Otherwise
* we timeout the select every second and see if there
* are any keypresses. Note: this is a hack, in a proper
* Windows application we wouldn't do this.
*/
Dr. Stephen Henson
committed
if(!write_tty) {
if(read_tty) {
tv.tv_sec = 1;
tv.tv_usec = 0;
i=select(width,(void *)&readfds,(void *)&writefds,
NULL,&tv);
#if defined(OPENSSL_SYS_WINCE) || defined(OPENSSL_SYS_MSDOS)
if(!i && (!_kbhit() || !read_tty) ) continue;
#else
if(!i && (!((_kbhit()) || (WAIT_OBJECT_0 == WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 0))) || !read_tty) ) continue;
Dr. Stephen Henson
committed
} else i=select(width,(void *)&readfds,(void *)&writefds,
Dr. Stephen Henson
committed
}
#elif defined(OPENSSL_SYS_NETWARE)
if(!write_tty) {
if(read_tty) {
tv.tv_sec = 1;
tv.tv_usec = 0;
i=select(width,(void *)&readfds,(void *)&writefds,
NULL,&tv);
} else i=select(width,(void *)&readfds,(void *)&writefds,
#elif defined(OPENSSL_SYS_BEOS_R5)
/* Under BeOS-R5 the situation is similar to DOS */
i=0;
stdin_set = 0;
(void)fcntl(fileno(stdin), F_SETFL, O_NONBLOCK);
if(!write_tty) {
if(read_tty) {
tv.tv_sec = 1;
tv.tv_usec = 0;
i=select(width,(void *)&readfds,(void *)&writefds,
NULL,&tv);
if (read(fileno(stdin), sbuf, 0) >= 0)
stdin_set = 1;
if (!i && (stdin_set != 1 || !read_tty))
continue;
} else i=select(width,(void *)&readfds,(void *)&writefds,
Dr. Stephen Henson
committed
#else
Dr. Stephen Henson
committed
#endif
if ( i < 0)
{
BIO_printf(bio_err,"bad select %d\n",
get_last_socket_error());
goto shut;
/* goto end; */
}
if ((SSL_version(con) == DTLS1_VERSION) && DTLSv1_handle_timeout(con) > 0)
{
BIO_printf(bio_err,"TIMEOUT occured\n");
}
if (!ssl_pending && FD_ISSET(SSL_get_fd(con),&writefds))
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
{
k=SSL_write(con,&(cbuf[cbuf_off]),
(unsigned int)cbuf_len);
switch (SSL_get_error(con,k))
{
case SSL_ERROR_NONE:
cbuf_off+=k;
cbuf_len-=k;
if (k <= 0) goto end;
/* we have done a write(con,NULL,0); */
if (cbuf_len <= 0)
{
read_tty=1;
write_ssl=0;
}
else /* if (cbuf_len > 0) */
{
read_tty=0;
write_ssl=1;
}
break;
case SSL_ERROR_WANT_WRITE:
BIO_printf(bio_c_out,"write W BLOCK\n");
write_ssl=1;
read_tty=0;
break;
case SSL_ERROR_WANT_READ:
BIO_printf(bio_c_out,"write R BLOCK\n");
write_tty=0;
read_ssl=1;
write_ssl=0;
break;
case SSL_ERROR_WANT_X509_LOOKUP:
BIO_printf(bio_c_out,"write X BLOCK\n");
break;
case SSL_ERROR_ZERO_RETURN:
if (cbuf_len != 0)
{
BIO_printf(bio_c_out,"shutdown\n");
ret = 0;
goto shut;
}
else
{
read_tty=1;
write_ssl=0;
break;
}
case SSL_ERROR_SYSCALL:
if ((k != 0) || (cbuf_len != 0))
{
BIO_printf(bio_err,"write:errno=%d\n",
get_last_socket_error());
goto shut;
}
else
{
read_tty=1;
write_ssl=0;
}
break;
case SSL_ERROR_SSL:
ERR_print_errors(bio_err);
goto shut;
}
}
#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS_R5)
/* Assume Windows/DOS/BeOS can always write */
Dr. Stephen Henson
committed
else if (!ssl_pending && write_tty)
#else
else if (!ssl_pending && FD_ISSET(fileno(stdout),&writefds))
Dr. Stephen Henson
committed
#endif
#ifdef CHARSET_EBCDIC
ascii2ebcdic(&(sbuf[sbuf_off]),&(sbuf[sbuf_off]),sbuf_len);
#endif
i=raw_write_stdout(&(sbuf[sbuf_off]),sbuf_len);
if (i <= 0)
{
BIO_printf(bio_c_out,"DONE\n");
ret = 0;
goto shut;
/* goto end; */
}
sbuf_len-=i;;
sbuf_off+=i;
if (sbuf_len <= 0)
{
read_ssl=1;
write_tty=0;
}
}
else if (ssl_pending || FD_ISSET(SSL_get_fd(con),&readfds))
#ifdef RENEG
{ static int iiii; if (++iiii == 52) { SSL_renegotiate(con); iiii=0; } }
#endif
k=SSL_read(con,sbuf,1024 /* BUFSIZZ */ );
#else
/* Demo for pending and peek :-) */
k=SSL_read(con,sbuf,16);
{ char zbuf[10240];
printf("read=%d pending=%d peek=%d\n",k,SSL_pending(con),SSL_peek(con,zbuf,10240));
}
#endif
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
switch (SSL_get_error(con,k))
{
case SSL_ERROR_NONE:
if (k <= 0)
goto end;
sbuf_off=0;
sbuf_len=k;
read_ssl=0;
write_tty=1;
break;
case SSL_ERROR_WANT_WRITE:
BIO_printf(bio_c_out,"read W BLOCK\n");
write_ssl=1;
read_tty=0;
break;
case SSL_ERROR_WANT_READ:
BIO_printf(bio_c_out,"read R BLOCK\n");
write_tty=0;
read_ssl=1;
if ((read_tty == 0) && (write_ssl == 0))
write_ssl=1;
break;
case SSL_ERROR_WANT_X509_LOOKUP:
BIO_printf(bio_c_out,"read X BLOCK\n");
break;
case SSL_ERROR_SYSCALL:
ret=get_last_socket_error();
BIO_printf(bio_err,"read:errno=%d\n",ret);
goto shut;
case SSL_ERROR_ZERO_RETURN:
BIO_printf(bio_c_out,"closed\n");
ret=0;
goto shut;
case SSL_ERROR_SSL:
ERR_print_errors(bio_err);
goto shut;
/* break; */
#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
#if defined(OPENSSL_SYS_WINCE) || defined(OPENSSL_SYS_MSDOS)
else if ((_kbhit()) || (WAIT_OBJECT_0 == WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 0)))
else if (_kbhit())
#elif defined(OPENSSL_SYS_BEOS_R5)
else if (stdin_set)
Dr. Stephen Henson
committed
#else
else if (FD_ISSET(fileno(stdin),&readfds))
Dr. Stephen Henson
committed
#endif
if (crlf)
{
int j, lf_num;
i=raw_read_stdin(cbuf,BUFSIZZ/2);
lf_num = 0;
/* both loops are skipped when i <= 0 */
for (j = 0; j < i; j++)
if (cbuf[j] == '\n')
lf_num++;
for (j = i-1; j >= 0; j--)
{
cbuf[j+lf_num] = cbuf[j];
if (cbuf[j] == '\n')
{
lf_num--;
i++;
cbuf[j+lf_num] = '\r';
}
}
assert(lf_num == 0);
}
else
i=raw_read_stdin(cbuf,BUFSIZZ);
if ((!c_ign_eof) && ((i <= 0) || (cbuf[0] == 'Q')))
{
BIO_printf(bio_err,"DONE\n");
ret=0;
goto shut;
}
if ((!c_ign_eof) && (cbuf[0] == 'R'))
SSL_renegotiate(con);
}
else
{
cbuf_len=i;
cbuf_off=0;
#ifdef CHARSET_EBCDIC
ebcdic2ascii(cbuf, cbuf, i);
#endif
}
write_ssl=1;
ret=0;
if (in_init)
print_stuff(bio_c_out,con,full_log);
SSL_shutdown(con);
SHUTDOWN(SSL_get_fd(con));
end:
if (con != NULL)
{
if (prexit != 0)
print_stuff(bio_c_out,con,1);
SSL_free(con);
}
if (ctx != NULL) SSL_CTX_free(ctx);
if (cert)
X509_free(cert);
if (key)
EVP_PKEY_free(key);
if (pass)
OPENSSL_free(pass);
if (cbuf != NULL) { OPENSSL_cleanse(cbuf,BUFSIZZ); OPENSSL_free(cbuf); }
if (sbuf != NULL) { OPENSSL_cleanse(sbuf,BUFSIZZ); OPENSSL_free(sbuf); }
if (mbuf != NULL) { OPENSSL_cleanse(mbuf,BUFSIZZ); OPENSSL_free(mbuf); }
if (bio_c_out != NULL)
{
BIO_free(bio_c_out);
bio_c_out=NULL;
}
apps_shutdown();
OPENSSL_EXIT(ret);
static void print_stuff(BIO *bio, SSL *s, int full)
STACK_OF(X509) *sk;
STACK_OF(X509_NAME) *sk2;
X509_NAME *xn;
int j,i;
const COMP_METHOD *comp, *expansion;
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");
sk_X509_value(sk,i)),buf,sizeof buf);
BIO_printf(bio,"%2d s:%s\n",i,buf);
sk_X509_value(sk,i)),buf,sizeof buf);
BIO_printf(bio," i:%s\n",buf);
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 */
X509_NAME_oneline(X509_get_subject_name(peer),
BIO_printf(bio,"subject=%s\n",buf);
X509_NAME_oneline(X509_get_issuer_name(peer),
BIO_printf(bio,"issuer=%s\n",buf);
}
else
BIO_printf(bio,"no peer certificate available\n");
if ((sk2 != NULL) && (sk_X509_NAME_num(sk2) > 0))
{
BIO_printf(bio,"---\nAcceptable client certificate CA names\n");
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);
}
Dr. Stephen Henson
committed
BIO_printf(bio, "Secure Renegotiation IS%s supported\n",
SSL_get_secure_renegotiation_support(s) ? "" : " NOT");
Richard Levitte
committed
comp=SSL_get_current_compression(s);
expansion=SSL_get_current_expansion(s);
Richard Levitte
committed
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");
#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
if (next_proto.status != -1) {
const unsigned char *proto;