diff options
Diffstat (limited to 'crypto/openssl/demos/state_machine/state_machine.c')
| -rw-r--r-- | crypto/openssl/demos/state_machine/state_machine.c | 395 | 
1 files changed, 0 insertions, 395 deletions
| diff --git a/crypto/openssl/demos/state_machine/state_machine.c b/crypto/openssl/demos/state_machine/state_machine.c deleted file mode 100644 index 0140fbca7046..000000000000 --- a/crypto/openssl/demos/state_machine/state_machine.c +++ /dev/null @@ -1,395 +0,0 @@ -/* ==================================================================== - * 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; -	    } -	} - -    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; - -    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); - -	/* 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); -	    } - -	/* FIXME: we should only extract if stdout is ready */ -	n=SSLStateMachine_read_extract(pMachine,buf,n); -	if(n < 0) -	    { -	    SSLStateMachine_print_error(pMachine,"read extract failed"); -	    break; -	    } -	assert(n >= 0); -	if(n > 0) -	    { -	    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; -    } | 
