diff options
Diffstat (limited to 'c/src/libnetworking/rtems_webserver/websSSL.c')
-rw-r--r-- | c/src/libnetworking/rtems_webserver/websSSL.c | 706 |
1 files changed, 0 insertions, 706 deletions
diff --git a/c/src/libnetworking/rtems_webserver/websSSL.c b/c/src/libnetworking/rtems_webserver/websSSL.c deleted file mode 100644 index 6c2e4ce5da..0000000000 --- a/c/src/libnetworking/rtems_webserver/websSSL.c +++ /dev/null @@ -1,706 +0,0 @@ -/* - * websSSL.c -- SSL envrionment creation - * - * Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved. - * - * See the file "license.txt" for usage and redistribution license requirements - * - * $Id$ - */ - -/******************************** Description *********************************/ - -/* - * This module implements a patch into SSL implementations for the webs - * module. - */ - -/********************************* Includes ***********************************/ - -#include "wsIntrn.h" -#include "webs.h" -#include "websSSL.h" - -/******************************* Definitions **********************************/ - -#define DEFAULT_CERT_FILE "./server.pem" -#define DEFAULT_KEY_FILE "./certs/cakey.pem" -#define DEFAULT_CA_FILE "./certs/cacert.pem" -#define DEFAULT_CA_PATH "./certs/" -#define SSL_PORT 443 - -/* - * Define the components of the apps_startup() macro - */ - -#ifdef SIGPIPE -#define do_pipe_sig() signal(SIGPIPE,SIG_IGN) -#else -#define do_pipe_sig() -#endif - -#ifdef OPENSSL -#define SSLC_add_all_algorithms() SSLeay_add_all_algorithms() -#else -extern void SSLC_add_all_algorithms(void); -#endif - -/* - * Define the apps_startup() macro - */ - -# if defined(MSDOS) || defined(WIN16) || defined(WIN32) -# ifdef _O_BINARY -# define apps_startup() \ - _fmode=_O_BINARY; do_pipe_sig(); CRYPTO_malloc_init(); \ - SSLC_add_all_algorithms() -# else -# define apps_startup() \ - _fmode=O_BINARY; do_pipe_sig(); CRYPTO_malloc_init(); \ - SSLC_add_all_algorithms() -# endif -# else -# define apps_startup() do_pipe_sig(); SSLC_add_all_algorithms(); -# endif - -/*************************** Forward Declarations *****************************/ - -static int websSSLSetCertStuff(SSL_CTX *ctx, - char *cert_file, - char *key_file); -static int websSSLVerifyCallback(int ok, X509_STORE_CTX *ctx); -static RSA *websSSLTempRSACallback(SSL *s, int is_export, int keylength); - -static int websSSLReadEvent (webs_t wp); -static int websSSLAccept(int sid, char *ipaddr, int port, int listenSid); -static void websSSLSocketEvent(int sid, int mask, int data); - -/*********************************** Locals ***********************************/ - -static int sslListenSock = -1; /* Listen socket */ -static SSL_CTX *sslctx = NULL; - -/******************************************************************************/ -/* - * Start up the SSL Context for the application, and start a listen on the - * SSL port (usually 443, and defined by SSL_PORT) - * Return 0 on success, -1 on failure. - */ - -int websSSLOpen() -{ - char *certFile, *keyFile, *CApath, *CAfile; - SSL_METHOD *meth; - -/* - * Install and initialize the SSL library - */ - apps_startup(); - trace(7, T("SSL: Initializing SSL\n")); - -#ifdef SSLC - SSL_library_init(); -#endif - - SSL_load_error_strings(); - -#ifdef OPENSSL - SSLeay_add_ssl_algorithms(); -#endif - -/* - * Important! Enable both SSL versions 2 and 3 - */ - meth = SSLv23_server_method(); - sslctx = SSL_CTX_new(meth); - - a_assert(sslctx); - - if (sslctx == NULL) { - trace(2, T("SSL: Unable to create SSL context!\n")); - return -1; - } - -/* - * Adjust some SSL Context variables - */ - SSL_CTX_set_quiet_shutdown(sslctx, 1); - SSL_CTX_set_options(sslctx, 0); - SSL_CTX_sess_set_cache_size(sslctx, 128); - -/* - * Set the certificate verification locations - */ - CApath = DEFAULT_CA_PATH; - CAfile = DEFAULT_CA_FILE; - if ((!SSL_CTX_load_verify_locations(sslctx, CAfile, CApath)) || - (!SSL_CTX_set_default_verify_paths(sslctx))) { - trace(2, T("SSL: Unable to set cert verification locations!\n")); - websSSLClose(); - return -1; - } - -/* - * Set the certificate and key files for the SSL context - */ - certFile = DEFAULT_CERT_FILE; - keyFile = NULL; - if (websSSLSetCertStuff(sslctx, certFile, keyFile) != 0) { - websSSLClose(); - return -1; - } - -/* - * Set the RSA callback for the SSL context - */ - SSL_CTX_set_tmp_rsa_callback(sslctx, websSSLTempRSACallback); - -/* - * Set the verification callback for the SSL context - */ - SSL_CTX_set_verify(sslctx, SSL_VERIFY_NONE, websSSLVerifyCallback); - -/* - * Set the certificate authority list for the client - */ - SSL_CTX_set_client_CA_list(sslctx, SSL_load_client_CA_file(CAfile)); - -/* - * Open the socket - */ - sslListenSock = socketOpenConnection(NULL, SSL_PORT, - websSSLAccept, SOCKET_BLOCK); - - if (sslListenSock < 0) { - trace(2, T("SSL: Unable to open SSL socket on port <%d>!\n"), - SSL_PORT); - return -1; - } - - return 0; -} - -/******************************************************************************/ -/* - * Return TRUE if websSSL has been opened - */ - -int websSSLIsOpen() -{ - return (sslListenSock != -1); -} - -/******************************************************************************/ -/* - * Stops the SSL - */ - -void websSSLClose() -{ - trace(7, T("SSL: Closing SSL\n")); - - if (sslctx != NULL) { - SSL_CTX_free(sslctx); - sslctx = NULL; - } - - if (sslListenSock != -1) { - socketCloseConnection(sslListenSock); - sslListenSock = -1; - } - -#ifdef SSLC - SSL_library_cleanup(); -#endif -} - -/******************************************************************************/ -/* - * Accept a connection - */ - -int websSSLAccept(int sid, char *ipaddr, int port, int listenSid) -{ - webs_t wp; - int wid; - - a_assert(ipaddr && *ipaddr); - a_assert(sid >= 0); - a_assert(port >= 0); - -/* - * Allocate a new handle for this accepted connection. This will allocate - * a webs_t structure in the webs[] list - */ - if ((wid = websAlloc(sid)) < 0) { - return -1; - } - wp = webs[wid]; - a_assert(wp); - wp->listenSid = listenSid; - - ascToUni(wp->ipaddr, ipaddr, min(sizeof(wp->ipaddr), strlen(ipaddr)+1)); - -/* - * Check if this is a request from a browser on this system. This is useful - * to know for permitting administrative operations only for local access - */ - if (gstrcmp(wp->ipaddr, T("127.0.0.1")) == 0 || - gstrcmp(wp->ipaddr, websIpaddr) == 0 || - gstrcmp(wp->ipaddr, websHost) == 0) { - wp->flags |= WEBS_LOCAL_REQUEST; - } -/* - * Since the acceptance came in on this channel, it must be secure - */ - wp->flags |= WEBS_SECURE; - -/* - * Arrange for websSocketEvent to be called when read data is available - */ - socketCreateHandler(sid, SOCKET_READABLE, websSSLSocketEvent, (int) wp); - -/* - * Arrange for a timeout to kill hung requests - */ - wp->timeout = emfSchedCallback(WEBS_TIMEOUT, websTimeout, (void *) wp); - trace(8, T("webs: accept request\n")); - return 0; -} - -/******************************************************************************/ -/* - * The webs socket handler. Called in response to I/O. We just pass control - * to the relevant read or write handler. A pointer to the webs structure - * is passed as an (int) in iwp. - */ - -static void websSSLSocketEvent(int sid, int mask, int iwp) -{ - webs_t wp; - - wp = (webs_t) iwp; - a_assert(wp); - - if (! websValid(wp)) { - return; - } - - if (mask & SOCKET_READABLE) { - websSSLReadEvent(wp); - } - if (mask & SOCKET_WRITABLE) { - if (wp->writeSocket) { - (*wp->writeSocket)(wp); - } - } -} - -/******************************************************************************/ -/* - * Handler for SSL Read Events - */ - -static int websSSLReadEvent (webs_t wp) -{ - int ret, sock; - socket_t *sptr; - SSL *ssl; - BIO *bio, *bioSSL, *bioSock; -#ifdef DEV - const char *ciphers; -#endif - - a_assert (wp); - a_assert(websValid(wp)); - - sptr = socketPtr(wp->sid); - a_assert(sptr); - - sock = sptr->sock; - -/* - * Create a new BIO and SSL session for this web request - */ - bio = BIO_new(BIO_f_buffer()); - a_assert(bio); - - if (!BIO_set_write_buffer_size(bio, 128)) { - return -1; - } - - ssl = (SSL *) SSL_new(sslctx); - a_assert(ssl); - - if (ssl == NULL) { - return -1; - } - - SSL_set_session(ssl, NULL); - - bioSSL = BIO_new(BIO_f_ssl()); - a_assert(bioSSL); - - bioSock = BIO_new_socket(sock, BIO_NOCLOSE); - a_assert(bioSock); - - SSL_set_bio(ssl, bioSock, bioSock); - SSL_set_accept_state(ssl); - - ret = BIO_set_ssl(bioSSL, ssl, BIO_CLOSE); - BIO_push(bio, bioSSL); - -#ifdef DEV - ciphers = SSL_get_cipher_list(ssl, 10); -#endif - -/* - * Create the SSL data structure in the wp. - */ -#ifdef WEBS_SSL_SUPPORT - wp->wsp = balloc(B_L, sizeof(websSSL_t)); - a_assert (wp->wsp); - (wp->wsp)->bio = bio; - (wp->wsp)->ssl = ssl; -#endif - -/* - * Call the default Read Event - */ - websReadEvent(wp); - - return ret; -} - - -/******************************************************************************/ -/* - * SSL Verification Callback - */ - -static int sslVerifyDepth = 0; -static int sslVerifyError = X509_V_OK; - -int websSSLVerifyCallback(int ok, X509_STORE_CTX *ctx) -{ - char buf[256]; - X509 *errCert; - int err; - int depth; - - errCert = X509_STORE_CTX_get_current_cert(ctx); - err = X509_STORE_CTX_get_error(ctx); - depth = X509_STORE_CTX_get_error_depth(ctx); - - X509_NAME_oneline(X509_get_subject_name(errCert), buf, 256); - - if (!ok) { - if (sslVerifyDepth >= depth) { - ok = 1; - sslVerifyError = X509_V_OK; - } else { - ok=0; - sslVerifyError = X509_V_ERR_CERT_CHAIN_TOO_LONG; - } - } - - switch (err) { - case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: -#ifdef OPENSSL - X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), buf, 256); -#endif - break; - - case X509_V_ERR_CERT_NOT_YET_VALID: - case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: - case X509_V_ERR_CERT_HAS_EXPIRED: - case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: - break; - } - - return ok; -} - -/******************************************************************************/ -/* - * Set the SSL certificate and key for the SSL context - */ - -int websSSLSetCertStuff(SSL_CTX *ctx, char *certFile, char *keyFile) -{ - a_assert (ctx); - a_assert (certFile); - - if (certFile != NULL) { - if (SSL_CTX_use_certificate_file(ctx, certFile, - SSL_FILETYPE_PEM) <= 0) { - trace(2, T("SSL: Unable to set certificate file <%s>\n"), - certFile); - return -1; - } - - if (keyFile == NULL) { - keyFile = certFile; - } - - if (SSL_CTX_use_PrivateKey_file(ctx, keyFile, SSL_FILETYPE_PEM) <= 0) { - trace(2, T("SSL: Unable to set private key file <%s>\n"), - keyFile); - return -1; - } - -/* - * Now we know that a key and cert have been set against - * the SSL context - */ - if (!SSL_CTX_check_private_key(ctx)) { - trace(2, T("SSL: Check of private key file <%s> FAILED!\n"), - keyFile); - return -1; - } - } - - return 0; -} - -/******************************************************************************/ -/* - * Set certificate file for SSL context - */ - -int websSSLSetCertFile(char_t *certFile) -{ - a_assert (sslctx); - a_assert (certFile); - - if (sslctx == NULL) { - return -1; - } - - if (SSL_CTX_use_certificate_file(sslctx, certFile, - SSL_FILETYPE_PEM) <= 0) { - return -1; - } -/* - * Confirm that the certificate and the private key jive. - */ - if (!SSL_CTX_check_private_key(sslctx)) { - return -1; - } - - return 0; -} - -/******************************************************************************/ -/* - * Set key file for SSL context - */ - -int websSSLSetKeyFile(char_t *keyFile) -{ - a_assert (sslctx); - a_assert (keyFile); - - if (sslctx == NULL) { - return -1; - } - - if (SSL_CTX_use_PrivateKey_file(sslctx, keyFile, SSL_FILETYPE_PEM) <= 0) { - return -1; - } -/* - * Confirm that the certificate and the private key jive. - */ - if (!SSL_CTX_check_private_key(sslctx)) { - return -1; - } - - return 0; -} - -#ifdef SSLC -extern RSA *RSA_new(void); -#endif - -/******************************************************************************/ -/* - * the Temporary RSA callback - */ - -static RSA *websSSLTempRSACallback(SSL *ssl, int isExport, int keyLength) -{ - static RSA *rsaTemp = NULL; - - if (rsaTemp == NULL) { - -#ifdef OPENSSL - rsaTemp = RSA_generate_key(keyLength, RSA_F4, NULL, NULL); -#endif - -#ifdef SSLC - rsaTemp = RSA_new(); -#endif - - } - - return rsaTemp; -} - -/******************************************************************************/ -/* - * Free SSL resources - */ - -int websSSLFree(websSSL_t *wsp) -{ - if (wsp == NULL) { - return -1; - } - -/* - * Make sure we re-use sessions - */ - if (wsp->ssl != NULL) { - SSL_set_shutdown(wsp->ssl, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); - } - - if (wsp->bio != NULL) { - BIO_free_all(wsp->bio); - } - - bfree(B_L, wsp); - - return 0; -} - -/******************************************************************************/ -/* - * Return Eof for the SSL BIO - */ - -int websSSLEof(websSSL_t *wsp) -{ - a_assert(wsp); - - if ((wsp == NULL) || (wsp->bio == NULL)) { - return -1; - } - - return BIO_eof(wsp->bio); -} - -/******************************************************************************/ -/* - * Perform a read of the SSL BIO - */ - -int websSSLRead(websSSL_t *wsp, char_t *buf, int len) -{ - a_assert(wsp); - a_assert(buf); - - if ((wsp == NULL) || (wsp->bio == NULL)) { - return -1; - } - - return BIO_read(wsp->bio, buf, len); -} - -/******************************************************************************/ -/* - * Perform a gets of the SSL BIO, returning an balloc'ed string - */ - -#define BUF_BLOCK 256 - -int websSSLGets(websSSL_t *wsp, char_t **buf) -{ - int rc, len, lenBuf; - char c; - - a_assert(wsp); - a_assert(buf); - - lenBuf = 0; - len = 0; - - if ((wsp == NULL) || (wsp->bio == NULL)) { - return -1; - } - - while (1) { - - if ((rc = BIO_read(wsp->bio, &c, 1)) < 0) { - return rc; - } - - if (rc == 0) { -/* - * If there is a partial line and we are at EOF, pretend we saw a '\n' - */ - if (len > 0 && BIO_eof(wsp->bio)) { - c = '\n'; - } else { - return -1; - } - } -/* - * If a newline is seen, return the data excluding the new line to the - * caller. If carriage return is seen, just eat it. - */ - if (c == '\n') { - if ((len > 0) && (len < lenBuf)) { - (*buf)[len] = 0; - } - return len; - } else if (c == '\r') { - continue; - } -/* - * Append character to buf - */ - if (len >= lenBuf) { - lenBuf += BUF_BLOCK; - *buf = brealloc(B_L, *buf, lenBuf); - } - - a_assert(*buf); - (*buf)[len] = c; - len++; - } -} - -/******************************************************************************/ -/* - * Perform a write to the SSL BIO - */ - -int websSSLWrite(websSSL_t *wsp, char_t *buf, int len) -{ - a_assert(wsp); - a_assert(buf); - - if ((wsp == NULL) || (wsp->bio == NULL)) { - return -1; - } - - return BIO_write(wsp->bio, buf, len); -} - -/******************************************************************************/ -/* - * Perform a flush of the SSL BIO - */ - -int websSSLFlush(websSSL_t *wsp) -{ - a_assert(wsp); - - if ((wsp == NULL) || (wsp->bio == NULL)) { - return -1; - } - - return BIO_flush(wsp->bio); -} - -/******************************************************************************/ |