summaryrefslogtreecommitdiffstats
path: root/nanohttp/nanohttp-ssl.c
diff options
context:
space:
mode:
Diffstat (limited to 'nanohttp/nanohttp-ssl.c')
-rw-r--r--nanohttp/nanohttp-ssl.c258
1 files changed, 158 insertions, 100 deletions
diff --git a/nanohttp/nanohttp-ssl.c b/nanohttp/nanohttp-ssl.c
index 79506ea..b9e4af1 100644
--- a/nanohttp/nanohttp-ssl.c
+++ b/nanohttp/nanohttp-ssl.c
@@ -1,5 +1,5 @@
/******************************************************************
-* $Id: nanohttp-ssl.c,v 1.24 2006/04/17 12:26:17 mrcsys Exp $
+* $Id: nanohttp-ssl.c,v 1.25 2006/04/26 17:48:30 mrcsys Exp $
*
* CSOAP Project: A http client/server library in C
* Copyright (C) 2001-2005 Rochester Institute of Technology
@@ -87,43 +87,47 @@ static int enabled = 0;
int (*_hssl_verify_cert) (X509 * cert) = _hssl_dummy_verify_cert;
static void
-_hssl_superseed (void)
+_hssl_superseed(void)
{
int buf[256], i;
- srand (time (NULL));
+ srand(time(NULL));
for (i = 0; i < 256; i++)
{
- buf[i] = rand ();
+ buf[i] = rand();
}
- RAND_seed ((unsigned char *) buf, sizeof (buf));
+ RAND_seed((unsigned char *) buf, sizeof(buf));
return;
}
static char *
-_hssl_get_error(SSL *ssl, int ret)
+_hssl_get_error(SSL * ssl, int ret)
{
switch (SSL_get_error(ssl, ret))
{
- case SSL_ERROR_NONE:
- return "None";
- case SSL_ERROR_ZERO_RETURN:
- return "Zero return";
- case SSL_ERROR_WANT_READ:
- return "Want read";
- case SSL_ERROR_WANT_WRITE:
- return "Want write";
- case SSL_ERROR_WANT_X509_LOOKUP:
- return "Want x509 lookup";
- case SSL_ERROR_SYSCALL:
- return "Syscall failed";
- case SSL_ERROR_SSL:
- return "SSL error";
- default:
- return "Unkown error";
+ case SSL_ERROR_NONE:
+ return "None";
+ case SSL_ERROR_ZERO_RETURN:
+ return "Zero return";
+ case SSL_ERROR_WANT_READ:
+ return "Want read";
+ case SSL_ERROR_WANT_WRITE:
+ return "Want write";
+ case SSL_ERROR_WANT_X509_LOOKUP:
+ return "Want x509 lookup";
+ case SSL_ERROR_SYSCALL:
+ if (ERR_get_error() == 0 && ret == -1)
+ {
+ return strerror(errno);
+ }
+ return "Syscall failed";
+ case SSL_ERROR_SSL:
+ return "SSL error";
+ default:
+ return "Unkown error";
}
}
@@ -144,45 +148,46 @@ _hssl_password_callback(char *buf, int num, int rwflag, void *userdata)
int
-verify_sn (X509 * cert, int who, int nid, char *str)
+verify_sn(X509 * cert, int who, int nid, char *str)
{
char name[256];
char buf[256];
- memset (name, '\0', 256);
- memset (buf, '\0', 256);
+ memset(name, '\0', 256);
+ memset(buf, '\0', 256);
if (who == CERT_SUBJECT)
{
- X509_NAME_oneline (X509_get_subject_name (cert), name, 256);
+ X509_NAME_oneline(X509_get_subject_name(cert), name, 256);
}
else
{
- X509_NAME_oneline (X509_get_issuer_name (cert), name, 256);
+ X509_NAME_oneline(X509_get_issuer_name(cert), name, 256);
}
buf[0] = '/';
- strcat (buf, OBJ_nid2sn (nid));
- strcat (buf, "=");
- strcat (buf, str);
+ strcat(buf, OBJ_nid2sn(nid));
+ strcat(buf, "=");
+ strcat(buf, str);
return strstr(name, buf) ? 1 : 0;
}
void
-hssl_set_hssl_verify_cert( int func(X509 * cert) ){
- _hssl_verify_cert = func;
+hssl_set_hssl_verify_cert(int func(X509 * cert))
+{
+ _hssl_verify_cert = func;
}
static int
_hssl_dummy_verify_cert(X509 * cert)
{
- /* TODO: Make sure that the client is providing a client cert,
- or that the Module is providing the Module cert */
+ /* TODO: Make sure that the client is providing a client cert, or that the
+ Module is providing the Module cert */
/* connect to anyone */
- log_verbose1 ("Validating certificate.");
+ log_verbose1("Validating certificate.");
return 1;
}
@@ -196,18 +201,41 @@ _hssl_cert_verify_callback(int prev_ok, X509_STORE_CTX * ctx)
return 1;
}
*/
- log_verbose2 ("Cert depth = %d", X509_STORE_CTX_get_error_depth(ctx) );
+ log_verbose2("Cert depth = %d", X509_STORE_CTX_get_error_depth(ctx));
if (X509_STORE_CTX_get_error_depth(ctx) == 0)
{
return _hssl_verify_cert(X509_STORE_CTX_get_current_cert(ctx));
}
else
{
- log_verbose1 ("Cert ok (prev)");
+ log_verbose1("Cert ok (prev)");
return prev_ok;
}
}
+void
+hssl_set_certificate(char *c)
+{
+ certificate = c;
+}
+
+void
+hssl_set_certpass(char *c)
+{
+ certpass = c;
+}
+
+void
+hssl_set_ca(char *c)
+{
+ ca_list = c;
+}
+
+void
+hssl_enable(void)
+{
+ enabled = 1;
+}
static void
_hssl_parse_arguments(int argc, char **argv)
@@ -215,21 +243,21 @@ _hssl_parse_arguments(int argc, char **argv)
int i;
- for (i=1; i<argc; i++)
+ for (i = 1; i < argc; i++)
{
- if (!strcmp(argv[i-1], NHTTP_ARG_CERT))
+ if (!strcmp(argv[i - 1], NHTTP_ARG_CERT))
{
certificate = argv[i];
}
- else if (!strcmp(argv[i-1], NHTTP_ARG_CERTPASS))
+ else if (!strcmp(argv[i - 1], NHTTP_ARG_CERTPASS))
{
certpass = argv[i];
}
- else if (!strcmp(argv[i-1], NHTTP_ARG_CA))
+ else if (!strcmp(argv[i - 1], NHTTP_ARG_CA))
{
ca_list = argv[i];
}
- else if (!strcmp(argv[i-1], NHTTP_ARG_HTTPS))
+ else if (!strcmp(argv[i - 1], NHTTP_ARG_HTTPS))
{
enabled = 1;
}
@@ -246,7 +274,7 @@ _hssl_library_init(void)
if (!initialized)
{
- log_verbose1 ("Initializing library");
+ log_verbose1("Initializing library");
SSL_library_init();
@@ -272,24 +300,27 @@ _hssl_server_context_init(void)
if (!(context = SSL_CTX_new(SSLv23_method())))
{
- log_error1 ("Cannot create SSL context");
- return herror_new("_hssl_server_context_init", HSSL_ERROR_CONTEXT, "Unable to create SSL context");
+ log_error1("Cannot create SSL context");
+ return herror_new("_hssl_server_context_init", HSSL_ERROR_CONTEXT,
+ "Unable to create SSL context");
}
- if (!(SSL_CTX_use_certificate_file (context, certificate, SSL_FILETYPE_PEM)))
+ if (!(SSL_CTX_use_certificate_file(context, certificate, SSL_FILETYPE_PEM)))
{
- log_error2 ("Cannot read certificate file: \"%s\"", certificate);
+ log_error2("Cannot read certificate file: \"%s\"", certificate);
SSL_CTX_free(context);
- return herror_new("_hssl_server_context_init", HSSL_ERROR_CERTIFICATE, "Unable to use SSL certificate \"%s\"", certificate);
+ return herror_new("_hssl_server_context_init", HSSL_ERROR_CERTIFICATE,
+ "Unable to use SSL certificate \"%s\"", certificate);
}
SSL_CTX_set_default_passwd_cb(context, _hssl_password_callback);
if (!(SSL_CTX_use_PrivateKey_file(context, certificate, SSL_FILETYPE_PEM)))
{
- log_error2 ("Cannot read key file: \"%s\"", certificate);
- SSL_CTX_free(context);
- return herror_new("_hssl_server_context_init", HSSL_ERROR_PEM, "Unable to use private key");
+ log_error2("Cannot read key file: \"%s\"", certificate);
+ SSL_CTX_free(context);
+ return herror_new("_hssl_server_context_init", HSSL_ERROR_PEM,
+ "Unable to use private key");
}
if (ca_list != NULL && *ca_list != '\0')
@@ -297,15 +328,17 @@ _hssl_server_context_init(void)
if (!(SSL_CTX_load_verify_locations(context, ca_list, NULL)))
{
SSL_CTX_free(context);
- log_error2 ("Cannot read CA list: \"%s\"", ca_list);
- return herror_new("_hssl_server_context_init", HSSL_ERROR_CA_LIST, "Unable to read certification authorities \"%s\"");
+ log_error2("Cannot read CA list: \"%s\"", ca_list);
+ return herror_new("_hssl_server_context_init", HSSL_ERROR_CA_LIST,
+ "Unable to read certification authorities \"%s\"");
}
- SSL_CTX_set_client_CA_list (context, SSL_load_client_CA_file (ca_list));
- log_verbose1 ("Certification authority contacted");
+ SSL_CTX_set_client_CA_list(context, SSL_load_client_CA_file(ca_list));
+ log_verbose1("Certification authority contacted");
}
- SSL_CTX_set_verify(context, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, _hssl_cert_verify_callback);
+ SSL_CTX_set_verify(context, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE,
+ _hssl_cert_verify_callback);
log_verbose1("Certificate verification callback registered");
SSL_CTX_set_mode(context, SSL_MODE_AUTO_RETRY);
@@ -366,12 +399,12 @@ hssl_enabled(void)
herror_t
-hssl_client_ssl(hsocket_t *sock)
+hssl_client_ssl(hsocket_t * sock)
{
SSL *ssl;
int ret;
- log_verbose1 ("Starting SSL client initialization");
+ log_verbose1("Starting SSL client initialization");
if (!(ssl = SSL_new(context)))
{
@@ -379,46 +412,49 @@ hssl_client_ssl(hsocket_t *sock)
return herror_new("hssl_client_ssl", HSSL_ERROR_CLIENT, "SSL_new failed");
}
- SSL_set_fd (ssl, sock->sock);
+ SSL_set_fd(ssl, sock->sock);
if ((ret = SSL_connect(ssl)) <= 0)
{
herror_t err;
- log_error2 ("SSL connect error (%s)", _hssl_get_error(ssl, -1));
- err = herror_new("hssl_client_ssl", HSSL_ERROR_CONNECT, "SSL_connect failed (%s)", _hssl_get_error(ssl, ret));
- SSL_free (ssl);
+ log_error2("SSL connect error (%s)", _hssl_get_error(ssl, -1));
+ err =
+ herror_new("hssl_client_ssl", HSSL_ERROR_CONNECT,
+ "SSL_connect failed (%s)", _hssl_get_error(ssl, ret));
+ SSL_free(ssl);
return err;
}
- /* SSL_connect should take care of this for us.
- if (SSL_get_peer_certificate(ssl) == NULL)
- {
- log_error1("No certificate provided");
- SSL_free(ssl);
- return herror_new("hssl_client_ssl", HSSL_ERROR_CERTIFICATE, "No certificate provided");
- }
+ /* SSL_connect should take care of this for us. if
+ (SSL_get_peer_certificate(ssl) == NULL) { log_error1("No certificate
+ provided"); SSL_free(ssl); return herror_new("hssl_client_ssl",
+ HSSL_ERROR_CERTIFICATE, "No certificate provided"); }
- if (SSL_get_verify_result(ssl) != X509_V_OK)
- {
- log_error1("Certificate did not verify");
- SSL_free(ssl);
- return herror_new("hssl_client_ssl", HSSL_ERROR_CERTIFICATE, "Verfiy certificate failed");
- } */
+ if (SSL_get_verify_result(ssl) != X509_V_OK) { log_error1("Certificate
+ did not verify"); SSL_free(ssl); return herror_new("hssl_client_ssl",
+ HSSL_ERROR_CERTIFICATE, "Verfiy certificate failed"); } */
+
+ log_verbose1("SSL client initialization completed");
- log_verbose1 ("SSL client initialization completed");
-
sock->ssl = ssl;
-
+
return H_OK;
}
+long
+hssl_bio_read(BIO * b, char *out, int outl)
+{
+
+ return hsocket_select_read(b->num, out, outl);;
+}
herror_t
-hssl_server_ssl(hsocket_t *sock)
+hssl_server_ssl(hsocket_t * sock)
{
SSL *ssl;
int ret;
+ BIO *sbio;
if (!enabled)
return H_OK;
@@ -428,18 +464,33 @@ hssl_server_ssl(hsocket_t *sock)
if (!(ssl = SSL_new(context)))
{
log_warn1("SSL_new failed");
- return herror_new("hssl_server_ssl", HSSL_ERROR_SERVER, "Cannot create SSL object");
+ return herror_new("hssl_server_ssl", HSSL_ERROR_SERVER,
+ "Cannot create SSL object");
}
- SSL_set_fd(ssl, sock->sock);
+ /* SSL_set_fd(ssl, sock->sock); */
+
+ sbio = BIO_new_socket(sock->sock, BIO_NOCLOSE);
+
+ if (sbio == NULL)
+ {
+ log_error1("BIO_new_socket failed");
+ return NULL;
+ }
+ // BIO_set_callback(sbio, hssl_bio_cb);
+ sbio->method->bread = hssl_bio_read;
+ SSL_set_bio(ssl, sbio, sbio);
+
if ((ret = SSL_accept(ssl)) <= 0)
{
herror_t err;
- log_error2 ("SSL_accept failed (%s)", _hssl_get_error(ssl, ret));
+ log_error2("SSL_accept failed (%s)", _hssl_get_error(ssl, ret));
- err = herror_new("hssl_server_ssl", HSSL_ERROR_SERVER, "SSL_accept failed (%s)", _hssl_get_error(ssl, ret));
- SSL_free (ssl);
+ err =
+ herror_new("hssl_server_ssl", HSSL_ERROR_SERVER,
+ "SSL_accept failed (%s)", _hssl_get_error(ssl, ret));
+ SSL_free(ssl);
return err;
}
@@ -451,21 +502,20 @@ hssl_server_ssl(hsocket_t *sock)
void
-hssl_cleanup(hsocket_t *sock)
+hssl_cleanup(hsocket_t * sock)
{
if (sock->ssl)
{
- SSL_shutdown (sock->ssl);
- SSL_free (sock->ssl);
+ SSL_shutdown(sock->ssl);
+ SSL_free(sock->ssl);
sock->ssl = NULL;
}
return;
}
-
herror_t
-hssl_read(hsocket_t *sock, char *buf, size_t len, size_t *received)
+hssl_read(hsocket_t * sock, char *buf, size_t len, size_t * received)
{
int count;
@@ -474,12 +524,15 @@ hssl_read(hsocket_t *sock, char *buf, size_t len, size_t *received)
if (sock->ssl)
{
if ((count = SSL_read(sock->ssl, buf, len)) == -1)
- return herror_new("SSL_read", HSOCKET_ERROR_RECEIVE, "SSL_read failed (%s)", _hssl_get_error(sock->ssl, count));
+ return herror_new("SSL_read", HSOCKET_ERROR_RECEIVE,
+ "SSL_read failed (%s)", _hssl_get_error(sock->ssl,
+ count));
}
else
{
- if ((count = recv(sock->sock, buf, len, 0)) == -1)
- return herror_new("hssl_read", HSOCKET_ERROR_RECEIVE, "recv failed (%s)", strerror(errno));
+ if ((count = hsocket_select_read(sock->sock, buf, len)) == -1)
+ return herror_new("hssl_read", HSOCKET_ERROR_RECEIVE,
+ "recv failed (%s)", strerror(errno));
}
*received = count;
@@ -488,7 +541,7 @@ hssl_read(hsocket_t *sock, char *buf, size_t len, size_t *received)
herror_t
-hssl_write(hsocket_t *sock, const char *buf, size_t len, size_t *sent)
+hssl_write(hsocket_t * sock, const char *buf, size_t len, size_t * sent)
{
int count;
@@ -497,12 +550,15 @@ hssl_write(hsocket_t *sock, const char *buf, size_t len, size_t *sent)
if (sock->ssl)
{
if ((count = SSL_write(sock->ssl, buf, len)) == -1)
- return herror_new("SSL_write", HSOCKET_ERROR_SEND, "SSL_write failed (%s)", _hssl_get_error(sock->ssl, count));
+ return herror_new("SSL_write", HSOCKET_ERROR_SEND,
+ "SSL_write failed (%s)", _hssl_get_error(sock->ssl,
+ count));
}
else
{
if ((count = send(sock->sock, buf, len, 0)) == -1)
- return herror_new("hssl_write", HSOCKET_ERROR_SEND, "send failed (%s)", strerror(errno));
+ return herror_new("hssl_write", HSOCKET_ERROR_SEND, "send failed (%s)",
+ strerror(errno));
}
*sent = count;
@@ -512,24 +568,26 @@ hssl_write(hsocket_t *sock, const char *buf, size_t len, size_t *sent)
#else
herror_t
-hssl_read(hsocket_t *sock, char *buf, size_t len, size_t *received)
+hssl_read(hsocket_t * sock, char *buf, size_t len, size_t * received)
{
int count;
- if ((count = recv(sock->sock, buf, len, 0)) == -1)
- return herror_new("hssl_read", HSOCKET_ERROR_RECEIVE, "recv failed (%s)", strerror(errno));
+ if ((count = hsocket_select_read(sock->sock, buf, len)) == -1)
+ return herror_new("hssl_read", HSOCKET_ERROR_RECEIVE, "recv failed (%s)",
+ strerror(errno));
*received = count;
return H_OK;
}
herror_t
-hssl_write(hsocket_t *sock, const char *buf, size_t len, size_t *sent)
+hssl_write(hsocket_t * sock, const char *buf, size_t len, size_t * sent)
{
int count;
if ((count = send(sock->sock, buf, len, 0)) == -1)
- return herror_new("hssl_write", HSOCKET_ERROR_SEND, "send failed (%s)", strerror(errno));
+ return herror_new("hssl_write", HSOCKET_ERROR_SEND, "send failed (%s)",
+ strerror(errno));
*sent = count;
return H_OK;
}