Newer
Older
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
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
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();
Dr. Stephen Henson
committed
BIO_puts(bio_err, "CONNECTION CLOSED BY SERVER\n");
else
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);
#ifndef OPENSSL_NO_HEARTBEATS
else if ((!c_ign_eof) && (cbuf[0] == 'B'))
{
BIO_printf(bio_err,"HEARTBEATING\n");
SSL_heartbeat(con);
cbuf_len=0;
}
#endif
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 !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
if (next_proto.data)
OPENSSL_free(next_proto.data);
#endif
if (ctx != NULL) SSL_CTX_free(ctx);
if (crls)
sk_X509_CRL_pop_free(crls, X509_CRL_free);
if (chain)
sk_X509_pop_free(chain, X509_free);
ssl_excert_free(exc);
Dr. Stephen Henson
committed
if (ssl_args)
sk_OPENSSL_STRING_free(ssl_args);
if (cctx)
SSL_CONF_CTX_free(cctx);
#ifndef OPENSSL_NO_JPAKE
if (jpake_secret && psk_key)
OPENSSL_free(psk_key);
#endif
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;
}
if (bio_c_msg != NULL)
{
BIO_free(bio_c_msg);
bio_c_msg=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);
}
ssl_print_sigalgs(bio, s);
Dr. Stephen Henson
committed
ssl_print_tmp_key(bio, s);
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");
{
/* 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)
# if !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);
}
{
const unsigned char *proto;
unsigned int proto_len;
SSL_get0_alpn_selected(s, &proto, &proto_len);
if (proto_len > 0)
{
BIO_printf(bio, "ALPN protocol: ");
BIO_write(bio, proto, proto_len);
BIO_write(bio, "\n", 1);
}
else
BIO_printf(bio, "No ALPN negotiated\n");
}
{
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);
}
SSL_SESSION_print(bio,SSL_get_session(s));
BIO_printf(bio, "Keying material exporter:\n");
BIO_printf(bio, " Label: '%s'\n", keymatexportlabel);
BIO_printf(bio, " Length: %i bytes\n", keymatexportlen);
exportedkeymat = OPENSSL_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");
BIO_printf(bio,"---\n");
if (peer != NULL)
X509_free(peer);
/* flush, or debugging output gets mixed with http response */
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
static int ocsp_resp_cb(SSL *s, void *arg)
{
const unsigned char *p;
int len;
OCSP_RESPONSE *rsp;
len = SSL_get_tlsext_status_ocsp_resp(s, &p);
BIO_puts(arg, "OCSP response: ");
if (!p)
{
BIO_puts(arg, "no response sent\n");
return 1;
}
rsp = d2i_OCSP_RESPONSE(NULL, &p, len);
if (!rsp)
{
BIO_puts(arg, "response parse error\n");
BIO_dump_indent(arg, (char *)p, len, 4);
return 0;
}
BIO_puts(arg, "\n======================================\n");
OCSP_RESPONSE_print(arg, rsp, 0);
BIO_puts(arg, "======================================\n");
OCSP_RESPONSE_free(rsp);
return 1;
}
static int authz_tlsext_cb(SSL *s, unsigned short ext_type,
const unsigned char *in,
unsigned short inlen, int *al,
void *arg)
if (TLSEXT_TYPE_server_authz == ext_type)
server_provided_server_authz
= (memchr(in, TLSEXT_AUTHZDATAFORMAT_dtcp, inlen) != NULL);
if (TLSEXT_TYPE_client_authz == ext_type)
server_provided_client_authz
= (memchr(in, TLSEXT_AUTHZDATAFORMAT_dtcp, inlen) != NULL);
return 1;
}
static int authz_tlsext_generate_cb(SSL *s, unsigned short ext_type,
const unsigned char **out, unsigned short *outlen,
int *al, void *arg)
{
if (c_auth)
Scott Deboy
committed
/*if auth_require_reneg flag is set, only send extensions if
renegotiation has occurred */
if (!c_auth_require_reneg || (c_auth_require_reneg && SSL_num_renegotiations(s)))
{
*out = auth_ext_data;
*outlen = 1;
return 1;
}
}
return -1;
}
static int suppdata_cb(SSL *s, unsigned short supp_data_type,
const unsigned char *in,
unsigned short inlen, int *al,
void *arg)
{
if (supp_data_type == TLSEXT_SUPPLEMENTALDATATYPE_authz_data)
{
most_recent_supplemental_data = in;
most_recent_supplemental_data_length = inlen;
static int auth_suppdata_generate_cb(SSL *s, unsigned short supp_data_type,
const unsigned char **out,
unsigned short *outlen, int *al, void *arg)
{
if (c_auth && server_provided_client_authz && server_provided_server_authz)
{
Scott Deboy
committed
/*if auth_require_reneg flag is set, only send supplemental data if
renegotiation has occurred */
if (!c_auth_require_reneg
|| (c_auth_require_reneg && SSL_num_renegotiations(s)))
{
Scott Deboy
committed
generated_supp_data = OPENSSL_malloc(10);
memcpy(generated_supp_data, "5432154321", 10);
*out = generated_supp_data;
*outlen = 10;
return 1;
}
}
return -1;
}