Shortened ssl test keys to 1024 to make tests faster

Fixed memory error in SSL code
This commit is contained in:
Olof hagsand 2021-04-05 12:24:05 +02:00
parent 6a64cf5ff1
commit d874a696f7
2 changed files with 77 additions and 53 deletions

View file

@ -234,29 +234,29 @@ buf_write(char *buf,
int retval = -1; int retval = -1;
ssize_t len; ssize_t len;
ssize_t totlen = 0; ssize_t totlen = 0;
int er;
clicon_debug(1, "%s %lu", __FUNCTION__, buflen); clicon_debug(1, "%s %lu", __FUNCTION__, buflen);
while (totlen < buflen){ while (totlen < buflen){
if (ssl){ if (ssl){
clicon_debug(1, "%s ssl", __FUNCTION__);
if ((len = SSL_write(ssl, buf+totlen, buflen-totlen)) <= 0){ if ((len = SSL_write(ssl, buf+totlen, buflen-totlen)) <= 0){
int e = errno; er = errno;
switch (SSL_get_error(ssl, len)){ switch (SSL_get_error(ssl, len)){
case SSL_ERROR_SYSCALL: /* 5 */ case SSL_ERROR_SYSCALL: /* 5 */
if (e == ECONNRESET) {/* Connection reset by peer */ if (er == ECONNRESET) {/* Connection reset by peer */
if (ssl) if (ssl)
SSL_free(ssl); SSL_free(ssl);
close(s); close(s);
clixon_event_unreg_fd(s, restconf_connection); clixon_event_unreg_fd(s, restconf_connection);
goto ok; /* Close socket and ssl */ goto ok; /* Close socket and ssl */
} }
else if (e == EAGAIN){ else if (er == EAGAIN){
clicon_debug(1, "%s write EAGAIN", __FUNCTION__); clicon_debug(1, "%s write EAGAIN", __FUNCTION__);
usleep(10000); usleep(10000);
continue; continue;
} }
else{ else{
clicon_err(OE_RESTCONF, e, "SSL_write %d", e); clicon_err(OE_RESTCONF, er, "SSL_write %d", er);
goto done; goto done;
} }
break; break;
@ -287,6 +287,7 @@ buf_write(char *buf,
ok: ok:
retval = 0; retval = 0;
done: done:
clicon_debug(1, "%s retval:%d", __FUNCTION__, retval);
return retval; return retval;
} }
@ -811,29 +812,38 @@ restconf_ssl_context_configure(clixon_handle h,
return retval; return retval;
} }
/*! Utility function to close restconf server ssl/evhtp socket.
* There are many variants to closing, one could probably make this more generic
* and always use this function, but it is difficult.
*/
static int static int
close_openssl_socket(int s, close_ssl_evhtp_socket(int s,
SSL *ssl) evhtp_connection_t *conn,
int shutdown)
{ {
int retval = -1; int retval = -1;
int ret; int ret;
SSL *ssl;
if (ssl){
// SSL_set_shutdown(ssl, SSL_RECEIVED_SHUTDOWN); ssl = conn->ssl;
/* SSL_shutdown() must not be called if a previous fatal error has occurred on a connection clicon_debug(1, "%s conn-free (%p) 1", __FUNCTION__, conn);
* i.e. if SSL_get_error() has returned SSL_ERROR_SYSCALL or SSL_ERROR_SSL. evhtp_connection_free(conn); /* evhtp */
*/ if (ssl != NULL){
if ((ret = SSL_shutdown(ssl)) < 0){ if (shutdown && (ret = SSL_shutdown(ssl)) < 0){
int e = SSL_get_error(ssl, ret); int e = SSL_get_error(ssl, ret);
clicon_err(OE_SSL, 0, "SSL_shutdown, err:%d", e); clicon_err(OE_SSL, 0, "SSL_shutdown, err:%d", e);
goto done; goto done;
} }
SSL_free(ssl); SSL_free(ssl);
} }
close(s); if (close(s) < 0){
clicon_err(OE_UNIX, errno, "close");
goto done;
}
clixon_event_unreg_fd(s, restconf_connection); clixon_event_unreg_fd(s, restconf_connection);
retval = 0; retval = 0;
done: done:
clicon_debug(1, "%s retval:%d", __FUNCTION__, retval);
return retval; return retval;
} }
@ -842,8 +852,8 @@ close_openssl_socket(int s,
*/ */
static int static int
send_badrequest(clicon_handle h, send_badrequest(clicon_handle h,
int s, int s,
SSL *ssl) SSL *ssl)
{ {
int retval = -1; int retval = -1;
char *buf = "HTTP/1.1 400 Bad Request\r\nConnection: close\r\nContent-Length: 0\r\nContent-Type: text/plain\r\n\r\n"; char *buf = "HTTP/1.1 400 Bad Request\r\nConnection: close\r\nContent-Length: 0\r\nContent-Type: text/plain\r\n\r\n";
@ -877,7 +887,6 @@ restconf_connection(int s,
evhtp_connection_t *conn = NULL; evhtp_connection_t *conn = NULL;
ssize_t n; ssize_t n;
char buf[BUFSIZ]; /* from stdio.h, typically 8K */ char buf[BUFSIZ]; /* from stdio.h, typically 8K */
SSL *ssl;
clicon_handle h; clicon_handle h;
int readmore = 1; int readmore = 1;
@ -907,10 +916,7 @@ restconf_connection(int s,
} }
if (n == 0){ if (n == 0){
clicon_debug(1, "%s n=0 closing socket", __FUNCTION__); clicon_debug(1, "%s n=0 closing socket", __FUNCTION__);
ssl = conn->ssl; if (close_ssl_evhtp_socket(s, conn, 1) < 0)
conn->ssl = NULL;
evhtp_connection_free(conn); /* evhtp */
if (close_openssl_socket(s, ssl) < 0)
goto done; goto done;
goto ok; goto ok;
} }
@ -922,9 +928,13 @@ restconf_connection(int s,
if (send_badrequest(h, s, conn->ssl) < 0) if (send_badrequest(h, s, conn->ssl) < 0)
goto done; goto done;
SSL_free(conn->ssl); SSL_free(conn->ssl);
if (close_openssl_socket(s, NULL) < 0) if (close(s) < 0){
clicon_err(OE_UNIX, errno, "close");
goto done; goto done;
}
clixon_event_unreg_fd(s, restconf_connection);
conn->ssl = NULL; conn->ssl = NULL;
clicon_debug(1, "%s conn-free (%p) 2", __FUNCTION__, conn);
evhtp_connection_free(conn); evhtp_connection_free(conn);
goto ok; goto ok;
} }
@ -937,7 +947,7 @@ restconf_connection(int s,
if ((ev = bufferevent_get_output(conn->bev)) != NULL){ if ((ev = bufferevent_get_output(conn->bev)) != NULL){
buf = (char*)evbuffer_pullup(ev, -1); buf = (char*)evbuffer_pullup(ev, -1);
buflen = evbuffer_get_length(ev); buflen = evbuffer_get_length(ev);
clicon_debug(1, "buf:%s", buf); clicon_debug(1, "%s buf:%s", __FUNCTION__, buf);
if (buflen){ if (buflen){
if (buf_write(buf, buflen, conn->sock, conn->ssl) < 0) if (buf_write(buf, buflen, conn->sock, conn->ssl) < 0)
goto done; goto done;
@ -1053,7 +1063,9 @@ restconf_accept_client(int fd,
evhtp_t *evhtp = NULL; evhtp_t *evhtp = NULL;
evhtp_connection_t *conn; evhtp_connection_t *conn;
int e; int e;
int er;
int readmore; int readmore;
X509 *peercert;
clicon_debug(1, "%s %d", __FUNCTION__, fd); clicon_debug(1, "%s %d", __FUNCTION__, fd);
if (rsock == NULL){ if (rsock == NULL){
@ -1075,11 +1087,13 @@ restconf_accept_client(int fd,
clicon_err(OE_UNIX, errno, "evhtp_connection_new_server"); clicon_err(OE_UNIX, errno, "evhtp_connection_new_server");
goto done; goto done;
} }
clicon_debug(1, "%s conn-new (%p)", __FUNCTION__, conn);
if (rsock->rs_ssl){ if (rsock->rs_ssl){
if ((ssl = SSL_new(rh->rh_ctx)) == NULL){ if ((ssl = SSL_new(rh->rh_ctx)) == NULL){
clicon_err(OE_SSL, 0, "SSL_new"); clicon_err(OE_SSL, 0, "SSL_new");
goto done; goto done;
} }
clicon_debug(1, "%s SSL_new(%p)", __FUNCTION__, ssl);
/* CCL_CTX_set_verify already set, need not call SSL_set_verify again for this server /* CCL_CTX_set_verify already set, need not call SSL_set_verify again for this server
*/ */
/* X509_CHECK_FLAG_NO_WILDCARDS disables wildcard expansion */ /* X509_CHECK_FLAG_NO_WILDCARDS disables wildcard expansion */
@ -1116,27 +1130,33 @@ restconf_accept_client(int fd,
* Both error cases: Call SSL_get_error() with the return value ret * Both error cases: Call SSL_get_error() with the return value ret
*/ */
if ((ret = SSL_accept(ssl)) != 1) { if ((ret = SSL_accept(ssl)) != 1) {
clicon_debug(1, "%s SSL_accept() ret:%d errno:%d", __FUNCTION__, ret, er=errno);
e = SSL_get_error(ssl, ret); e = SSL_get_error(ssl, ret);
switch (e){ switch (e){
case SSL_ERROR_SSL: /* 1 */ case SSL_ERROR_SSL: /* 1 */
clicon_debug(1, "%s SSL_ERROR_SSL (not ssl mesage on ssl socket)", __FUNCTION__); clicon_debug(1, "%s SSL_ERROR_SSL (non-ssl message on ssl socket)", __FUNCTION__);
if (send_badrequest(h, s, NULL) < 0) if (send_badrequest(h, s, NULL) < 0)
goto done; goto done;
SSL_free(ssl); SSL_free(ssl);
if (close_openssl_socket(s, NULL) < 0) if (close(s) < 0){
clicon_err(OE_UNIX, errno, "close");
goto done; goto done;
}
clixon_event_unreg_fd(s, restconf_connection);
conn->ssl = NULL; conn->ssl = NULL;
evhtp_connection_free(conn); clicon_debug(1, "%s conn-free (%p) 3", __FUNCTION__, conn);
evhtp_connection_free(conn); /* evhtp */
goto ok; goto ok;
break; break;
case SSL_ERROR_SYSCALL: /* 5 */ case SSL_ERROR_SYSCALL: /* 5 */
/* look at error stack/return value/errno */ /* Some non-recoverable, fatal I/O error occurred. The OpenSSL error queue
clicon_debug(1, "%s SSL_ERROR_SYSCALL", __FUNCTION__); may contain more information on the error. For socket I/O on Unix systems,
SSL_free(ssl); consult errno for details. If this error occurs then no further I/O
if (close_openssl_socket(s, NULL) < 0) operations should be performed on the connection and SSL_shutdown() must
not be called.*/
clicon_debug(1, "%s SSL_accept() SSL_ERROR_SYSCALL %d", __FUNCTION__, er);
if (close_ssl_evhtp_socket(s, conn, 0) < 0)
goto done; goto done;
conn->ssl = NULL;
evhtp_connection_free(conn);
goto ok; goto ok;
break; break;
case SSL_ERROR_WANT_READ: /* 2 */ case SSL_ERROR_WANT_READ: /* 2 */
@ -1172,21 +1192,25 @@ restconf_accept_client(int fd,
* Alt: set SSL_CTX_set_verify(ctx, SSL_VERIFY_FAIL_IF_NO_PEER_CERT) * Alt: set SSL_CTX_set_verify(ctx, SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
* but then SSL_accept fails. * but then SSL_accept fails.
*/ */
if (restconf_auth_type_get(h) == CLIXON_AUTH_CLIENT_CERTIFICATE && if (restconf_auth_type_get(h) == CLIXON_AUTH_CLIENT_CERTIFICATE){
SSL_get_peer_certificate(ssl) == NULL) { /* Get certificates (if available) */ if ((peercert = SSL_get_peer_certificate(ssl)) != NULL){
if (send_badrequest(h, s, ssl) < 0) X509_free(peercert);
goto done; }
if (ssl){ else { /* Get certificates (if available) */
if ((ret = SSL_shutdown(ssl)) < 0){ if (send_badrequest(h, s, ssl) < 0)
int e = SSL_get_error(ssl, ret); goto done;
clicon_err(OE_SSL, 0, "SSL_shutdown, err:%d", e); clicon_debug(1, "%s conn-free (%p) 5", __FUNCTION__, conn);
goto done; evhtp_connection_free(conn); /* evhtp */
} if (ssl){
SSL_free(ssl); if ((ret = SSL_shutdown(ssl)) < 0){
} int e = SSL_get_error(ssl, ret);
// close(s); Error (56 != 0) in Test14 [No cert: certificate required]: clicon_err(OE_SSL, 0, "SSL_shutdown, err:%d", e);
// clixon_event_unreg_fd(s, restconf_connection); goto done;
goto ok; }
SSL_free(ssl);
}
goto ok;
}
} }
/* Get the actual peer, XXX this maybe could be done in ca-auth client-cert code ? /* Get the actual peer, XXX this maybe could be done in ca-auth client-cert code ?
* Note this _only_ works if SSL_set1_host() was set previously,... * Note this _only_ works if SSL_set1_host() was set previously,...
@ -1627,7 +1651,7 @@ restconf_sig_term(int arg)
clicon_debug(1, "%s", __FUNCTION__); clicon_debug(1, "%s", __FUNCTION__);
if (i++ == 0){ if (i++ == 0){
clicon_log(LOG_NOTICE, "%s: %s: pid: %u Signal %d", /* XYZXYZ */ clicon_log(LOG_NOTICE, "%s: %s: pid: %u Signal %d",
__PROGRAM__, __FUNCTION__, getpid(), arg); __PROGRAM__, __FUNCTION__, getpid(), arg);
} }
else else
@ -1679,7 +1703,7 @@ main(int argc,
cxobj *xrestconf = NULL; cxobj *xrestconf = NULL;
/* In the startup, logs to stderr & debug flag set later */ /* In the startup, logs to stderr & debug flag set later */
clicon_log_init(__PROGRAM__, LOG_INFO, logdst); /* XYZXYZ */ clicon_log_init(__PROGRAM__, LOG_INFO, logdst);
/* Create handle */ /* Create handle */
if ((h = restconf_handle_init()) == NULL) if ((h = restconf_handle_init()) == NULL)
@ -1728,7 +1752,7 @@ main(int argc,
) < 0) ) < 0)
goto done; goto done;
clicon_debug_init(dbg, NULL); clicon_debug_init(dbg, NULL);
clicon_log(LOG_NOTICE, "%s openssl: %u Started", __PROGRAM__, getpid()); /* XYZXYZ */ clicon_log(LOG_NOTICE, "%s openssl: %u Started", __PROGRAM__, getpid());
if (set_signal(SIGTERM, restconf_sig_term, NULL) < 0){ if (set_signal(SIGTERM, restconf_sig_term, NULL) < 0){
clicon_err(OE_DAEMON, errno, "Setting signal"); clicon_err(OE_DAEMON, errno, "Setting signal");
goto done; goto done;

View file

@ -19,7 +19,7 @@ default_crl_days = 9999
default_md = md5 default_md = md5
[ req ] [ req ]
default_bits = 2048 default_bits = 1024
days = 1 days = 1
distinguished_name = req_distinguished_name distinguished_name = req_distinguished_name
attributes = req_attributes attributes = req_attributes
@ -58,7 +58,7 @@ subjectAltName = DNS:clicon.org
EOF EOF
# Generate server key # Generate server key
openssl genrsa -out $srvkey 2048 openssl genrsa -out $srvkey 1024
# Generate CSR (signing request) # Generate CSR (signing request)
openssl req -new -config $dir/srv.cnf -key $srvkey -out $certdir/srv_csr.pem openssl req -new -config $dir/srv.cnf -key $srvkey -out $certdir/srv_csr.pem