diff options
author | kris <kris@FreeBSD.org> | 2000-11-13 01:03:58 +0000 |
---|---|---|
committer | kris <kris@FreeBSD.org> | 2000-11-13 01:03:58 +0000 |
commit | 539b977eff7c71f628cb2a407543a51070b14763 (patch) | |
tree | 258f64877cac3711a3434257baddcbae72af2af3 /crypto/openssl/demos | |
parent | 893841d237b49d10e810e8b130839b4b63fd5ab4 (diff) | |
download | FreeBSD-src-539b977eff7c71f628cb2a407543a51070b14763.zip FreeBSD-src-539b977eff7c71f628cb2a407543a51070b14763.tar.gz |
Initial import of OpenSSL 0.9.6
Diffstat (limited to 'crypto/openssl/demos')
-rw-r--r-- | crypto/openssl/demos/b64.c | 10 | ||||
-rw-r--r-- | crypto/openssl/demos/pkcs12/README | 3 | ||||
-rw-r--r-- | crypto/openssl/demos/pkcs12/pkread.c | 61 | ||||
-rw-r--r-- | crypto/openssl/demos/pkcs12/pkwrite.c | 46 | ||||
-rw-r--r-- | crypto/openssl/demos/state_machine/Makefile | 9 | ||||
-rw-r--r-- | crypto/openssl/demos/state_machine/state_machine.c | 395 |
6 files changed, 519 insertions, 5 deletions
diff --git a/crypto/openssl/demos/b64.c b/crypto/openssl/demos/b64.c index ad86bc9..8e248e7 100644 --- a/crypto/openssl/demos/b64.c +++ b/crypto/openssl/demos/b64.c @@ -177,11 +177,11 @@ bad: if (verbose) BIO_printf(bio_err,"bufsize=%d\n",bsize); } - strbuf=Malloc(SIZE); - buff=(unsigned char *)Malloc(EVP_ENCODE_LENGTH(bsize)); + strbuf=OPENSSL_malloc(SIZE); + buff=(unsigned char *)OPENSSL_malloc(EVP_ENCODE_LENGTH(bsize)); if ((buff == NULL) || (strbuf == NULL)) { - BIO_printf(bio_err,"Malloc failure\n"); + BIO_printf(bio_err,"OPENSSL_malloc failure\n"); goto end; } @@ -259,8 +259,8 @@ bad: BIO_printf(bio_err,"bytes written:%8ld\n",BIO_number_written(out)); } end: - if (strbuf != NULL) Free(strbuf); - if (buff != NULL) Free(buff); + if (strbuf != NULL) OPENSSL_free(strbuf); + if (buff != NULL) OPENSSL_free(buff); if (in != NULL) BIO_free(in); if (out != NULL) BIO_free(out); if (benc != NULL) BIO_free(benc); diff --git a/crypto/openssl/demos/pkcs12/README b/crypto/openssl/demos/pkcs12/README new file mode 100644 index 0000000..c87434b --- /dev/null +++ b/crypto/openssl/demos/pkcs12/README @@ -0,0 +1,3 @@ +PKCS#12 demo applications + +Written by Steve Henson. diff --git a/crypto/openssl/demos/pkcs12/pkread.c b/crypto/openssl/demos/pkcs12/pkread.c new file mode 100644 index 0000000..8e1b686 --- /dev/null +++ b/crypto/openssl/demos/pkcs12/pkread.c @@ -0,0 +1,61 @@ +/* pkread.c */ + +#include <stdio.h> +#include <stdlib.h> +#include <openssl/pem.h> +#include <openssl/err.h> +#include <openssl/pkcs12.h> + +/* Simple PKCS#12 file reader */ + +int main(int argc, char **argv) +{ + FILE *fp; + EVP_PKEY *pkey; + X509 *cert; + STACK_OF(X509) *ca = NULL; + PKCS12 *p12; + int i; + if (argc != 4) { + fprintf(stderr, "Usage: pkread p12file password opfile\n"); + exit (1); + } + SSLeay_add_all_algorithms(); + ERR_load_crypto_strings(); + if (!(fp = fopen(argv[1], "rb"))) { + fprintf(stderr, "Error opening file %s\n", argv[1]); + exit(1); + } + p12 = d2i_PKCS12_fp(fp, NULL); + fclose (fp); + if (!p12) { + fprintf(stderr, "Error reading PKCS#12 file\n"); + ERR_print_errors_fp(stderr); + exit (1); + } + if (!PKCS12_parse(p12, argv[2], &pkey, &cert, &ca)) { + fprintf(stderr, "Error parsing PKCS#12 file\n"); + ERR_print_errors_fp(stderr); + exit (1); + } + PKCS12_free(p12); + if (!(fp = fopen(argv[3], "w"))) { + fprintf(stderr, "Error opening file %s\n", argv[1]); + exit(1); + } + if (pkey) { + fprintf(fp, "***Private Key***\n"); + PEM_write_PrivateKey(fp, pkey, NULL, NULL, 0, NULL, NULL); + } + if (cert) { + fprintf(fp, "***User Certificate***\n"); + PEM_write_X509_AUX(fp, cert); + } + if (ca && sk_num(ca)) { + fprintf(fp, "***Other Certificates***\n"); + for (i = 0; i < sk_X509_num(ca); i++) + PEM_write_X509_AUX(fp, sk_X509_value(ca, i)); + } + fclose(fp); + return 0; +} diff --git a/crypto/openssl/demos/pkcs12/pkwrite.c b/crypto/openssl/demos/pkcs12/pkwrite.c new file mode 100644 index 0000000..15f839d --- /dev/null +++ b/crypto/openssl/demos/pkcs12/pkwrite.c @@ -0,0 +1,46 @@ +/* pkwrite.c */ + +#include <stdio.h> +#include <stdlib.h> +#include <openssl/pem.h> +#include <openssl/err.h> +#include <openssl/pkcs12.h> + +/* Simple PKCS#12 file creator */ + +int main(int argc, char **argv) +{ + FILE *fp; + EVP_PKEY *pkey; + X509 *cert; + PKCS12 *p12; + if (argc != 5) { + fprintf(stderr, "Usage: pkwrite infile password name p12file\n"); + exit(1); + } + SSLeay_add_all_algorithms(); + ERR_load_crypto_strings(); + if (!(fp = fopen(argv[1], "r"))) { + fprintf(stderr, "Error opening file %s\n", argv[1]); + exit(1); + } + cert = PEM_read_X509(fp, NULL, NULL, NULL); + rewind(fp); + pkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL); + fclose(fp); + p12 = PKCS12_create(argv[2], argv[3], pkey, cert, NULL, 0,0,0,0,0); + if(!p12) { + fprintf(stderr, "Error creating PKCS#12 structure\n"); + ERR_print_errors_fp(stderr); + exit(1); + } + if (!(fp = fopen(argv[4], "wb"))) { + fprintf(stderr, "Error opening file %s\n", argv[1]); + ERR_print_errors_fp(stderr); + exit(1); + } + i2d_PKCS12_fp(fp, p12); + PKCS12_free(p12); + fclose(fp); + return 0; +} diff --git a/crypto/openssl/demos/state_machine/Makefile b/crypto/openssl/demos/state_machine/Makefile new file mode 100644 index 0000000..c7a1145 --- /dev/null +++ b/crypto/openssl/demos/state_machine/Makefile @@ -0,0 +1,9 @@ +CFLAGS=-I../../include -Wall -Werror -g + +all: state_machine + +state_machine: state_machine.o + $(CC) -o state_machine state_machine.o -L../.. -lssl -lcrypto + +test: state_machine + ./state_machine 10000 ../../apps/server.pem ../../apps/server.pem diff --git a/crypto/openssl/demos/state_machine/state_machine.c b/crypto/openssl/demos/state_machine/state_machine.c new file mode 100644 index 0000000..0140fbc --- /dev/null +++ b/crypto/openssl/demos/state_machine/state_machine.c @@ -0,0 +1,395 @@ +/* ==================================================================== + * 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; + } |