/* ====================================================================
 * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@openssl.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */

/*
 * Nuron, a leader in hardware encryption technology, generously
 * sponsored the development of this demo by Ben Laurie.
 *
 * See http://www.nuron.com/.
 */

/*
 * the aim of this demo is to provide a fully working state-machine
 * style SSL implementation, i.e. one where the main loop acquires
 * some data, then converts it from or to SSL by feeding it into the
 * SSL state machine. It then does any I/O required by the state machine
 * and loops.
 *
 * In order to keep things as simple as possible, this implementation
 * listens on a TCP socket, which it expects to get an SSL connection
 * on (for example, from s_client) and from then on writes decrypted
 * data to stdout and encrypts anything arriving on stdin. Verbose
 * commentary is written to stderr.
 *
 * This implementation acts as a server, but it can also be done for a client.  */

#include <openssl/ssl.h>
#include <assert.h>
#include <unistd.h>
#include <string.h>
#include <openssl/err.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

/* die_unless is intended to work like assert, except that it happens
   always, even if NDEBUG is defined. Use assert as a stopgap. */

#define die_unless(x)	assert(x)

typedef struct
    {
    SSL_CTX *pCtx;
    BIO *pbioRead;
    BIO *pbioWrite;
    SSL *pSSL;
    } SSLStateMachine;

void SSLStateMachine_print_error(SSLStateMachine *pMachine,const char *szErr)
    {
    unsigned long l;

    fprintf(stderr,"%s\n",szErr);
    while((l=ERR_get_error()))
	{
	char buf[1024];

	ERR_error_string_n(l,buf,sizeof buf);
	fprintf(stderr,"Error %lx: %s\n",l,buf);
	}
    }

SSLStateMachine *SSLStateMachine_new(const char *szCertificateFile,
				     const char *szKeyFile)
    {
    SSLStateMachine *pMachine=malloc(sizeof *pMachine);
    int n;

    die_unless(pMachine);

    pMachine->pCtx=SSL_CTX_new(SSLv23_server_method());
    die_unless(pMachine->pCtx);

    n=SSL_CTX_use_certificate_file(pMachine->pCtx,szCertificateFile,
				   SSL_FILETYPE_PEM);
    die_unless(n > 0);

    n=SSL_CTX_use_PrivateKey_file(pMachine->pCtx,szKeyFile,SSL_FILETYPE_PEM);
    die_unless(n > 0);

    pMachine->pSSL=SSL_new(pMachine->pCtx);
    die_unless(pMachine->pSSL);

    pMachine->pbioRead=BIO_new(BIO_s_mem());

    pMachine->pbioWrite=BIO_new(BIO_s_mem());

    SSL_set_bio(pMachine->pSSL,pMachine->pbioRead,pMachine->pbioWrite);

    SSL_set_accept_state(pMachine->pSSL);

    return pMachine;
    }

void SSLStateMachine_read_inject(SSLStateMachine *pMachine,
				 const unsigned char *aucBuf,int nBuf)
    {
    int n=BIO_write(pMachine->pbioRead,aucBuf,nBuf);
    /* If it turns out this assert fails, then buffer the data here
     * and just feed it in in churn instead. Seems to me that it
     * should be guaranteed to succeed, though.
     */
    assert(n == nBuf);
    fprintf(stderr,"%d bytes of encrypted data fed to state machine\n",n);
    }

int SSLStateMachine_read_extract(SSLStateMachine *pMachine,
				 unsigned char *aucBuf,int nBuf)
    {
    int n;

    if(!SSL_is_init_finished(pMachine->pSSL))
	{
	fprintf(stderr,"Doing SSL_accept\n");
	n=SSL_accept(pMachine->pSSL);
	if(n == 0)
	    fprintf(stderr,"SSL_accept returned zero\n");
	if(n < 0)
	    {
	    int err;

	    if((err=SSL_get_error(pMachine->pSSL,n)) == SSL_ERROR_WANT_READ)
		{
		fprintf(stderr,"SSL_accept wants more data\n");
		return 0;
		}

	    SSLStateMachine_print_error(pMachine,"SSL_accept error");
	    exit(7);
	    }
	return 0;
	}

    n=SSL_read(pMachine->pSSL,aucBuf,nBuf);
    if(n < 0)
	{
	int err=SSL_get_error(pMachine->pSSL,n);

	if(err == SSL_ERROR_WANT_READ)
	    {
	    fprintf(stderr,"SSL_read wants more data\n");
	    return 0;
	    }

	SSLStateMachine_print_error(pMachine,"SSL_read error");
	exit(8);
	}

    fprintf(stderr,"%d bytes of decrypted data read from state machine\n",n);
    return n;
    }

int SSLStateMachine_write_can_extract(SSLStateMachine *pMachine)
    {
    int n=BIO_pending(pMachine->pbioWrite);
    if(n)
	fprintf(stderr,"There is encrypted data available to write\n");
    else
	fprintf(stderr,"There is no encrypted data available to write\n");

    return n;
    }

int SSLStateMachine_write_extract(SSLStateMachine *pMachine,
				  unsigned char *aucBuf,int nBuf)
    {
    int n;

    n=BIO_read(pMachine->pbioWrite,aucBuf,nBuf);
    fprintf(stderr,"%d bytes of encrypted data read from state machine\n",n);
    return n;
    }

void SSLStateMachine_write_inject(SSLStateMachine *pMachine,
				  const unsigned char *aucBuf,int nBuf)
    {
    int n=SSL_write(pMachine->pSSL,aucBuf,nBuf);
    /* If it turns out this assert fails, then buffer the data here
     * and just feed it in in churn instead. Seems to me that it
     * should be guaranteed to succeed, though.
     */
    assert(n == nBuf);
    fprintf(stderr,"%d bytes of unencrypted data fed to state machine\n",n);
    }

int OpenSocket(int nPort)
    {
    int nSocket;
    struct sockaddr_in saServer;
    struct sockaddr_in saClient;
    int one=1;
    int nSize;
    int nFD;
    int nLen;

    nSocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if(nSocket < 0)
	{
	perror("socket");
	exit(1);
	}

    if(setsockopt(nSocket,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof one) < 0)
	{
	perror("setsockopt");
        exit(2);
	}

    memset(&saServer,0,sizeof saServer);
    saServer.sin_family=AF_INET;
    saServer.sin_port=htons(nPort);
    nSize=sizeof saServer;
    if(bind(nSocket,(struct sockaddr *)&saServer,nSize) < 0)
	{
	perror("bind");
	exit(3);
	}

    if(listen(nSocket,512) < 0)
	{
	perror("listen");
	exit(4);
	}

    nLen=sizeof saClient;
    nFD=accept(nSocket,(struct sockaddr *)&saClient,&nLen);
    if(nFD < 0)
	{
	perror("accept");
	exit(5);
	}

    fprintf(stderr,"Incoming accepted on port %d\n",nPort);

    return nFD;
    }

int main(int argc,char **argv)
    {
    SSLStateMachine *pMachine;
    int nPort;
    int nFD;
    const char *szCertificateFile;
    const char *szKeyFile;
    char rbuf[1];
    int nrbuf=0;

    if(argc != 4)
	{
	fprintf(stderr,"%s <port> <certificate file> <key file>\n",argv[0]);
	exit(6);
	}

    nPort=atoi(argv[1]);
    szCertificateFile=argv[2];
    szKeyFile=argv[3];

    SSL_library_init();
    OpenSSL_add_ssl_algorithms();
    SSL_load_error_strings();
    ERR_load_crypto_strings();

    nFD=OpenSocket(nPort);

    pMachine=SSLStateMachine_new(szCertificateFile,szKeyFile);

    for( ; ; )
	{
	fd_set rfds,wfds;
	unsigned char buf[1024];
	int n;

	FD_ZERO(&rfds);
	FD_ZERO(&wfds);

	/* Select socket for input */
	FD_SET(nFD,&rfds);

	/* check whether there's decrypted data */
	if(!nrbuf)
	    nrbuf=SSLStateMachine_read_extract(pMachine,rbuf,1);

	/* if there's decrypted data, check whether we can write it */
	if(nrbuf)
	    FD_SET(1,&wfds);

	/* Select socket for output */
	if(SSLStateMachine_write_can_extract(pMachine))
	    FD_SET(nFD,&wfds);

	/* Select stdin for input */
	FD_SET(0,&rfds);

	/* Wait for something to do something */
	n=select(nFD+1,&rfds,&wfds,NULL,NULL);
	assert(n > 0);

	/* Socket is ready for input */
	if(FD_ISSET(nFD,&rfds))
	    {
	    n=read(nFD,buf,sizeof buf);
	    if(n == 0)
		{
		fprintf(stderr,"Got EOF on socket\n");
		exit(0);
		}
	    assert(n > 0);

	    SSLStateMachine_read_inject(pMachine,buf,n);
	    }

	/* stdout is ready for output (and hence we have some to send it) */
	if(FD_ISSET(1,&wfds))
	    {
	    assert(nrbuf == 1);
	    buf[0]=rbuf[0];
	    nrbuf=0;

	    n=SSLStateMachine_read_extract(pMachine,buf+1,sizeof buf-1);
	    if(n < 0)
		{
		SSLStateMachine_print_error(pMachine,"read extract failed");
		break;
		}
	    assert(n >= 0);
	    ++n;
	    if(n > 0) /* FIXME: has to be true now */
		{
		int w;
		
		w=write(1,buf,n);
		/* FIXME: we should push back any unwritten data */
		assert(w == n);
		}
	    }

	/* Socket is ready for output (and therefore we have output to send) */
	if(FD_ISSET(nFD,&wfds))
	    {
	    int w;

	    n=SSLStateMachine_write_extract(pMachine,buf,sizeof buf);
	    assert(n > 0);

	    w=write(nFD,buf,n);
	    /* FIXME: we should push back any unwritten data */
	    assert(w == n);
	    }

	/* Stdin is ready for input */
	if(FD_ISSET(0,&rfds))
	    {
	    n=read(0,buf,sizeof buf);
	    if(n == 0)
		{
		fprintf(stderr,"Got EOF on stdin\n");
		exit(0);
		}
	    assert(n > 0);

	    SSLStateMachine_write_inject(pMachine,buf,n);
	    }
	}
    /* not reached */
    return 0;
    }
