Import of old SSLeay release: SSLeay 0.8.1b
This commit is contained in:
3
demos/README
Normal file
3
demos/README
Normal file
@@ -0,0 +1,3 @@
|
||||
Some demo programs sent to me by various people
|
||||
|
||||
eric
|
||||
270
demos/b64.c
Normal file
270
demos/b64.c
Normal file
@@ -0,0 +1,270 @@
|
||||
/* demos/b64.c */
|
||||
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* 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 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 acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS 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 AUTHOR OR 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.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "apps.h"
|
||||
#include "buffer.h"
|
||||
#include "err.h"
|
||||
#include "evp.h"
|
||||
#include "objects.h"
|
||||
#include "x509.h"
|
||||
#include "pem.h"
|
||||
|
||||
#undef SIZE
|
||||
#undef BSIZE
|
||||
#undef PROG
|
||||
|
||||
#define SIZE (512)
|
||||
#define BSIZE (8*1024)
|
||||
#define PROG enc_main
|
||||
|
||||
int main(argc,argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
char *strbuf=NULL;
|
||||
unsigned char *buff=NULL,*bufsize=NULL;
|
||||
int bsize=BSIZE,verbose=0;
|
||||
int ret=1,inl;
|
||||
unsigned char key[24],iv[MD5_DIGEST_LENGTH];
|
||||
char *str=NULL;
|
||||
char *hkey=NULL,*hiv=NULL;
|
||||
int enc=1,printkey=0,i,base64=0;
|
||||
int debug=0;
|
||||
EVP_CIPHER *cipher=NULL,*c;
|
||||
char *inf=NULL,*outf=NULL;
|
||||
BIO *in=NULL,*out=NULL,*b64=NULL,*benc=NULL,*rbio=NULL,*wbio=NULL;
|
||||
#define PROG_NAME_SIZE 16
|
||||
char pname[PROG_NAME_SIZE];
|
||||
|
||||
|
||||
apps_startup();
|
||||
|
||||
if (bio_err == NULL)
|
||||
if ((bio_err=BIO_new(BIO_s_file())) != NULL)
|
||||
BIO_set_fp(bio_err,stderr,BIO_NOCLOSE);
|
||||
|
||||
base64=1;
|
||||
|
||||
argc--;
|
||||
argv++;
|
||||
while (argc >= 1)
|
||||
{
|
||||
if (strcmp(*argv,"-e") == 0)
|
||||
enc=1;
|
||||
if (strcmp(*argv,"-in") == 0)
|
||||
{
|
||||
if (--argc < 1) goto bad;
|
||||
inf= *(++argv);
|
||||
}
|
||||
else if (strcmp(*argv,"-out") == 0)
|
||||
{
|
||||
if (--argc < 1) goto bad;
|
||||
outf= *(++argv);
|
||||
}
|
||||
else if (strcmp(*argv,"-d") == 0)
|
||||
enc=0;
|
||||
else if (strcmp(*argv,"-v") == 0)
|
||||
verbose=1;
|
||||
else if (strcmp(*argv,"-debug") == 0)
|
||||
debug=1;
|
||||
else if (strcmp(*argv,"-bufsize") == 0)
|
||||
{
|
||||
if (--argc < 1) goto bad;
|
||||
bufsize=(unsigned char *)*(++argv);
|
||||
}
|
||||
else
|
||||
{
|
||||
BIO_printf(bio_err,"unknown option '%s'\n",*argv);
|
||||
bad:
|
||||
BIO_printf(bio_err,"options are\n");
|
||||
BIO_printf(bio_err,"%-14s input file\n","-in <file>");
|
||||
BIO_printf(bio_err,"%-14s output file\n","-out <file>");
|
||||
BIO_printf(bio_err,"%-14s encode\n","-e");
|
||||
BIO_printf(bio_err,"%-14s decode\n","-d");
|
||||
BIO_printf(bio_err,"%-14s buffer size\n","-bufsize <n>");
|
||||
|
||||
goto end;
|
||||
}
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
|
||||
if (bufsize != NULL)
|
||||
{
|
||||
int i;
|
||||
unsigned long n;
|
||||
|
||||
for (n=0; *bufsize; bufsize++)
|
||||
{
|
||||
i= *bufsize;
|
||||
if ((i <= '9') && (i >= '0'))
|
||||
n=n*10+i-'0';
|
||||
else if (i == 'k')
|
||||
{
|
||||
n*=1024;
|
||||
bufsize++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (*bufsize != '\0')
|
||||
{
|
||||
BIO_printf(bio_err,"invalid 'bufsize' specified.\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* It must be large enough for a base64 encoded line */
|
||||
if (n < 80) n=80;
|
||||
|
||||
bsize=(int)n;
|
||||
if (verbose) BIO_printf(bio_err,"bufsize=%d\n",bsize);
|
||||
}
|
||||
|
||||
strbuf=Malloc(SIZE);
|
||||
buff=(unsigned char *)Malloc(EVP_ENCODE_LENGTH(bsize));
|
||||
if ((buff == NULL) || (strbuf == NULL))
|
||||
{
|
||||
BIO_printf(bio_err,"Malloc failure\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
in=BIO_new(BIO_s_file());
|
||||
out=BIO_new(BIO_s_file());
|
||||
if ((in == NULL) || (out == NULL))
|
||||
{
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
if (debug)
|
||||
{
|
||||
BIO_set_callback(in,BIO_debug_callback);
|
||||
BIO_set_callback(out,BIO_debug_callback);
|
||||
BIO_set_callback_arg(in,bio_err);
|
||||
BIO_set_callback_arg(out,bio_err);
|
||||
}
|
||||
|
||||
if (inf == NULL)
|
||||
BIO_set_fp(in,stdin,BIO_NOCLOSE);
|
||||
else
|
||||
{
|
||||
if (BIO_read_filename(in,inf) <= 0)
|
||||
{
|
||||
perror(inf);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if (outf == NULL)
|
||||
BIO_set_fp(out,stdout,BIO_NOCLOSE);
|
||||
else
|
||||
{
|
||||
if (BIO_write_filename(out,outf) <= 0)
|
||||
{
|
||||
perror(outf);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
rbio=in;
|
||||
wbio=out;
|
||||
|
||||
if (base64)
|
||||
{
|
||||
if ((b64=BIO_new(BIO_f_base64())) == NULL)
|
||||
goto end;
|
||||
if (debug)
|
||||
{
|
||||
BIO_set_callback(b64,BIO_debug_callback);
|
||||
BIO_set_callback_arg(b64,bio_err);
|
||||
}
|
||||
if (enc)
|
||||
wbio=BIO_push(b64,wbio);
|
||||
else
|
||||
rbio=BIO_push(b64,rbio);
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
inl=BIO_read(rbio,(char *)buff,bsize);
|
||||
if (inl <= 0) break;
|
||||
if (BIO_write(wbio,(char *)buff,inl) != inl)
|
||||
{
|
||||
BIO_printf(bio_err,"error writing output file\n");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
BIO_flush(wbio);
|
||||
|
||||
ret=0;
|
||||
if (verbose)
|
||||
{
|
||||
BIO_printf(bio_err,"bytes read :%8ld\n",BIO_number_read(in));
|
||||
BIO_printf(bio_err,"bytes written:%8ld\n",BIO_number_written(out));
|
||||
}
|
||||
end:
|
||||
if (strbuf != NULL) Free(strbuf);
|
||||
if (buff != NULL) Free(buff);
|
||||
if (in != NULL) BIO_free(in);
|
||||
if (out != NULL) BIO_free(out);
|
||||
if (benc != NULL) BIO_free(benc);
|
||||
if (b64 != NULL) BIO_free(b64);
|
||||
EXIT(ret);
|
||||
}
|
||||
|
||||
20
demos/b64.pl
Normal file
20
demos/b64.pl
Normal file
@@ -0,0 +1,20 @@
|
||||
#!/usr/local/bin/perl
|
||||
|
||||
#
|
||||
# Make PEM encoded data have lines of 64 bytes of data
|
||||
#
|
||||
|
||||
while (<>)
|
||||
{
|
||||
if (/^-----BEGIN/ .. /^-----END/)
|
||||
{
|
||||
if (/^-----BEGIN/) { $first=$_; next; }
|
||||
if (/^-----END/) { $last=$_; next; }
|
||||
$out.=$_;
|
||||
}
|
||||
}
|
||||
$out =~ s/\s//g;
|
||||
$out =~ s/(.{64})/$1\n/g;
|
||||
print "$first$out\n$last\n";
|
||||
|
||||
|
||||
3
demos/bio/README
Normal file
3
demos/bio/README
Normal file
@@ -0,0 +1,3 @@
|
||||
This directory contains some simple examples of the use of BIO's
|
||||
to simplify socket programming.
|
||||
|
||||
107
demos/bio/saccept.c
Normal file
107
demos/bio/saccept.c
Normal file
@@ -0,0 +1,107 @@
|
||||
/* NOCW */
|
||||
/* demos/bio/saccept.c */
|
||||
|
||||
/* A minimal program to server an SSL connection.
|
||||
* It uses blocking.
|
||||
* saccept host:port
|
||||
* host is the interface IP to use. If any interface, use *:port
|
||||
* The default it *:4433
|
||||
*
|
||||
* cc -I../../include saccept.c -L../.. -lssl -lcrypto
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include "err.h"
|
||||
#include "ssl.h"
|
||||
|
||||
#define CERT_FILE "server.pem"
|
||||
|
||||
BIO *in=NULL;
|
||||
|
||||
void close_up()
|
||||
{
|
||||
if (in != NULL)
|
||||
BIO_free(in);
|
||||
}
|
||||
|
||||
int main(argc,argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
char *port=NULL;
|
||||
BIO *ssl_bio,*tmp;
|
||||
SSL_CTX *ctx;
|
||||
SSL *ssl;
|
||||
char buf[512];
|
||||
int ret=1,i;
|
||||
|
||||
if (argc <= 1)
|
||||
port="*:4433";
|
||||
else
|
||||
port=argv[1];
|
||||
|
||||
signal(SIGINT,close_up);
|
||||
|
||||
SSL_load_error_strings();
|
||||
|
||||
/* Add ciphers and message digests */
|
||||
SSLeay_add_ssl_algorithms();
|
||||
|
||||
ctx=SSL_CTX_new(SSLv23_server_method());
|
||||
if (!SSL_CTX_use_certificate_file(ctx,CERT_FILE,SSL_FILETYPE_PEM))
|
||||
goto err;
|
||||
if (!SSL_CTX_use_PrivateKey_file(ctx,CERT_FILE,SSL_FILETYPE_PEM))
|
||||
goto err;
|
||||
if (!SSL_CTX_check_private_key(ctx))
|
||||
goto err;
|
||||
|
||||
/* Setup server side SSL bio */
|
||||
ssl=SSL_new(ctx);
|
||||
ssl_bio=BIO_new_ssl(ctx,0);
|
||||
|
||||
if ((in=BIO_new_accept(port)) == NULL) goto err;
|
||||
|
||||
/* This means that when a new connection is acceptede on 'in',
|
||||
* The ssl_bio will be 'dupilcated' and have the new socket
|
||||
* BIO push into it. Basically it means the SSL BIO will be
|
||||
* automatically setup */
|
||||
BIO_set_accept_bios(in,ssl_bio);
|
||||
|
||||
again:
|
||||
/* The first call will setup the accept socket, and the second
|
||||
* will get a socket. In this loop, the first actuall accept
|
||||
* will occur in the BIO_read() function. */
|
||||
|
||||
if (BIO_do_accept(in) <= 0) goto err;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
i=BIO_read(in,buf,512);
|
||||
if (i == 0)
|
||||
{
|
||||
/* If we have finished, remove the underlying
|
||||
* BIO stack so the next time we call any function
|
||||
* for this BIO, it will attempt to do an
|
||||
* accept */
|
||||
printf("Done\n");
|
||||
tmp=BIO_pop(in);
|
||||
BIO_free_all(tmp);
|
||||
goto again;
|
||||
}
|
||||
if (i < 0) goto err;
|
||||
fwrite(buf,1,i,stdout);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
ret=0;
|
||||
err:
|
||||
if (ret)
|
||||
{
|
||||
ERR_print_errors_fp(stderr);
|
||||
}
|
||||
if (in != NULL) BIO_free(in);
|
||||
exit(ret);
|
||||
return(!ret);
|
||||
}
|
||||
|
||||
115
demos/bio/sconnect.c
Normal file
115
demos/bio/sconnect.c
Normal file
@@ -0,0 +1,115 @@
|
||||
/* NOCW */
|
||||
/* demos/bio/sconnect.c */
|
||||
|
||||
/* A minimal program to do SSL to a passed host and port.
|
||||
* It is actually using non-blocking IO but in a very simple manner
|
||||
* sconnect host:port - it does a 'GET / HTTP/1.0'
|
||||
*
|
||||
* cc -I../../include sconnect.c -L../.. -lssl -lcrypto
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "err.h"
|
||||
#include "ssl.h"
|
||||
|
||||
extern int errno;
|
||||
|
||||
int main(argc,argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
char *host;
|
||||
BIO *out;
|
||||
char buf[1024*10],*p;
|
||||
SSL_CTX *ssl_ctx=NULL;
|
||||
SSL *ssl;
|
||||
BIO *ssl_bio;
|
||||
int i,len,off,ret=1;
|
||||
|
||||
if (argc <= 1)
|
||||
host="localhost:4433";
|
||||
else
|
||||
host=argv[1];
|
||||
|
||||
/* Lets get nice error messages */
|
||||
SSL_load_error_strings();
|
||||
|
||||
/* Setup all the global SSL stuff */
|
||||
SSLeay_add_ssl_algorithms();
|
||||
ssl_ctx=SSL_CTX_new(SSLv23_client_method());
|
||||
|
||||
/* Lets make a SSL structure */
|
||||
ssl=SSL_new(ssl_ctx);
|
||||
SSL_set_connect_state(ssl);
|
||||
|
||||
/* Use it inside an SSL BIO */
|
||||
ssl_bio=BIO_new(BIO_f_ssl());
|
||||
BIO_set_ssl(ssl_bio,ssl,BIO_CLOSE);
|
||||
|
||||
/* Lets use a connect BIO under the SSL BIO */
|
||||
out=BIO_new(BIO_s_connect());
|
||||
BIO_set_hostname(out,host);
|
||||
BIO_set_nbio(out,1);
|
||||
out=BIO_push(ssl_bio,out);
|
||||
|
||||
p="GET / HTTP/1.0\r\n\r\n";
|
||||
len=strlen(p);
|
||||
|
||||
off=0;
|
||||
for (;;)
|
||||
{
|
||||
i=BIO_write(out,&(p[off]),len);
|
||||
if (i <= 0)
|
||||
{
|
||||
if (BIO_should_retry(out))
|
||||
{
|
||||
fprintf(stderr,"write DELAY\n");
|
||||
sleep(1);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
off+=i;
|
||||
len-=i;
|
||||
if (len <= 0) break;
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
i=BIO_read(out,buf,sizeof(buf));
|
||||
if (i == 0) break;
|
||||
if (i < 0)
|
||||
{
|
||||
if (BIO_should_retry(out))
|
||||
{
|
||||
fprintf(stderr,"read DELAY\n");
|
||||
sleep(1);
|
||||
continue;
|
||||
}
|
||||
goto err;
|
||||
}
|
||||
fwrite(buf,1,i,stdout);
|
||||
}
|
||||
|
||||
ret=1;
|
||||
|
||||
if (0)
|
||||
{
|
||||
err:
|
||||
if (ERR_peek_error() == 0) /* system call error */
|
||||
{
|
||||
fprintf(stderr,"errno=%d ",errno);
|
||||
perror("error");
|
||||
}
|
||||
else
|
||||
ERR_print_errors_fp(stderr);
|
||||
}
|
||||
BIO_free_all(out);
|
||||
if (ssl_ctx != NULL) SSL_CTX_free(ssl_ctx);
|
||||
exit(!ret);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
30
demos/bio/server.pem
Normal file
30
demos/bio/server.pem
Normal file
@@ -0,0 +1,30 @@
|
||||
subject=/C=AU/SP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=SSLeay demo server
|
||||
issuer= /C=AU/SP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=CA
|
||||
-----BEGIN X509 CERTIFICATE-----
|
||||
|
||||
MIIBgjCCASwCAQQwDQYJKoZIhvcNAQEEBQAwODELMAkGA1UEBhMCQVUxDDAKBgNV
|
||||
BAgTA1FMRDEbMBkGA1UEAxMSU1NMZWF5L3JzYSB0ZXN0IENBMB4XDTk1MTAwOTIz
|
||||
MzIwNVoXDTk4MDcwNTIzMzIwNVowYDELMAkGA1UEBhMCQVUxDDAKBgNVBAgTA1FM
|
||||
RDEZMBcGA1UEChMQTWluY29tIFB0eS4gTHRkLjELMAkGA1UECxMCQ1MxGzAZBgNV
|
||||
BAMTElNTTGVheSBkZW1vIHNlcnZlcjBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC3
|
||||
LCXcScWua0PFLkHBLm2VejqpA1F4RQ8q0VjRiPafjx/Z/aWH3ipdMVvuJGa/wFXb
|
||||
/nDFLDlfWp+oCPwhBtVPAgMBAAEwDQYJKoZIhvcNAQEEBQADQQArNFsihWIjBzb0
|
||||
DCsU0BvL2bvSwJrPEqFlkDq3F4M6EGutL9axEcANWgbbEdAvNJD1dmEmoWny27Pn
|
||||
IMs6ZOZB
|
||||
-----END X509 CERTIFICATE-----
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
|
||||
MIIBPAIBAAJBALcsJdxJxa5rQ8UuQcEubZV6OqkDUXhFDyrRWNGI9p+PH9n9pYfe
|
||||
Kl0xW+4kZr/AVdv+cMUsOV9an6gI/CEG1U8CAwEAAQJAXJMBZ34ZXHd1vtgL/3hZ
|
||||
hexKbVTx/djZO4imXO/dxPGRzG2ylYZpHmG32/T1kaHpZlCHoEPgHoSzmxYXfxjG
|
||||
sQIhAPmZ/bQOjmRUHM/VM2X5zrjjM6z18R1P6l3ObFwt9FGdAiEAu943Yh9SqMRw
|
||||
tL0xHGxKmM/YJueUw1gB6sLkETN71NsCIQCeT3RhoqXfrpXDoEcEU+gwzjI1bpxq
|
||||
agiNTOLfqGoA5QIhAIQFYjgzONxex7FLrsKBm16N2SFl5pXsN9SpRqqL2n63AiEA
|
||||
g9VNIQ3xwpw7og3IbONifeku+J9qGMGQJMKwSTwrFtI=
|
||||
-----END RSA PRIVATE KEY-----
|
||||
|
||||
-----BEGIN DH PARAMETERS-----
|
||||
MEYCQQDaWDwW2YUiidDkr3VvTMqS3UvlM7gE+w/tlO+cikQD7VdGUNNpmdsp13Yn
|
||||
a6LT1BLiGPTdHghM9tgAPnxHdOgzAgEC
|
||||
-----END DH PARAMETERS-----
|
||||
|
||||
23
demos/maurice/Makefile
Normal file
23
demos/maurice/Makefile
Normal file
@@ -0,0 +1,23 @@
|
||||
CC=cc
|
||||
CFLAGS= -g -I../../include
|
||||
LIBS= -L/usr/local/ssl/lib -L../.. -lcrypto
|
||||
EXAMPLES=example1 example2 example3 example4
|
||||
|
||||
all: $(EXAMPLES)
|
||||
|
||||
example1: example1.o loadkeys.o
|
||||
$(CC) -o example1 example1.o loadkeys.o $(LIBS)
|
||||
|
||||
example2: example2.o loadkeys.o
|
||||
$(CC) -o example2 example2.o loadkeys.o $(LIBS)
|
||||
|
||||
example3: example3.o
|
||||
$(CC) -o example3 example3.o $(LIBS)
|
||||
|
||||
example4: example4.o
|
||||
$(CC) -o example4 example4.o $(LIBS)
|
||||
|
||||
|
||||
clean:
|
||||
rm -f $(EXAMPLES) *.o
|
||||
|
||||
34
demos/maurice/README
Normal file
34
demos/maurice/README
Normal file
@@ -0,0 +1,34 @@
|
||||
From Maurice Gittens <mgittens@gits.nl>
|
||||
--
|
||||
Example programs, demonstrating some basic SSLeay crypto library
|
||||
operations, to help you not to make the same mistakes I did.
|
||||
|
||||
The following files are present.
|
||||
- loadkeys.c Demonstrates the loading and of public and
|
||||
private keys.
|
||||
- loadkeys.h The interface for loadkeys.c
|
||||
- example1.c Demonstrates the sealing and opening API's
|
||||
- example2.c Demonstrates rsa encryption and decryption
|
||||
- example3.c Demonstrates the use of symmetric block ciphers
|
||||
- example4.c Demonstrates base64 and decoding
|
||||
- Makefile A makefile you probably will have to adjust for
|
||||
your environment
|
||||
- README this file
|
||||
|
||||
|
||||
The programs were written by Maurice Gittens <mgittens@gits.nl>
|
||||
with the necesary help from Eric Young <eay@cryptsoft.com>
|
||||
|
||||
You may do as you please with these programs, but please don't
|
||||
pretend that you wrote them.
|
||||
|
||||
To be complete: If you use these programs you acknowlegde that
|
||||
you are aware that there is NO warranty of any kind associated
|
||||
with these programs. I don't even claim that the programs work,
|
||||
they are provided AS-IS.
|
||||
|
||||
January 1997
|
||||
|
||||
Maurice
|
||||
|
||||
|
||||
77
demos/maurice/cert.pem
Normal file
77
demos/maurice/cert.pem
Normal file
@@ -0,0 +1,77 @@
|
||||
issuer :/C=NL/SP=Brabant/L=Eindhoven/O=Gittens Information Systems B.V./OU=Certification Services/CN=ca.gits.nl/Email=mgittens@gits.nl
|
||||
subject:/C=NL/SP=Brabant/O=Gittens Information Systems B.V./OU=Certification Services/CN=caleb.gits.nl/Email=mgittens@gits.nl
|
||||
serial :01
|
||||
|
||||
Certificate:
|
||||
Data:
|
||||
Version: 0 (0x0)
|
||||
Serial Number: 1 (0x1)
|
||||
Signature Algorithm: md5withRSAEncryption
|
||||
Issuer: C=NL, SP=Brabant, L=Eindhoven, O=Gittens Information Systems B.V., OU=Certification Services, CN=ca.gits.nl/Email=mgittens@gits.nl
|
||||
Validity
|
||||
Not Before: Jan 5 13:21:16 1997 GMT
|
||||
Not After : Jul 24 13:21:16 1997 GMT
|
||||
Subject: C=NL, SP=Brabant, O=Gittens Information Systems B.V., OU=Certification Services, CN=caleb.gits.nl/Email=mgittens@gits.nl
|
||||
Subject Public Key Info:
|
||||
Public Key Algorithm: rsaEncryption
|
||||
Modulus:
|
||||
00:dd:82:a0:fe:a9:8d:6a:02:7e:78:d6:33:75:9b:
|
||||
82:01:4b:12:80:ea:6b:9b:83:9e:e3:ae:dc:f3:d0:
|
||||
71:7c:4b:ea:03:57:b4:cc:ba:44:5b:b8:4b:49:d3:
|
||||
f6:39:cc:3d:12:1f:da:58:26:27:bc:bc:ab:a4:6d:
|
||||
62:d1:91:5a:47:9f:80:40:c1:b9:fa:e3:1e:ef:52:
|
||||
78:46:26:43:65:1d:f2:6b:bf:ff:c0:81:66:14:cd:
|
||||
81:32:91:f1:f8:51:7d:0e:17:1f:27:fc:c7:51:fd:
|
||||
1c:73:41:e5:66:43:3c:67:a3:09:b9:5e:36:50:50:
|
||||
b1:e8:42:bd:5c:c6:2b:ec:a9:2c:fe:6a:fe:40:26:
|
||||
64:9e:b9:bf:2d:1d:fb:d0:48:5b:82:2a:8e:ab:a4:
|
||||
d5:7b:5f:26:84:8a:9a:69:5e:c1:71:e2:a9:59:4c:
|
||||
2a:76:f7:fd:f4:cf:3f:d3:ce:30:72:62:65:1c:e9:
|
||||
e9:ee:d2:fc:44:00:1e:e0:80:57:e9:41:b3:f0:44:
|
||||
e5:0f:77:3b:1a:1f:57:5e:94:1d:c3:a5:fa:af:41:
|
||||
8c:4c:30:6b:2b:00:84:52:0c:64:0c:a8:5b:17:16:
|
||||
d1:1e:f8:ea:72:01:47:9a:b9:21:95:f9:71:ed:7c:
|
||||
d2:93:54:0c:c5:9c:e8:e5:40:28:c5:a0:ca:b1:a9:
|
||||
20:f9
|
||||
Exponent: 65537 (0x10001)
|
||||
Signature Algorithm: md5withRSAEncryption
|
||||
93:08:f9:e0:d4:c5:ca:95:de:4e:38:3b:28:87:e9:d3:b6:ce:
|
||||
4f:69:2e:c9:09:57:2f:fa:e2:50:9f:39:ec:f3:84:e8:3a:8f:
|
||||
9b:c3:06:62:90:49:93:6d:23:7a:2b:3d:7b:f9:46:32:18:d3:
|
||||
87:44:49:f7:29:2f:f3:58:97:70:c3:45:5b:90:52:1c:df:fb:
|
||||
a8:a3:a1:29:53:a3:4c:ed:d2:51:d0:44:98:a4:14:6f:76:9d:
|
||||
0d:03:76:e5:d3:13:21:ce:a3:4d:2a:77:fe:ad:b3:47:6d:42:
|
||||
b9:4a:0e:ff:61:f4:ec:62:b2:3b:00:9c:ac:16:a2:ec:19:c8:
|
||||
c7:3d:d7:7d:97:cd:4d:1a:d2:00:07:4e:40:3d:b9:ba:1e:e2:
|
||||
fe:81:28:57:b9:ad:2b:74:59:b0:9f:8b:a5:98:d3:75:06:67:
|
||||
4a:04:11:b2:ea:1a:8c:e0:d4:be:c8:0c:46:76:7f:5f:5a:7b:
|
||||
72:09:dd:b6:d3:6b:97:70:e8:7e:17:74:1c:f7:3a:5f:e3:fa:
|
||||
c2:f7:95:bd:74:5e:44:4b:9b:bd:27:de:02:7f:87:1f:68:68:
|
||||
60:b9:f4:1d:2b:7b:ce:ef:b1:7f:3a:be:b9:66:60:54:6f:0c:
|
||||
a0:dd:8c:03:a7:f1:9f:f8:0e:8d:bb:c6:ba:77:61:f7:8e:be:
|
||||
28:ba:d8:4f
|
||||
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDzzCCArcCAQEwDQYJKoZIhvcNAQEEBQAwgbUxCzAJBgNVBAYTAk5MMRAwDgYD
|
||||
VQQIEwdCcmFiYW50MRIwEAYDVQQHEwlFaW5kaG92ZW4xKTAnBgNVBAoTIEdpdHRl
|
||||
bnMgSW5mb3JtYXRpb24gU3lzdGVtcyBCLlYuMR8wHQYDVQQLExZDZXJ0aWZpY2F0
|
||||
aW9uIFNlcnZpY2VzMRMwEQYDVQQDEwpjYS5naXRzLm5sMR8wHQYJKoZIhvcNAQkB
|
||||
FhBtZ2l0dGVuc0BnaXRzLm5sMB4XDTk3MDEwNTEzMjExNloXDTk3MDcyNDEzMjEx
|
||||
NlowgaQxCzAJBgNVBAYTAk5MMRAwDgYDVQQIEwdCcmFiYW50MSkwJwYDVQQKEyBH
|
||||
aXR0ZW5zIEluZm9ybWF0aW9uIFN5c3RlbXMgQi5WLjEfMB0GA1UECxMWQ2VydGlm
|
||||
aWNhdGlvbiBTZXJ2aWNlczEWMBQGA1UEAxMNY2FsZWIuZ2l0cy5ubDEfMB0GCSqG
|
||||
SIb3DQEJARYQbWdpdHRlbnNAZ2l0cy5ubDCCASIwDQYJKoZIhvcNAQEBBQADggEP
|
||||
ADCCAQoCggEBAN2CoP6pjWoCfnjWM3WbggFLEoDqa5uDnuOu3PPQcXxL6gNXtMy6
|
||||
RFu4S0nT9jnMPRIf2lgmJ7y8q6RtYtGRWkefgEDBufrjHu9SeEYmQ2Ud8mu//8CB
|
||||
ZhTNgTKR8fhRfQ4XHyf8x1H9HHNB5WZDPGejCbleNlBQsehCvVzGK+ypLP5q/kAm
|
||||
ZJ65vy0d+9BIW4Iqjquk1XtfJoSKmmlewXHiqVlMKnb3/fTPP9POMHJiZRzp6e7S
|
||||
/EQAHuCAV+lBs/BE5Q93OxofV16UHcOl+q9BjEwwaysAhFIMZAyoWxcW0R746nIB
|
||||
R5q5IZX5ce180pNUDMWc6OVAKMWgyrGpIPkCAwEAATANBgkqhkiG9w0BAQQFAAOC
|
||||
AQEAkwj54NTFypXeTjg7KIfp07bOT2kuyQlXL/riUJ857POE6DqPm8MGYpBJk20j
|
||||
eis9e/lGMhjTh0RJ9ykv81iXcMNFW5BSHN/7qKOhKVOjTO3SUdBEmKQUb3adDQN2
|
||||
5dMTIc6jTSp3/q2zR21CuUoO/2H07GKyOwCcrBai7BnIxz3XfZfNTRrSAAdOQD25
|
||||
uh7i/oEoV7mtK3RZsJ+LpZjTdQZnSgQRsuoajODUvsgMRnZ/X1p7cgndttNrl3Do
|
||||
fhd0HPc6X+P6wveVvXReREubvSfeAn+HH2hoYLn0HSt7zu+xfzq+uWZgVG8MoN2M
|
||||
A6fxn/gOjbvGundh946+KLrYTw==
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
200
demos/maurice/example1.c
Normal file
200
demos/maurice/example1.c
Normal file
@@ -0,0 +1,200 @@
|
||||
/* NOCW */
|
||||
/*
|
||||
Please read the README file for condition of use, before
|
||||
using this software.
|
||||
|
||||
Maurice Gittens <mgittens@gits.nl> January 1997
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <netinet/in.h>
|
||||
#include <fcntl.h>
|
||||
#include <strings.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "rsa.h"
|
||||
#include "evp.h"
|
||||
#include "objects.h"
|
||||
#include "x509.h"
|
||||
#include "err.h"
|
||||
#include "pem.h"
|
||||
#include "ssl.h"
|
||||
|
||||
#include "loadkeys.h"
|
||||
|
||||
#define PUBFILE "cert.pem"
|
||||
#define PRIVFILE "privkey.pem"
|
||||
|
||||
#define STDIN 0
|
||||
#define STDOUT 1
|
||||
|
||||
void main_encrypt(void);
|
||||
void main_decrypt(void);
|
||||
|
||||
static const char *usage = "Usage: example1 [-d]\n";
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
|
||||
ERR_load_crypto_strings();
|
||||
|
||||
if ((argc == 1))
|
||||
{
|
||||
main_encrypt();
|
||||
}
|
||||
else if ((argc == 2) && !strcmp(argv[1],"-d"))
|
||||
{
|
||||
main_decrypt();
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("%s",usage);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void main_encrypt(void)
|
||||
{
|
||||
unsigned int ebuflen;
|
||||
EVP_CIPHER_CTX ectx;
|
||||
unsigned char iv[EVP_MAX_IV_LENGTH];
|
||||
unsigned char *ekey[1];
|
||||
int readlen;
|
||||
int ekeylen, net_ekeylen;
|
||||
EVP_PKEY *pubKey[1];
|
||||
char buf[512];
|
||||
char ebuf[512];
|
||||
|
||||
memset(iv, '\0', sizeof(iv));
|
||||
|
||||
pubKey[0] = ReadPublicKey(PUBFILE);
|
||||
|
||||
if(!pubKey)
|
||||
{
|
||||
fprintf(stderr,"Error: can't load public key");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ekey[0] = malloc(EVP_PKEY_size(pubKey[0]));
|
||||
if (!ekey[0])
|
||||
{
|
||||
EVP_PKEY_free(pubKey[0]);
|
||||
perror("malloc");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
EVP_SealInit(&ectx,
|
||||
EVP_des_ede3_cbc(),
|
||||
ekey,
|
||||
&ekeylen,
|
||||
iv,
|
||||
pubKey,
|
||||
1);
|
||||
|
||||
net_ekeylen = htonl(ekeylen);
|
||||
write(STDOUT, (char*)&net_ekeylen, sizeof(net_ekeylen));
|
||||
write(STDOUT, ekey[0], ekeylen);
|
||||
write(STDOUT, iv, sizeof(iv));
|
||||
|
||||
while(1)
|
||||
{
|
||||
readlen = read(STDIN, buf, sizeof(buf));
|
||||
|
||||
if (readlen <= 0)
|
||||
{
|
||||
if (readlen < 0)
|
||||
perror("read");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
EVP_SealUpdate(&ectx, ebuf, &ebuflen, buf, readlen);
|
||||
|
||||
write(STDOUT, ebuf, ebuflen);
|
||||
}
|
||||
|
||||
EVP_SealFinal(&ectx, ebuf, &ebuflen);
|
||||
|
||||
write(STDOUT, ebuf, ebuflen);
|
||||
|
||||
EVP_PKEY_free(pubKey[0]);
|
||||
free(ekey[0]);
|
||||
}
|
||||
|
||||
void main_decrypt(void)
|
||||
{
|
||||
char buf[512];
|
||||
char ebuf[512];
|
||||
unsigned int buflen;
|
||||
EVP_CIPHER_CTX ectx;
|
||||
unsigned char iv[8];
|
||||
unsigned char *encryptKey;
|
||||
unsigned int ekeylen;
|
||||
EVP_PKEY *privateKey;
|
||||
|
||||
memset(iv, '\0', sizeof(iv));
|
||||
|
||||
privateKey = ReadPrivateKey(PRIVFILE);
|
||||
if (!privateKey)
|
||||
{
|
||||
fprintf(stderr, "Error: can't load private key");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
read(STDIN, &ekeylen, sizeof(ekeylen));
|
||||
ekeylen = ntohl(ekeylen);
|
||||
|
||||
if (ekeylen != EVP_PKEY_size(privateKey))
|
||||
{
|
||||
EVP_PKEY_free(privateKey);
|
||||
fprintf(stderr, "keylength mismatch");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
encryptKey = malloc(sizeof(char) * ekeylen);
|
||||
if (!encryptKey)
|
||||
{
|
||||
EVP_PKEY_free(privateKey);
|
||||
perror("malloc");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
read(STDIN, encryptKey, ekeylen);
|
||||
read(STDIN, iv, sizeof(iv));
|
||||
|
||||
EVP_OpenInit(&ectx,
|
||||
EVP_des_ede3_cbc(),
|
||||
encryptKey,
|
||||
ekeylen,
|
||||
iv,
|
||||
privateKey);
|
||||
|
||||
while(1)
|
||||
{
|
||||
int readlen = read(STDIN, ebuf, sizeof(ebuf));
|
||||
|
||||
if (readlen <= 0)
|
||||
{
|
||||
if (readlen < 0)
|
||||
perror("read");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
EVP_OpenUpdate(&ectx, buf, &buflen, ebuf, readlen);
|
||||
|
||||
write(STDOUT, buf, buflen);
|
||||
}
|
||||
|
||||
EVP_OpenFinal(&ectx, buf, &buflen);
|
||||
|
||||
write(STDOUT, buf, buflen);
|
||||
|
||||
EVP_PKEY_free(privateKey);
|
||||
free(encryptKey);
|
||||
}
|
||||
|
||||
|
||||
77
demos/maurice/example2.c
Normal file
77
demos/maurice/example2.c
Normal file
@@ -0,0 +1,77 @@
|
||||
/* NOCW */
|
||||
/*
|
||||
Please read the README file for condition of use, before
|
||||
using this software.
|
||||
|
||||
Maurice Gittens <mgittens@gits.nl> January 1997
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <strings.h>
|
||||
|
||||
#include "rsa.h"
|
||||
#include "evp.h"
|
||||
#include "objects.h"
|
||||
#include "x509.h"
|
||||
#include "err.h"
|
||||
#include "pem.h"
|
||||
#include "ssl.h"
|
||||
|
||||
#include "loadkeys.h"
|
||||
|
||||
#define PUBFILE "cert.pem"
|
||||
#define PRIVFILE "privkey.pem"
|
||||
#define STDIN 0
|
||||
#define STDOUT 1
|
||||
|
||||
int main()
|
||||
{
|
||||
char *ct = "This the clear text";
|
||||
char *buf;
|
||||
char *buf2;
|
||||
EVP_PKEY *pubKey;
|
||||
EVP_PKEY *privKey;
|
||||
int len;
|
||||
FILE *fp;
|
||||
|
||||
ERR_load_crypto_strings();
|
||||
|
||||
privKey = ReadPrivateKey(PRIVFILE);
|
||||
if (!privKey)
|
||||
{
|
||||
ERR_print_errors_fp (stderr);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
pubKey = ReadPublicKey(PUBFILE);
|
||||
if(!pubKey)
|
||||
{
|
||||
EVP_PKEY_free(privKey);
|
||||
fprintf(stderr,"Error: can't load public key");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* No error checking */
|
||||
buf = malloc(EVP_PKEY_size(pubKey));
|
||||
buf2 = malloc(EVP_PKEY_size(pubKey));
|
||||
|
||||
len = RSA_public_encrypt(strlen(ct)+1, ct, buf, pubKey->pkey.rsa,RSA_PKCS1_PADDING);
|
||||
|
||||
if (len != EVP_PKEY_size(pubKey))
|
||||
{
|
||||
fprintf(stderr,"Error: ciphertext should match length of key\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
RSA_private_decrypt(len, buf, buf2, privKey->pkey.rsa,RSA_PKCS1_PADDING);
|
||||
|
||||
printf("%s\n", buf2);
|
||||
|
||||
EVP_PKEY_free(privKey);
|
||||
EVP_PKEY_free(pubKey);
|
||||
free(buf);
|
||||
free(buf2);
|
||||
}
|
||||
|
||||
|
||||
86
demos/maurice/example3.c
Normal file
86
demos/maurice/example3.c
Normal file
@@ -0,0 +1,86 @@
|
||||
/* NOCW */
|
||||
/*
|
||||
Please read the README file for condition of use, before
|
||||
using this software.
|
||||
|
||||
Maurice Gittens <mgittens@gits.nl> January 1997
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <evp.h>
|
||||
|
||||
#define STDIN 0
|
||||
#define STDOUT 1
|
||||
#define BUFLEN 512
|
||||
#define INIT_VECTOR "12345678"
|
||||
#define ENCRYPT 1
|
||||
#define DECRYPT 0
|
||||
#define ALG EVP_des_ede3_cbc()
|
||||
|
||||
static const char *usage = "Usage: example3 [-d] password\n";
|
||||
|
||||
void do_cipher(char *,int);
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if ((argc == 2))
|
||||
{
|
||||
do_cipher(argv[1],ENCRYPT);
|
||||
}
|
||||
else if ((argc == 3) && !strcmp(argv[1],"-d"))
|
||||
{
|
||||
do_cipher(argv[2],DECRYPT);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr,"%s", usage);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void do_cipher(char *pw, int operation)
|
||||
{
|
||||
char buf[BUFLEN];
|
||||
char ebuf[BUFLEN + 8];
|
||||
unsigned int ebuflen, rc;
|
||||
unsigned char iv[EVP_MAX_IV_LENGTH], key[EVP_MAX_KEY_LENGTH];
|
||||
unsigned int ekeylen, net_ekeylen;
|
||||
EVP_CIPHER_CTX ectx;
|
||||
|
||||
memcpy(iv, INIT_VECTOR, sizeof(iv));
|
||||
|
||||
EVP_BytesToKey(ALG, EVP_md5(), "salu", pw, strlen(pw), 1, key, iv);
|
||||
|
||||
EVP_CipherInit(&ectx, ALG, key, iv, operation);
|
||||
|
||||
while(1)
|
||||
{
|
||||
int readlen = read(STDIN, buf, sizeof(buf));
|
||||
|
||||
if (readlen <= 0)
|
||||
{
|
||||
if (!readlen)
|
||||
break;
|
||||
else
|
||||
{
|
||||
perror("read");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
EVP_CipherUpdate(&ectx, ebuf, &ebuflen, buf, readlen);
|
||||
|
||||
write(STDOUT, ebuf, ebuflen);
|
||||
}
|
||||
|
||||
EVP_CipherFinal(&ectx, ebuf, &ebuflen);
|
||||
|
||||
write(STDOUT, ebuf, ebuflen);
|
||||
}
|
||||
|
||||
|
||||
122
demos/maurice/example4.c
Normal file
122
demos/maurice/example4.c
Normal file
@@ -0,0 +1,122 @@
|
||||
/* NOCW */
|
||||
/*
|
||||
Please read the README file for condition of use, before
|
||||
using this software.
|
||||
|
||||
Maurice Gittens <mgittens@gits.nl> January 1997
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <evp.h>
|
||||
|
||||
#define STDIN 0
|
||||
#define STDOUT 1
|
||||
#define BUFLEN 512
|
||||
|
||||
static const char *usage = "Usage: example4 [-d]\n";
|
||||
|
||||
void do_encode(void);
|
||||
void do_decode(void);
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if ((argc == 1))
|
||||
{
|
||||
do_encode();
|
||||
}
|
||||
else if ((argc == 2) && !strcmp(argv[1],"-d"))
|
||||
{
|
||||
do_decode();
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr,"%s", usage);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void do_encode()
|
||||
{
|
||||
char buf[BUFLEN];
|
||||
char ebuf[BUFLEN+24];
|
||||
unsigned int ebuflen, rc;
|
||||
EVP_ENCODE_CTX ectx;
|
||||
|
||||
EVP_EncodeInit(&ectx);
|
||||
|
||||
while(1)
|
||||
{
|
||||
int readlen = read(STDIN, buf, sizeof(buf));
|
||||
|
||||
if (readlen <= 0)
|
||||
{
|
||||
if (!readlen)
|
||||
break;
|
||||
else
|
||||
{
|
||||
perror("read");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
EVP_EncodeUpdate(&ectx, ebuf, &ebuflen, buf, readlen);
|
||||
|
||||
write(STDOUT, ebuf, ebuflen);
|
||||
}
|
||||
|
||||
EVP_EncodeFinal(&ectx, ebuf, &ebuflen);
|
||||
|
||||
write(STDOUT, ebuf, ebuflen);
|
||||
}
|
||||
|
||||
void do_decode()
|
||||
{
|
||||
char buf[BUFLEN];
|
||||
char ebuf[BUFLEN+24];
|
||||
unsigned int ebuflen, rc;
|
||||
EVP_ENCODE_CTX ectx;
|
||||
|
||||
EVP_DecodeInit(&ectx);
|
||||
|
||||
while(1)
|
||||
{
|
||||
int readlen = read(STDIN, buf, sizeof(buf));
|
||||
int rc;
|
||||
|
||||
if (readlen <= 0)
|
||||
{
|
||||
if (!readlen)
|
||||
break;
|
||||
else
|
||||
{
|
||||
perror("read");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
rc = EVP_DecodeUpdate(&ectx, ebuf, &ebuflen, buf, readlen);
|
||||
if (rc <= 0)
|
||||
{
|
||||
if (!rc)
|
||||
{
|
||||
write(STDOUT, ebuf, ebuflen);
|
||||
break;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Error: decoding message\n");
|
||||
return;
|
||||
}
|
||||
|
||||
write(STDOUT, ebuf, ebuflen);
|
||||
}
|
||||
|
||||
EVP_DecodeFinal(&ectx, ebuf, &ebuflen);
|
||||
|
||||
write(STDOUT, ebuf, ebuflen);
|
||||
}
|
||||
|
||||
77
demos/maurice/loadkeys.c
Normal file
77
demos/maurice/loadkeys.c
Normal file
@@ -0,0 +1,77 @@
|
||||
/* NOCW */
|
||||
/*
|
||||
Please read the README file for condition of use, before
|
||||
using this software.
|
||||
|
||||
Maurice Gittens <mgittens@gits.nl> January 1997
|
||||
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <netinet/in.h>
|
||||
#include <fcntl.h>
|
||||
#include <strings.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "rsa.h"
|
||||
#include "evp.h"
|
||||
#include "objects.h"
|
||||
#include "x509.h"
|
||||
#include "err.h"
|
||||
#include "pem.h"
|
||||
#include "ssl.h"
|
||||
|
||||
EVP_PKEY * ReadPublicKey(const char *certfile)
|
||||
{
|
||||
FILE *fp = fopen (certfile, "r");
|
||||
X509 *x509;
|
||||
EVP_PKEY *pkey;
|
||||
|
||||
if (!fp)
|
||||
return NULL;
|
||||
|
||||
x509 = (X509 *)PEM_ASN1_read ((char *(*)())d2i_X509,
|
||||
PEM_STRING_X509,
|
||||
fp, NULL, NULL);
|
||||
|
||||
if (x509 == NULL)
|
||||
{
|
||||
ERR_print_errors_fp (stderr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fclose (fp);
|
||||
|
||||
pkey=X509_extract_key(x509);
|
||||
|
||||
X509_free(x509);
|
||||
|
||||
if (pkey == NULL)
|
||||
ERR_print_errors_fp (stderr);
|
||||
|
||||
return pkey;
|
||||
}
|
||||
|
||||
EVP_PKEY *ReadPrivateKey(const char *keyfile)
|
||||
{
|
||||
FILE *fp = fopen(keyfile, "r");
|
||||
EVP_PKEY *pkey;
|
||||
|
||||
if (!fp)
|
||||
return NULL;
|
||||
|
||||
pkey = (EVP_PKEY*)PEM_ASN1_read ((char *(*)())d2i_PrivateKey,
|
||||
PEM_STRING_EVP_PKEY,
|
||||
fp,
|
||||
NULL, NULL);
|
||||
|
||||
fclose (fp);
|
||||
|
||||
if (pkey == NULL)
|
||||
ERR_print_errors_fp (stderr);
|
||||
|
||||
return pkey;
|
||||
}
|
||||
|
||||
|
||||
19
demos/maurice/loadkeys.h
Normal file
19
demos/maurice/loadkeys.h
Normal file
@@ -0,0 +1,19 @@
|
||||
/* NOCW */
|
||||
/*
|
||||
Please read the README file for condition of use, before
|
||||
using this software.
|
||||
|
||||
Maurice Gittens <mgittens@gits.nl> January 1997
|
||||
|
||||
*/
|
||||
|
||||
#ifndef LOADKEYS_H_SEEN
|
||||
#define LOADKEYS_H_SEEN
|
||||
|
||||
#include "evp.h"
|
||||
|
||||
EVP_PKEY * ReadPublicKey(const char *certfile);
|
||||
EVP_PKEY *ReadPrivateKey(const char *keyfile);
|
||||
|
||||
#endif
|
||||
|
||||
27
demos/maurice/privkey.pem
Normal file
27
demos/maurice/privkey.pem
Normal file
@@ -0,0 +1,27 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEA3YKg/qmNagJ+eNYzdZuCAUsSgOprm4Oe467c89BxfEvqA1e0
|
||||
zLpEW7hLSdP2Ocw9Eh/aWCYnvLyrpG1i0ZFaR5+AQMG5+uMe71J4RiZDZR3ya7//
|
||||
wIFmFM2BMpHx+FF9DhcfJ/zHUf0cc0HlZkM8Z6MJuV42UFCx6EK9XMYr7Kks/mr+
|
||||
QCZknrm/LR370EhbgiqOq6TVe18mhIqaaV7BceKpWUwqdvf99M8/084wcmJlHOnp
|
||||
7tL8RAAe4IBX6UGz8ETlD3c7Gh9XXpQdw6X6r0GMTDBrKwCEUgxkDKhbFxbRHvjq
|
||||
cgFHmrkhlflx7XzSk1QMxZzo5UAoxaDKsakg+QIDAQABAoIBAQC0hnh083PnuJ6g
|
||||
Flob+B+stCUhYWtPc6ZzgphaMD+9ABV4oescipWZdooNYiyikBwZgFIvUvFBtTXh
|
||||
rLBDgUVlZ81beUb7/EvC2aBh818rsotWW0Sw/ARY4d7wetcL/EWBzUA8E5vR6wlb
|
||||
uZGelR9OiyYqp2h2bj1/v5yaVnuHxBeBj5clTHtPMXc+/70iUNBDMZ0ruZTdSwll
|
||||
e0DH8pp/5USYewlrKtRIJT7elC8LFMqEz4OpNvfaR2OEY0FatYYmSvQPNwV8/Eor
|
||||
XlNzRi9qD0uXbVexaAgQZ3/KZuAzUbOgwJZZXEAOGkZ/J1n08jljPXdU0o7bHhNl
|
||||
7siHbuEBAoGBAP53IvvJkhnH8Akf6E6sXelZkPKHnwDwfywDAiIhXza9DB1DViRS
|
||||
bZUB5gzcxmLGalex5+LcwZmsqFO5NXZ8SQeE9p0YT8yJsX4J1w9JzSvsWJBS2vyW
|
||||
Kbt21oG6JAGrWSGMIfxKpuahtWLf4JpGjftti0qIVQ60GKEPc1/xE2PZAoGBAN7Y
|
||||
nRPaUaqcIwbnH9kovOKwZ/PWREy1ecr3YXj65VYTnwSJHD0+CJa/DX8eB/G4AoNA
|
||||
Y2LPbq0Xu3+7SaUsO45VkaZuJmNwheUQ4tmyd/YdnVZ0AHXx1tvpR7QeO0WjnlNK
|
||||
mR+x00fetrff2Ypahs0wtU0Xf3F8ORgVB8jnxBIhAoGAcwf0PpI+g30Im3dbEsWE
|
||||
poogpiJ81HXjZ0fs3PTtD9eh9FCOTlkcxHFZR5M980TyqbX4t2tH8WpFpaNh8a/5
|
||||
a3bF7PoiiLnuDKXyHC0mnKZ42rU53VkcgGwWSAqXYFHPNwUcD+rHTBbp4kqGQ/eF
|
||||
E5XPk9/RY5YyVAyiAUr/kvECgYBvW1Ua75SxqbZDI8mhbZ79tGMt0NtubZz/1KCL
|
||||
oOxrGAD1dkJ7Q/1svunSpMIZgvcWeV1wqfFHY72ZNZC2jiTwmkffH9nlBPyTm92Q
|
||||
JYOWo/PUmMEGLyRL3gWrtxOtV/as7nEYCndmyZ8KwTxmy5fi/z0J2f0gS5AIPbIX
|
||||
LeGnoQKBgQDapjz9K4HWR5AMxyga4eiLIrmADySP846uz3eZIvTJQZ+6TAamvnno
|
||||
KbnU21cGq5HBBtxqQvGswLPGW9rZAgykHHJmYBUp0xv4+I4qHfXyD7QNmvq+Vxjj
|
||||
V2tgIafEpaf2ZsfM7BZeZz8MzeGcDwyrHtIO1FQiYN5Qz9Hq68XmVA==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
100
demos/prime/prime.c
Normal file
100
demos/prime/prime.c
Normal file
@@ -0,0 +1,100 @@
|
||||
/* demos/prime/prime.c */
|
||||
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* 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 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 acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS 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 AUTHOR OR 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.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "bn.h"
|
||||
|
||||
void callback(type,num)
|
||||
int type,num;
|
||||
{
|
||||
if (type == 0)
|
||||
fprintf(stderr,".");
|
||||
else if (type == 1)
|
||||
fprintf(stderr,"+");
|
||||
else if (type == 2)
|
||||
fprintf(stderr,"*");
|
||||
fflush(stderr);
|
||||
}
|
||||
|
||||
int main(argc,argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
BIGNUM *rand;
|
||||
int num=256;
|
||||
|
||||
/* we should really call RAND_seed(char *bytes,int num);
|
||||
* to fully initalise the random number generator */
|
||||
if (argc >= 2)
|
||||
{
|
||||
num=atoi(argv[1]);
|
||||
if (num == 0) num=256;
|
||||
}
|
||||
|
||||
fprintf(stderr,"generate a strong prime\n");
|
||||
rand=BN_generate_prime(num,1,NULL,NULL,callback);
|
||||
/* change the second parameter to 1 for a strong prime */
|
||||
fprintf(stderr,"\n");
|
||||
|
||||
BN_print_fp(stdout,rand);
|
||||
fprintf(stdout,"\n");
|
||||
BN_free(rand);
|
||||
exit(0);
|
||||
return(0);
|
||||
}
|
||||
|
||||
9
demos/privkey.pem
Normal file
9
demos/privkey.pem
Normal file
@@ -0,0 +1,9 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIBPAIBAAJBAN+FmbxmHVOp/RxtpMGz0DvQEBz1sDktHp19hIoMSu0YZift5MAu
|
||||
4xAEJYvWVCshDiyOTWsUBXwZkrkt87FyctkCAwEAAQJAG/vxBGpQb6IPo1iC0RF/
|
||||
F430BnwoBPCGLbeCOXpSgx5X+19vuTSdEqMgeNB6+aNb+XY/7mvVfCjyD6WZ0oxs
|
||||
JQIhAPO+uL9cP40lFs62pdL3QSWsh3VNDByvOtr9LpeaxBm/AiEA6sKVfXsDQ5hd
|
||||
SHt9U61r2r8Lcxmzi9Kw6JNqjMmzqWcCIQCKoRy+aZ8Tjdas9yDVHh+FZ90bEBkl
|
||||
b1xQFNOdEj8aTQIhAOJWrO6INYNsWTPS6+hLYZtLamyUsQj0H+B8kNQge/mtAiEA
|
||||
nBfvUl243qbqN8gF7Az1u33uc9FsPVvQPiBzLxZ4ixw=
|
||||
-----END RSA PRIVATE KEY-----
|
||||
168
demos/selfsign.c
Normal file
168
demos/selfsign.c
Normal file
@@ -0,0 +1,168 @@
|
||||
/* NOCW */
|
||||
/* cc -o ssdemo -I../include selfsign.c ../libcrypto.a */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "buffer.h"
|
||||
#include "crypto.h"
|
||||
#include "objects.h"
|
||||
#include "asn1.h"
|
||||
#include "evp.h"
|
||||
#include "x509.h"
|
||||
#include "pem.h"
|
||||
|
||||
int mkit(X509 **x509p, EVP_PKEY **pkeyp, int bits, int serial, int days);
|
||||
|
||||
int main()
|
||||
{
|
||||
BIO *bio_err;
|
||||
X509 *x509=NULL;
|
||||
EVP_PKEY *pkey=NULL;
|
||||
|
||||
CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
|
||||
|
||||
X509v3_add_netscape_extensions();
|
||||
|
||||
if ((bio_err=BIO_new(BIO_s_file())) != NULL)
|
||||
BIO_set_fp(bio_err,stderr,BIO_NOCLOSE);
|
||||
|
||||
mkit(&x509,&pkey,512,0,365);
|
||||
|
||||
RSA_print_fp(stdout,pkey->pkey.rsa,0);
|
||||
X509_print_fp(stdout,x509);
|
||||
|
||||
PEM_write_RSAPrivateKey(stdout,pkey->pkey.rsa,NULL,NULL,0,NULL);
|
||||
PEM_write_X509(stdout,x509);
|
||||
|
||||
X509_free(x509);
|
||||
EVP_PKEY_free(pkey);
|
||||
BIO_free(bio_err);
|
||||
|
||||
X509_cleanup_extensions();
|
||||
|
||||
CRYPTO_mem_leaks(bio_err);
|
||||
return(0);
|
||||
}
|
||||
|
||||
#ifdef WIN16
|
||||
# define MS_CALLBACK _far _loadds
|
||||
# define MS_FAR _far
|
||||
#else
|
||||
# define MS_CALLBACK
|
||||
# define MS_FAR
|
||||
#endif
|
||||
|
||||
static void MS_CALLBACK callback(p, n)
|
||||
int p;
|
||||
int n;
|
||||
{
|
||||
char c='B';
|
||||
|
||||
if (p == 0) c='.';
|
||||
if (p == 1) c='+';
|
||||
if (p == 2) c='*';
|
||||
if (p == 3) c='\n';
|
||||
fputc(c,stderr);
|
||||
}
|
||||
|
||||
int mkit(x509p,pkeyp,bits,serial,days)
|
||||
X509 **x509p;
|
||||
EVP_PKEY **pkeyp;
|
||||
int bits;
|
||||
int serial;
|
||||
int days;
|
||||
{
|
||||
X509 *x;
|
||||
EVP_PKEY *pk;
|
||||
RSA *rsa;
|
||||
char *s;
|
||||
X509_NAME *name=NULL;
|
||||
X509_NAME_ENTRY *ne=NULL;
|
||||
X509_EXTENSION *ex=NULL;
|
||||
ASN1_OCTET_STRING *data=NULL;
|
||||
|
||||
|
||||
if ((pkeyp == NULL) || (*pkeyp == NULL))
|
||||
{
|
||||
if ((pk=EVP_PKEY_new()) == NULL)
|
||||
{
|
||||
abort();
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
else
|
||||
pk= *pkeyp;
|
||||
|
||||
if ((x509p == NULL) || (*x509p == NULL))
|
||||
{
|
||||
if ((x=X509_new()) == NULL)
|
||||
goto err;
|
||||
}
|
||||
else
|
||||
x= *x509p;
|
||||
|
||||
rsa=RSA_generate_key(bits,RSA_F4,callback);
|
||||
if (!EVP_PKEY_assign_RSA(pk,rsa))
|
||||
{
|
||||
abort();
|
||||
goto err;
|
||||
}
|
||||
rsa=NULL;
|
||||
|
||||
X509_set_version(x,3);
|
||||
ASN1_INTEGER_set(X509_get_serialNumber(x),serial);
|
||||
X509_gmtime_adj(X509_get_notBefore(x),0);
|
||||
X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days);
|
||||
X509_set_pubkey(x,pk);
|
||||
|
||||
name=X509_NAME_new();
|
||||
|
||||
ne=X509_NAME_ENTRY_create_by_NID(NULL,NID_countryName,
|
||||
V_ASN1_APP_CHOOSE,"AU",-1);
|
||||
X509_NAME_add_entry(name,ne,0,0);
|
||||
|
||||
X509_NAME_ENTRY_create_by_NID(&ne,NID_commonName,
|
||||
V_ASN1_APP_CHOOSE,"Eric Young",-1);
|
||||
X509_NAME_add_entry(name,ne,1,0);
|
||||
|
||||
/* finished with structure */
|
||||
X509_NAME_ENTRY_free(ne);
|
||||
|
||||
X509_set_subject_name(x,name);
|
||||
X509_set_issuer_name(x,name);
|
||||
|
||||
/* finished with structure */
|
||||
X509_NAME_free(name);
|
||||
|
||||
data=X509v3_pack_string(NULL,V_ASN1_BIT_STRING,
|
||||
"\001",1);
|
||||
ex=X509_EXTENSION_create_by_NID(NULL,NID_netscape_cert_type,0,data);
|
||||
X509_add_ext(x,ex,-1);
|
||||
|
||||
X509v3_pack_string(&data,V_ASN1_IA5STRING,
|
||||
"example comment extension",-1);
|
||||
X509_EXTENSION_create_by_NID(&ex,NID_netscape_comment,0,data);
|
||||
X509_add_ext(x,ex,-1);
|
||||
|
||||
X509v3_pack_string(&data,V_ASN1_BIT_STRING,
|
||||
"www.cryptsoft.com",-1);
|
||||
X509_EXTENSION_create_by_NID(&ex,NID_netscape_ssl_server_name,0,data);
|
||||
X509_add_ext(x,ex,-1);
|
||||
|
||||
X509_EXTENSION_free(ex);
|
||||
ASN1_OCTET_STRING_free(data);
|
||||
|
||||
if (!X509_sign(x,pk,EVP_md5()))
|
||||
goto err;
|
||||
|
||||
*x509p=x;
|
||||
*pkeyp=pk;
|
||||
return(1);
|
||||
err:
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
14
demos/sign/cert.pem
Normal file
14
demos/sign/cert.pem
Normal file
@@ -0,0 +1,14 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICLDCCAdYCAQAwDQYJKoZIhvcNAQEEBQAwgaAxCzAJBgNVBAYTAlBUMRMwEQYD
|
||||
VQQIEwpRdWVlbnNsYW5kMQ8wDQYDVQQHEwZMaXNib2ExFzAVBgNVBAoTDk5ldXJv
|
||||
bmlvLCBMZGEuMRgwFgYDVQQLEw9EZXNlbnZvbHZpbWVudG8xGzAZBgNVBAMTEmJy
|
||||
dXR1cy5uZXVyb25pby5wdDEbMBkGCSqGSIb3DQEJARYMc2FtcG9AaWtpLmZpMB4X
|
||||
DTk2MDkwNTAzNDI0M1oXDTk2MTAwNTAzNDI0M1owgaAxCzAJBgNVBAYTAlBUMRMw
|
||||
EQYDVQQIEwpRdWVlbnNsYW5kMQ8wDQYDVQQHEwZMaXNib2ExFzAVBgNVBAoTDk5l
|
||||
dXJvbmlvLCBMZGEuMRgwFgYDVQQLEw9EZXNlbnZvbHZpbWVudG8xGzAZBgNVBAMT
|
||||
EmJydXR1cy5uZXVyb25pby5wdDEbMBkGCSqGSIb3DQEJARYMc2FtcG9AaWtpLmZp
|
||||
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAL7+aty3S1iBA/+yxjxv4q1MUTd1kjNw
|
||||
L4lYKbpzzlmC5beaQXeQ2RmGMTXU+mDvuqItjVHOK3DvPK7lTcSGftUCAwEAATAN
|
||||
BgkqhkiG9w0BAQQFAANBAFqPEKFjk6T6CKTHvaQeEAsX0/8YHPHqH/9AnhSjrwuX
|
||||
9EBc0n6bVGhN7XaXd6sJ7dym9sbsWxb+pJdurnkxjx4=
|
||||
-----END CERTIFICATE-----
|
||||
9
demos/sign/key.pem
Normal file
9
demos/sign/key.pem
Normal file
@@ -0,0 +1,9 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIBPAIBAAJBAL7+aty3S1iBA/+yxjxv4q1MUTd1kjNwL4lYKbpzzlmC5beaQXeQ
|
||||
2RmGMTXU+mDvuqItjVHOK3DvPK7lTcSGftUCAwEAAQJBALjkK+jc2+iihI98riEF
|
||||
oudmkNziSRTYjnwjx8mCoAjPWviB3c742eO3FG4/soi1jD9A5alihEOXfUzloenr
|
||||
8IECIQD3B5+0l+68BA/6d76iUNqAAV8djGTzvxnCxycnxPQydQIhAMXt4trUI3nc
|
||||
a+U8YL2HPFA3gmhBsSICbq2OptOCnM7hAiEA6Xi3JIQECob8YwkRj29DU3/4WYD7
|
||||
WLPgsQpwo1GuSpECICGsnWH5oaeD9t9jbFoSfhJvv0IZmxdcLpRcpslpeWBBAiEA
|
||||
6/5B8J0GHdJq89FHwEG/H2eVVUYu5y/aD6sgcm+0Avg=
|
||||
-----END RSA PRIVATE KEY-----
|
||||
158
demos/sign/sig.txt
Normal file
158
demos/sign/sig.txt
Normal file
@@ -0,0 +1,158 @@
|
||||
From ssl-lists-owner@mincom.com Mon Sep 30 02:37:40 1996
|
||||
Received: from cygnus.mincom.oz.au by orb.mincom.oz.au with SMTP id AA11782
|
||||
(5.65c/IDA-1.4.4 for eay); Mon, 30 Sep 1996 11:46:21 +1000
|
||||
Received: (from daemon@localhost) by cygnus.mincom.oz.au (8.7.5/8.7.3) id LAA18980 for ssl-users-outgoing; Mon, 30 Sep 1996 11:44:56 +1000 (EST)
|
||||
Received: from minbne.mincom.oz.au (minbne.mincom.oz.au [192.55.196.247]) by cygnus.mincom.oz.au (8.7.5/8.7.3) with SMTP id LAA18962 for <ssl-users@listserv.mincom.oz.au>; Mon, 30 Sep 1996 11:44:51 +1000 (EST)
|
||||
Received: by minbne.mincom.oz.au id AA22230
|
||||
(5.65c/IDA-1.4.4 for ssl-users@listserv.mincom.oz.au); Mon, 30 Sep 1996 11:38:41 +1000
|
||||
Received: from brutus.neuronio.pt (brutus.neuronio.pt [193.126.253.2]) by bunyip.cc.uq.oz.au (8.7.6/8.7.3) with SMTP id LAA15824 for <ssl-users@mincom.com>; Mon, 30 Sep 1996 11:40:07 +1000
|
||||
Received: (from sampo@localhost) by brutus.neuronio.pt (8.6.11/8.6.11) id BAA08729; Mon, 30 Sep 1996 01:37:40 +0100
|
||||
Date: Mon, 30 Sep 1996 01:37:40 +0100
|
||||
Message-Id: <199609300037.BAA08729@brutus.neuronio.pt>
|
||||
From: Sampo Kellomaki <sampo@neuronio.pt>
|
||||
To: ssl-users@mincom.com
|
||||
Cc: sampo@brutus.neuronio.pt
|
||||
Subject: Signing with envelope routines
|
||||
Sender: ssl-lists-owner@mincom.com
|
||||
Precedence: bulk
|
||||
Status: RO
|
||||
X-Status: D
|
||||
|
||||
|
||||
I have been trying to figure out how to produce signatures with EVP_
|
||||
routines. I seem to be able to read in private key and sign some
|
||||
data ok, but I can't figure out how I am supposed to read in
|
||||
public key so that I could verify my signature. I use self signed
|
||||
certificate.
|
||||
|
||||
I figured I should use
|
||||
EVP_PKEY* pkey = PEM_ASN1_read(d2i_PrivateKey, PEM_STRING_EVP_PKEY,
|
||||
fp, NULL, NULL);
|
||||
to read in private key and this seems to work Ok.
|
||||
|
||||
However when I try analogous
|
||||
EVP_PKEY* pkey = PEM_ASN1_read(d2i_PublicKey, PEM_STRING_X509,
|
||||
fp, NULL, NULL);
|
||||
the program fails with
|
||||
|
||||
error:0D09508D:asn1 encoding routines:D2I_PUBLICKEY:unknown public key type:d2i_pu.c:93
|
||||
error:0906700D:PEM routines:PEM_ASN1_read_bio:ASN1 lib:pem_lib.c:232
|
||||
|
||||
I figured that the second argument to PEM_ASN1_read should match the
|
||||
name in my PEM encoded object, hence PEM_STRING_X509.
|
||||
PEM_STRING_EVP_PKEY seems to be somehow magical
|
||||
because it matches whatever private key there happens to be. I could
|
||||
not find a similar constant to use with getting the certificate, however.
|
||||
|
||||
Is my approach of using PEM_ASN1_read correct? What should I pass in
|
||||
as name? Can I use normal (or even self signed) X509 certificate for
|
||||
verifying the signature?
|
||||
|
||||
When will SSLeay documentation be written ;-)? If I would contribute
|
||||
comments to the code, would Eric take time to review them and include
|
||||
them in distribution?
|
||||
|
||||
I'm using SSLeay-0.6.4. My program is included below along with the
|
||||
key and cert that I use.
|
||||
|
||||
--Sampo
|
||||
|
||||
-----------------------------------
|
||||
/* sign-it.cpp - Simple test app using SSLeay envelopes to sign data
|
||||
29.9.1996, Sampo Kellomaki <sampo@iki.fi> */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "rsa.h"
|
||||
#include "evp.h"
|
||||
#include "objects.h"
|
||||
#include "x509.h"
|
||||
#include "err.h"
|
||||
#include "pem.h"
|
||||
#include "ssl.h"
|
||||
|
||||
void main ()
|
||||
{
|
||||
int err;
|
||||
int sig_len;
|
||||
unsigned char sig_buf [4096];
|
||||
const char certfile[] = "plain-cert.pem";
|
||||
const char keyfile[] = "plain-key.pem";
|
||||
const char data[] = "I owe you...";
|
||||
EVP_MD_CTX md_ctx;
|
||||
EVP_PKEY* pkey;
|
||||
FILE* fp;
|
||||
|
||||
SSL_load_error_strings();
|
||||
|
||||
/* Read private key */
|
||||
|
||||
fp = fopen (keyfile, "r"); if (fp == NULL) exit (1);
|
||||
pkey = (EVP_PKEY*)PEM_ASN1_read ((char *(*)())d2i_PrivateKey,
|
||||
PEM_STRING_EVP_PKEY,
|
||||
fp,
|
||||
NULL, NULL);
|
||||
if (pkey == NULL) { ERR_print_errors_fp (stderr); exit (1); }
|
||||
fclose (fp);
|
||||
|
||||
/* Do the signature */
|
||||
|
||||
EVP_SignInit (&md_ctx, EVP_md5());
|
||||
EVP_SignUpdate (&md_ctx, data, strlen(data));
|
||||
sig_len = sizeof(sig_buf);
|
||||
err = EVP_SignFinal (&md_ctx,
|
||||
sig_buf,
|
||||
&sig_len,
|
||||
pkey);
|
||||
if (err != 1) { ERR_print_errors_fp (stderr); exit (1); }
|
||||
EVP_PKEY_free (pkey);
|
||||
|
||||
/* Read public key */
|
||||
|
||||
fp = fopen (certfile, "r"); if (fp == NULL) exit (1);
|
||||
pkey = (EVP_PKEY*)PEM_ASN1_read ((char *(*)())d2i_PublicKey,
|
||||
PEM_STRING_X509,
|
||||
fp,
|
||||
NULL, NULL);
|
||||
if (pkey == NULL) { ERR_print_errors_fp (stderr); exit (1); }
|
||||
fclose (fp);
|
||||
|
||||
/* Verify the signature */
|
||||
|
||||
EVP_VerifyInit (&md_ctx, EVP_md5());
|
||||
EVP_VerifyUpdate (&md_ctx, data, strlen((char*)data));
|
||||
err = EVP_VerifyFinal (&md_ctx,
|
||||
sig_buf,
|
||||
sig_len,
|
||||
pkey);
|
||||
if (err != 1) { ERR_print_errors_fp (stderr); exit (1); }
|
||||
EVP_PKEY_free (pkey);
|
||||
printf ("Signature Verified Ok.\n");
|
||||
}
|
||||
/* EOF */
|
||||
--------------- plain-cert.pem -----------------
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICLDCCAdYCAQAwDQYJKoZIhvcNAQEEBQAwgaAxCzAJBgNVBAYTAlBUMRMwEQYD
|
||||
VQQIEwpRdWVlbnNsYW5kMQ8wDQYDVQQHEwZMaXNib2ExFzAVBgNVBAoTDk5ldXJv
|
||||
bmlvLCBMZGEuMRgwFgYDVQQLEw9EZXNlbnZvbHZpbWVudG8xGzAZBgNVBAMTEmJy
|
||||
dXR1cy5uZXVyb25pby5wdDEbMBkGCSqGSIb3DQEJARYMc2FtcG9AaWtpLmZpMB4X
|
||||
DTk2MDkwNTAzNDI0M1oXDTk2MTAwNTAzNDI0M1owgaAxCzAJBgNVBAYTAlBUMRMw
|
||||
EQYDVQQIEwpRdWVlbnNsYW5kMQ8wDQYDVQQHEwZMaXNib2ExFzAVBgNVBAoTDk5l
|
||||
dXJvbmlvLCBMZGEuMRgwFgYDVQQLEw9EZXNlbnZvbHZpbWVudG8xGzAZBgNVBAMT
|
||||
EmJydXR1cy5uZXVyb25pby5wdDEbMBkGCSqGSIb3DQEJARYMc2FtcG9AaWtpLmZp
|
||||
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAL7+aty3S1iBA/+yxjxv4q1MUTd1kjNw
|
||||
L4lYKbpzzlmC5beaQXeQ2RmGMTXU+mDvuqItjVHOK3DvPK7lTcSGftUCAwEAATAN
|
||||
BgkqhkiG9w0BAQQFAANBAFqPEKFjk6T6CKTHvaQeEAsX0/8YHPHqH/9AnhSjrwuX
|
||||
9EBc0n6bVGhN7XaXd6sJ7dym9sbsWxb+pJdurnkxjx4=
|
||||
-----END CERTIFICATE-----
|
||||
---------------- plain-key.pem -----------------
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIBPAIBAAJBAL7+aty3S1iBA/+yxjxv4q1MUTd1kjNwL4lYKbpzzlmC5beaQXeQ
|
||||
2RmGMTXU+mDvuqItjVHOK3DvPK7lTcSGftUCAwEAAQJBALjkK+jc2+iihI98riEF
|
||||
oudmkNziSRTYjnwjx8mCoAjPWviB3c742eO3FG4/soi1jD9A5alihEOXfUzloenr
|
||||
8IECIQD3B5+0l+68BA/6d76iUNqAAV8djGTzvxnCxycnxPQydQIhAMXt4trUI3nc
|
||||
a+U8YL2HPFA3gmhBsSICbq2OptOCnM7hAiEA6Xi3JIQECob8YwkRj29DU3/4WYD7
|
||||
WLPgsQpwo1GuSpECICGsnWH5oaeD9t9jbFoSfhJvv0IZmxdcLpRcpslpeWBBAiEA
|
||||
6/5B8J0GHdJq89FHwEG/H2eVVUYu5y/aD6sgcm+0Avg=
|
||||
-----END RSA PRIVATE KEY-----
|
||||
------------------------------------------------
|
||||
|
||||
137
demos/sign/sign.c
Normal file
137
demos/sign/sign.c
Normal file
@@ -0,0 +1,137 @@
|
||||
/* demos/sign/sign.c */
|
||||
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* 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 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 acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS 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 AUTHOR OR 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.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
/* sign-it.cpp - Simple test app using SSLeay envelopes to sign data
|
||||
29.9.1996, Sampo Kellomaki <sampo@iki.fi> */
|
||||
|
||||
/* converted to C - eay :-) */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "rsa.h"
|
||||
#include "evp.h"
|
||||
#include "objects.h"
|
||||
#include "x509.h"
|
||||
#include "err.h"
|
||||
#include "pem.h"
|
||||
#include "ssl.h"
|
||||
|
||||
void main ()
|
||||
{
|
||||
int err;
|
||||
int sig_len;
|
||||
unsigned char sig_buf [4096];
|
||||
static char certfile[] = "cert.pem";
|
||||
static char keyfile[] = "key.pem";
|
||||
static char data[] = "I owe you...";
|
||||
EVP_MD_CTX md_ctx;
|
||||
EVP_PKEY * pkey;
|
||||
FILE * fp;
|
||||
X509 * x509;
|
||||
|
||||
/* Just load the crypto library error strings,
|
||||
* SSL_load_error_strings() loads the crypto AND the SSL ones */
|
||||
/* SSL_load_error_strings();*/
|
||||
ERR_load_crypto_strings();
|
||||
|
||||
/* Read private key */
|
||||
|
||||
fp = fopen (keyfile, "r"); if (fp == NULL) exit (1);
|
||||
pkey = (EVP_PKEY*)PEM_ASN1_read ((char *(*)())d2i_PrivateKey,
|
||||
PEM_STRING_EVP_PKEY,
|
||||
fp,
|
||||
NULL, NULL);
|
||||
if (pkey == NULL) { ERR_print_errors_fp (stderr); exit (1); }
|
||||
fclose (fp);
|
||||
|
||||
/* Do the signature */
|
||||
|
||||
EVP_SignInit (&md_ctx, EVP_md5());
|
||||
EVP_SignUpdate (&md_ctx, data, strlen(data));
|
||||
sig_len = sizeof(sig_buf);
|
||||
err = EVP_SignFinal (&md_ctx,
|
||||
sig_buf,
|
||||
&sig_len,
|
||||
pkey);
|
||||
if (err != 1) { ERR_print_errors_fp (stderr); exit (1); }
|
||||
EVP_PKEY_free (pkey);
|
||||
|
||||
/* Read public key */
|
||||
|
||||
fp = fopen (certfile, "r"); if (fp == NULL) exit (1);
|
||||
x509 = (X509 *)PEM_ASN1_read ((char *(*)())d2i_X509,
|
||||
PEM_STRING_X509,
|
||||
fp, NULL, NULL);
|
||||
if (x509 == NULL) { ERR_print_errors_fp (stderr); exit (1); }
|
||||
fclose (fp);
|
||||
|
||||
/* Get public key - eay */
|
||||
pkey=X509_extract_key(x509);
|
||||
if (pkey == NULL) { ERR_print_errors_fp (stderr); exit (1); }
|
||||
|
||||
/* Verify the signature */
|
||||
|
||||
EVP_VerifyInit (&md_ctx, EVP_md5());
|
||||
EVP_VerifyUpdate (&md_ctx, data, strlen((char*)data));
|
||||
err = EVP_VerifyFinal (&md_ctx,
|
||||
sig_buf,
|
||||
sig_len,
|
||||
pkey);
|
||||
if (err != 1) { ERR_print_errors_fp (stderr); exit (1); }
|
||||
EVP_PKEY_free (pkey);
|
||||
printf ("Signature Verified Ok.\n");
|
||||
}
|
||||
170
demos/sign/sign.txt
Normal file
170
demos/sign/sign.txt
Normal file
@@ -0,0 +1,170 @@
|
||||
From ssl-lists-owner@mincom.com Mon Sep 30 22:43:15 1996
|
||||
Received: from cygnus.mincom.oz.au by orb.mincom.oz.au with SMTP id AA12802
|
||||
(5.65c/IDA-1.4.4 for eay); Mon, 30 Sep 1996 12:45:43 +1000
|
||||
Received: (from daemon@localhost) by cygnus.mincom.oz.au (8.7.5/8.7.3) id MAA25922 for ssl-users-outgoing; Mon, 30 Sep 1996 12:43:43 +1000 (EST)
|
||||
Received: from orb.mincom.oz.au (eay@orb.mincom.oz.au [192.55.197.1]) by cygnus.mincom.oz.au (8.7.5/8.7.3) with SMTP id MAA25900 for <ssl-users@listserv.mincom.oz.au>; Mon, 30 Sep 1996 12:43:39 +1000 (EST)
|
||||
Received: by orb.mincom.oz.au id AA12688
|
||||
(5.65c/IDA-1.4.4 for ssl-users@listserv.mincom.oz.au); Mon, 30 Sep 1996 12:43:16 +1000
|
||||
Date: Mon, 30 Sep 1996 12:43:15 +1000 (EST)
|
||||
From: Eric Young <eay@mincom.com>
|
||||
X-Sender: eay@orb
|
||||
To: Sampo Kellomaki <sampo@neuronio.pt>
|
||||
Cc: ssl-users@mincom.com, sampo@brutus.neuronio.pt
|
||||
Subject: Re: Signing with envelope routines
|
||||
In-Reply-To: <199609300037.BAA08729@brutus.neuronio.pt>
|
||||
Message-Id: <Pine.SOL.3.91.960930121504.11800Y-100000@orb>
|
||||
Mime-Version: 1.0
|
||||
Content-Type: TEXT/PLAIN; charset=US-ASCII
|
||||
Sender: ssl-lists-owner@mincom.com
|
||||
Precedence: bulk
|
||||
Status: O
|
||||
X-Status:
|
||||
|
||||
|
||||
On Mon, 30 Sep 1996, Sampo Kellomaki wrote:
|
||||
> I have been trying to figure out how to produce signatures with EVP_
|
||||
> routines. I seem to be able to read in private key and sign some
|
||||
> data ok, but I can't figure out how I am supposed to read in
|
||||
> public key so that I could verify my signature. I use self signed
|
||||
> certificate.
|
||||
|
||||
hmm... a rather poorly documented are of the library at this point in time.
|
||||
|
||||
> I figured I should use
|
||||
> EVP_PKEY* pkey = PEM_ASN1_read(d2i_PrivateKey, PEM_STRING_EVP_PKEY,
|
||||
> fp, NULL, NULL);
|
||||
> to read in private key and this seems to work Ok.
|
||||
>
|
||||
> However when I try analogous
|
||||
> EVP_PKEY* pkey = PEM_ASN1_read(d2i_PublicKey, PEM_STRING_X509,
|
||||
> fp, NULL, NULL);
|
||||
|
||||
What you should do is
|
||||
X509 *x509=PEM_read_X509(fp,NULL,NULL);
|
||||
/* which is the same as PEM_ASN1_read(d2i_X509,PEM_STRING_X509,fp,
|
||||
* NULL,NULL); */
|
||||
Then
|
||||
EVP_PKEY *pkey=X509_extract_key(x509);
|
||||
|
||||
There is also a X509_REQ_extract_key(req);
|
||||
which gets the public key from a certificate request.
|
||||
|
||||
I re-worked quite a bit of this when I cleaned up the dependancy on
|
||||
RSA as the private key.
|
||||
|
||||
> I figured that the second argument to PEM_ASN1_read should match the
|
||||
> name in my PEM encoded object, hence PEM_STRING_X509.
|
||||
> PEM_STRING_EVP_PKEY seems to be somehow magical
|
||||
> because it matches whatever private key there happens to be. I could
|
||||
> not find a similar constant to use with getting the certificate, however.
|
||||
|
||||
:-), PEM_STRING_EVP_PKEY is 'magical' :-). In theory I should be using a
|
||||
standard such as PKCS#8 to store the private key so that the type is
|
||||
encoded in the asn.1 encoding of the object.
|
||||
|
||||
> Is my approach of using PEM_ASN1_read correct? What should I pass in
|
||||
> as name? Can I use normal (or even self signed) X509 certificate for
|
||||
> verifying the signature?
|
||||
|
||||
The actual public key is kept in the certificate, so basically you have
|
||||
to load the certificate and then 'unpack' the public key from the
|
||||
certificate.
|
||||
|
||||
> When will SSLeay documentation be written ;-)? If I would contribute
|
||||
> comments to the code, would Eric take time to review them and include
|
||||
> them in distribution?
|
||||
|
||||
:-) After SSLv3 and PKCS#7 :-). I actually started doing a function list
|
||||
but what I really need to do is do quite a few 'this is how you do xyz'
|
||||
type documents. I suppose the current method is to post to ssl-users and
|
||||
I'll respond :-).
|
||||
|
||||
I'll add a 'demo' directory for the next release, I've appended a
|
||||
modified version of your program that works, you were very close :-).
|
||||
|
||||
eric
|
||||
|
||||
/* sign-it.cpp - Simple test app using SSLeay envelopes to sign data
|
||||
29.9.1996, Sampo Kellomaki <sampo@iki.fi> */
|
||||
|
||||
/* converted to C - eay :-) */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "rsa.h"
|
||||
#include "evp.h"
|
||||
#include "objects.h"
|
||||
#include "x509.h"
|
||||
#include "err.h"
|
||||
#include "pem.h"
|
||||
#include "ssl.h"
|
||||
|
||||
void main ()
|
||||
{
|
||||
int err;
|
||||
int sig_len;
|
||||
unsigned char sig_buf [4096];
|
||||
static char certfile[] = "plain-cert.pem";
|
||||
static char keyfile[] = "plain-key.pem";
|
||||
static char data[] = "I owe you...";
|
||||
EVP_MD_CTX md_ctx;
|
||||
EVP_PKEY * pkey;
|
||||
FILE * fp;
|
||||
X509 * x509;
|
||||
|
||||
/* Just load the crypto library error strings,
|
||||
* SSL_load_error_strings() loads the crypto AND the SSL ones */
|
||||
/* SSL_load_error_strings();*/
|
||||
ERR_load_crypto_strings();
|
||||
|
||||
/* Read private key */
|
||||
|
||||
fp = fopen (keyfile, "r"); if (fp == NULL) exit (1);
|
||||
pkey = (EVP_PKEY*)PEM_ASN1_read ((char *(*)())d2i_PrivateKey,
|
||||
PEM_STRING_EVP_PKEY,
|
||||
fp,
|
||||
NULL, NULL);
|
||||
if (pkey == NULL) { ERR_print_errors_fp (stderr); exit (1); }
|
||||
fclose (fp);
|
||||
|
||||
/* Do the signature */
|
||||
|
||||
EVP_SignInit (&md_ctx, EVP_md5());
|
||||
EVP_SignUpdate (&md_ctx, data, strlen(data));
|
||||
sig_len = sizeof(sig_buf);
|
||||
err = EVP_SignFinal (&md_ctx,
|
||||
sig_buf,
|
||||
&sig_len,
|
||||
pkey);
|
||||
if (err != 1) { ERR_print_errors_fp (stderr); exit (1); }
|
||||
EVP_PKEY_free (pkey);
|
||||
|
||||
/* Read public key */
|
||||
|
||||
fp = fopen (certfile, "r"); if (fp == NULL) exit (1);
|
||||
x509 = (X509 *)PEM_ASN1_read ((char *(*)())d2i_X509,
|
||||
PEM_STRING_X509,
|
||||
fp, NULL, NULL);
|
||||
if (x509 == NULL) { ERR_print_errors_fp (stderr); exit (1); }
|
||||
fclose (fp);
|
||||
|
||||
/* Get public key - eay */
|
||||
pkey=X509_extract_key(x509);
|
||||
if (pkey == NULL) { ERR_print_errors_fp (stderr); exit (1); }
|
||||
|
||||
/* Verify the signature */
|
||||
|
||||
EVP_VerifyInit (&md_ctx, EVP_md5());
|
||||
EVP_VerifyUpdate (&md_ctx, data, strlen((char*)data));
|
||||
err = EVP_VerifyFinal (&md_ctx,
|
||||
sig_buf,
|
||||
sig_len,
|
||||
pkey);
|
||||
if (err != 1) { ERR_print_errors_fp (stderr); exit (1); }
|
||||
EVP_PKEY_free (pkey);
|
||||
printf ("Signature Verified Ok.\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
160
demos/spkigen.c
Normal file
160
demos/spkigen.c
Normal file
@@ -0,0 +1,160 @@
|
||||
/* NOCW */
|
||||
/* demos/spkigen.c
|
||||
* 18-Mar-1997 - eay - A quick hack :-)
|
||||
* version 1.1, it would probably help to save or load the
|
||||
* private key :-)
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "err.h"
|
||||
#include "asn1.h"
|
||||
#include "objects.h"
|
||||
#include "evp.h"
|
||||
#include "x509.h"
|
||||
#include "pem.h"
|
||||
|
||||
/* The following two don't exist in SSLeay but they are in here as
|
||||
* examples */
|
||||
#define PEM_write_SPKI(fp,x) \
|
||||
PEM_ASN1_write((int (*)())i2d_NETSCAPE_SPKI,"SPKI",fp,\
|
||||
(char *)x,NULL,NULL,0,NULL)
|
||||
int SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey);
|
||||
|
||||
/* These are defined in the next version of SSLeay */
|
||||
int EVP_PKEY_assign(EVP_PKEY *pkey, int type,char *key);
|
||||
#define RSA_F4 0x10001
|
||||
#define EVP_PKEY_assign_RSA(pkey,rsa) EVP_PKEY_assign((pkey),EVP_PKEY_RSA,\
|
||||
(char *)(rsa))
|
||||
|
||||
int main(argc,argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
RSA *rsa=NULL;
|
||||
NETSCAPE_SPKI *spki=NULL;
|
||||
EVP_PKEY *pkey=NULL;
|
||||
char buf[128];
|
||||
int ok=0,i;
|
||||
FILE *fp;
|
||||
|
||||
pkey=EVP_PKEY_new();
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
/* Generate an RSA key, the random state should have been seeded
|
||||
* with lots of calls to RAND_seed(....) */
|
||||
fprintf(stderr,"generating RSA key, could take some time...\n");
|
||||
if ((rsa=RSA_generate_key(512,RSA_F4,NULL)) == NULL) goto err;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((fp=fopen(argv[1],"r")) == NULL)
|
||||
{ perror(argv[1]); goto err; }
|
||||
if ((rsa=PEM_read_RSAPrivateKey(fp,NULL,NULL)) == NULL)
|
||||
goto err;
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
if (!EVP_PKEY_assign_RSA(pkey,rsa)) goto err;
|
||||
rsa=NULL;
|
||||
|
||||
/* lets make the spki and set the public key and challenge */
|
||||
if ((spki=NETSCAPE_SPKI_new()) == NULL) goto err;
|
||||
|
||||
if (!SPKI_set_pubkey(spki,pkey)) goto err;
|
||||
|
||||
fprintf(stderr,"please enter challenge string:");
|
||||
fflush(stderr);
|
||||
fgets(buf,120,stdin);
|
||||
i=strlen(buf);
|
||||
if (i > 0) buf[--i]='\0';
|
||||
if (!ASN1_STRING_set((ASN1_STRING *)spki->spkac->challenge,
|
||||
buf,i)) goto err;
|
||||
|
||||
if (!NETSCAPE_SPKI_sign(spki,pkey,EVP_md5())) goto err;
|
||||
PEM_write_SPKI(stdout,spki);
|
||||
if (argc < 2)
|
||||
PEM_write_RSAPrivateKey(stdout,pkey->pkey.rsa,NULL,NULL,0,NULL);
|
||||
|
||||
ok=1;
|
||||
err:
|
||||
if (!ok)
|
||||
{
|
||||
fprintf(stderr,"something bad happened....");
|
||||
ERR_print_errors_fp(stderr);
|
||||
}
|
||||
NETSCAPE_SPKI_free(spki);
|
||||
EVP_PKEY_free(pkey);
|
||||
exit(!ok);
|
||||
}
|
||||
|
||||
/* This function is in the next version of SSLeay */
|
||||
int EVP_PKEY_assign(pkey,type,key)
|
||||
EVP_PKEY *pkey;
|
||||
int type;
|
||||
char *key;
|
||||
{
|
||||
if (pkey == NULL) return(0);
|
||||
if (pkey->pkey.ptr != NULL)
|
||||
{
|
||||
if (pkey->type == EVP_PKEY_RSA)
|
||||
RSA_free(pkey->pkey.rsa);
|
||||
/* else memory leak */
|
||||
}
|
||||
pkey->type=type;
|
||||
pkey->pkey.ptr=key;
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* While I have a
|
||||
* X509_set_pubkey() and X509_REQ_set_pubkey(), SPKI_set_pubkey() does
|
||||
* not currently exist so here is a version of it.
|
||||
* The next SSLeay release will probably have
|
||||
* X509_set_pubkey(),
|
||||
* X509_REQ_set_pubkey() and
|
||||
* NETSCAPE_SPKI_set_pubkey()
|
||||
* as macros calling the same function */
|
||||
int SPKI_set_pubkey(x,pkey)
|
||||
NETSCAPE_SPKI *x;
|
||||
EVP_PKEY *pkey;
|
||||
{
|
||||
int ok=0;
|
||||
X509_PUBKEY *pk;
|
||||
X509_ALGOR *a;
|
||||
ASN1_OBJECT *o;
|
||||
unsigned char *s,*p;
|
||||
int i;
|
||||
|
||||
if (x == NULL) return(0);
|
||||
|
||||
if ((pk=X509_PUBKEY_new()) == NULL) goto err;
|
||||
a=pk->algor;
|
||||
|
||||
/* set the algorithm id */
|
||||
if ((o=OBJ_nid2obj(pkey->type)) == NULL) goto err;
|
||||
ASN1_OBJECT_free(a->algorithm);
|
||||
a->algorithm=o;
|
||||
|
||||
/* Set the parameter list */
|
||||
if ((a->parameter == NULL) || (a->parameter->type != V_ASN1_NULL))
|
||||
{
|
||||
ASN1_TYPE_free(a->parameter);
|
||||
a->parameter=ASN1_TYPE_new();
|
||||
a->parameter->type=V_ASN1_NULL;
|
||||
}
|
||||
i=i2d_PublicKey(pkey,NULL);
|
||||
if ((s=(unsigned char *)malloc(i+1)) == NULL) goto err;
|
||||
p=s;
|
||||
i2d_PublicKey(pkey,&p);
|
||||
if (!ASN1_BIT_STRING_set(pk->public_key,s,i)) goto err;
|
||||
free(s);
|
||||
|
||||
X509_PUBKEY_free(x->spkac->pubkey);
|
||||
x->spkac->pubkey=pk;
|
||||
pk=NULL;
|
||||
ok=1;
|
||||
err:
|
||||
if (pk != NULL) X509_PUBKEY_free(pk);
|
||||
return(ok);
|
||||
}
|
||||
|
||||
102
demos/ssl/cli.cpp
Normal file
102
demos/ssl/cli.cpp
Normal file
@@ -0,0 +1,102 @@
|
||||
/* cli.cpp - Minimal ssleay client for Unix
|
||||
30.9.1996, Sampo Kellomaki <sampo@iki.fi> */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <memory.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#include "rsa.h" /* SSLeay stuff */
|
||||
#include "crypto.h"
|
||||
#include "x509.h"
|
||||
#include "pem.h"
|
||||
#include "ssl.h"
|
||||
#include "err.h"
|
||||
|
||||
#define CHK_NULL(x) if ((x)==NULL) exit (1)
|
||||
#define CHK_ERR(err,s) if ((err)==-1) { perror(s); exit(1); }
|
||||
#define CHK_SSL(err) if ((err)==-1) { ERR_print_errors_fp(stderr); exit(2); }
|
||||
|
||||
void main ()
|
||||
{
|
||||
int err;
|
||||
int sd;
|
||||
struct sockaddr_in sa;
|
||||
SSL_CTX* ctx;
|
||||
SSL* ssl;
|
||||
X509* server_cert;
|
||||
char* str;
|
||||
char buf [4096];
|
||||
|
||||
SSL_load_error_strings();
|
||||
ctx = SSL_CTX_new (); CHK_NULL(ctx);
|
||||
|
||||
/* ----------------------------------------------- */
|
||||
/* Create a socket and connect to server using normal socket calls. */
|
||||
|
||||
sd = socket (AF_INET, SOCK_STREAM, 0); CHK_ERR(sd, "socket");
|
||||
|
||||
memset (&sa, '\0', sizeof(sa));
|
||||
sa.sin_family = AF_INET;
|
||||
sa.sin_addr.s_addr = inet_addr ("127.0.0.1"); /* Server IP */
|
||||
sa.sin_port = htons (1111); /* Server Port number */
|
||||
|
||||
err = connect(sd, (struct sockaddr*) &sa,
|
||||
sizeof(sa)); CHK_ERR(err, "connect");
|
||||
|
||||
/* ----------------------------------------------- */
|
||||
/* Now we have TCP conncetion. Start SSL negotiation. */
|
||||
|
||||
ssl = SSL_new (ctx); CHK_NULL(ssl);
|
||||
SSL_set_fd (ssl, sd);
|
||||
err = SSL_connect (ssl); CHK_SSL(err);
|
||||
|
||||
/* Following two steps are optional and not required for
|
||||
data exchange to be successful. */
|
||||
|
||||
/* Get the cipher - opt */
|
||||
|
||||
printf ("SSL connection using %s\n", SSL_get_cipher (ssl));
|
||||
|
||||
/* Get server's certificate (note: beware of dynamic allocation) - opt */
|
||||
|
||||
server_cert = SSL_get_peer_certificate (ssl); CHK_NULL(server_cert);
|
||||
printf ("Server certificate:\n");
|
||||
|
||||
str = X509_NAME_oneline (X509_get_subject_name (server_cert));
|
||||
CHK_NULL(str);
|
||||
printf ("\t subject: %s\n", str);
|
||||
Free (str);
|
||||
|
||||
str = X509_NAME_oneline (X509_get_issuer_name (server_cert));
|
||||
CHK_NULL(str);
|
||||
printf ("\t issuer: %s\n", str);
|
||||
Free (str);
|
||||
|
||||
/* We could do all sorts of certificate verification stuff here before
|
||||
deallocating the certificate. */
|
||||
|
||||
X509_free (server_cert);
|
||||
|
||||
/* --------------------------------------------------- */
|
||||
/* DATA EXCHANGE - Send a message and receive a reply. */
|
||||
|
||||
err = SSL_write (ssl, "Hello World!", strlen("Hello World!")); CHK_SSL(err);
|
||||
|
||||
shutdown (sd, 1); /* Half close, send EOF to server. */
|
||||
|
||||
err = SSL_read (ssl, buf, sizeof(buf) - 1); CHK_SSL(err);
|
||||
buf[err] = '\0';
|
||||
printf ("Got %d chars:'%s'\n", err, buf);
|
||||
|
||||
/* Clean up. */
|
||||
|
||||
close (sd);
|
||||
SSL_free (ssl);
|
||||
SSL_CTX_free (ctx);
|
||||
}
|
||||
/* EOF - cli.cpp */
|
||||
98
demos/ssl/inetdsrv.cpp
Normal file
98
demos/ssl/inetdsrv.cpp
Normal file
@@ -0,0 +1,98 @@
|
||||
/* inetdserv.cpp - Minimal ssleay server for Unix inetd.conf
|
||||
* 30.9.1996, Sampo Kellomaki <sampo@iki.fi>
|
||||
* From /etc/inetd.conf:
|
||||
* 1111 stream tcp nowait sampo /usr/users/sampo/demo/inetdserv inetdserv
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "rsa.h" /* SSLeay stuff */
|
||||
#include "crypto.h"
|
||||
#include "x509.h"
|
||||
#include "pem.h"
|
||||
#include "ssl.h"
|
||||
#include "err.h"
|
||||
|
||||
#define HOME "/usr/users/sampo/demo/"
|
||||
#define CERTF HOME "plain-cert.pem"
|
||||
#define KEYF HOME "plain-key.pem"
|
||||
|
||||
#define CHK_NULL(x) if ((x)==NULL) exit (1)
|
||||
#define CHK_ERR(err,s) if ((err)==-1) \
|
||||
{ fprintf(log, "%s %d\n", (s), errno); exit(1); }
|
||||
#define CHK_SSL(err) if ((err)==-1) { ERR_print_errors_fp(log); exit(2); }
|
||||
|
||||
void main ()
|
||||
{
|
||||
int err;
|
||||
SSL_CTX* ctx;
|
||||
SSL* ssl;
|
||||
X509* client_cert;
|
||||
char* str;
|
||||
char buf [4096];
|
||||
FILE* log;
|
||||
|
||||
log = fopen ("/dev/console", "a"); CHK_NULL(log);
|
||||
fprintf (log, "inetdserv %ld\n", (long)getpid());
|
||||
|
||||
SSL_load_error_strings();
|
||||
ctx = SSL_CTX_new (); CHK_NULL(ctx);
|
||||
|
||||
err = SSL_CTX_use_RSAPrivateKey_file (ctx, KEYF, SSL_FILETYPE_PEM);
|
||||
CHK_SSL (err);
|
||||
|
||||
err = SSL_CTX_use_certificate_file (ctx, CERTF, SSL_FILETYPE_PEM);
|
||||
CHK_SSL (err);
|
||||
|
||||
/* inetd has already opened the TCP connection, so we can get right
|
||||
down to business. */
|
||||
|
||||
ssl = SSL_new (ctx); CHK_NULL(ssl);
|
||||
SSL_set_fd (ssl, fileno(stdin));
|
||||
err = SSL_accept (ssl); CHK_SSL(err);
|
||||
|
||||
/* Get the cipher - opt */
|
||||
|
||||
fprintf (log, "SSL connection using %s\n", SSL_get_cipher (ssl));
|
||||
|
||||
/* Get client's certificate (note: beware of dynamic allocation) - opt */
|
||||
|
||||
client_cert = SSL_get_peer_certificate (ssl);
|
||||
if (client_cert != NULL) {
|
||||
fprintf (log, "Client certificate:\n");
|
||||
|
||||
str = X509_NAME_oneline (X509_get_subject_name (client_cert));
|
||||
CHK_NULL(str);
|
||||
fprintf (log, "\t subject: %s\n", str);
|
||||
Free (str);
|
||||
|
||||
str = X509_NAME_oneline (X509_get_issuer_name (client_cert));
|
||||
CHK_NULL(str);
|
||||
fprintf (log, "\t issuer: %s\n", str);
|
||||
Free (str);
|
||||
|
||||
/* We could do all sorts of certificate verification stuff here before
|
||||
deallocating the certificate. */
|
||||
|
||||
X509_free (client_cert);
|
||||
} else
|
||||
fprintf (log, "Client doe not have certificate.\n");
|
||||
|
||||
/* ------------------------------------------------- */
|
||||
/* DATA EXCHANGE: Receive message and send reply */
|
||||
|
||||
err = SSL_read (ssl, buf, sizeof(buf) - 1); CHK_SSL(err);
|
||||
buf[err] = '\0';
|
||||
fprintf (log, "Got %d chars:'%s'\n", err, buf);
|
||||
|
||||
err = SSL_write (ssl, "Loud and clear.", strlen("Loud and clear."));
|
||||
CHK_SSL(err);
|
||||
|
||||
/* Clean up. */
|
||||
|
||||
fclose (log);
|
||||
SSL_free (ssl);
|
||||
SSL_CTX_free (ctx);
|
||||
}
|
||||
/* EOF - inetdserv.cpp */
|
||||
126
demos/ssl/serv.cpp
Normal file
126
demos/ssl/serv.cpp
Normal file
@@ -0,0 +1,126 @@
|
||||
/* serv.cpp - Minimal ssleay server for Unix
|
||||
30.9.1996, Sampo Kellomaki <sampo@iki.fi> */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <memory.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#include "rsa.h" /* SSLeay stuff */
|
||||
#include "crypto.h"
|
||||
#include "x509.h"
|
||||
#include "pem.h"
|
||||
#include "ssl.h"
|
||||
#include "err.h"
|
||||
|
||||
#define HOME "/usr/users/sampo/sibs/tim/"
|
||||
#define CERTF HOME "plain-cert.pem"
|
||||
#define KEYF HOME "plain-key.pem"
|
||||
|
||||
#define CHK_NULL(x) if ((x)==NULL) exit (1)
|
||||
#define CHK_ERR(err,s) if ((err)==-1) { perror(s); exit(1); }
|
||||
#define CHK_SSL(err) if ((err)==-1) { ERR_print_errors_fp(stderr); exit(2); }
|
||||
|
||||
void main ()
|
||||
{
|
||||
int err;
|
||||
int listen_sd;
|
||||
int sd;
|
||||
struct sockaddr_in sa_serv;
|
||||
struct sockaddr_in sa_cli;
|
||||
int client_len;
|
||||
SSL_CTX* ctx;
|
||||
SSL* ssl;
|
||||
X509* client_cert;
|
||||
char* str;
|
||||
char buf [4096];
|
||||
|
||||
/* SSL preliminaries. We keep the certificate and key with the context. */
|
||||
|
||||
SSL_load_error_strings();
|
||||
ctx = SSL_CTX_new (); CHK_NULL(ctx);
|
||||
|
||||
err = SSL_CTX_use_RSAPrivateKey_file (ctx, KEYF, SSL_FILETYPE_PEM);
|
||||
CHK_SSL(err);
|
||||
|
||||
err = SSL_CTX_use_certificate_file (ctx, CERTF, SSL_FILETYPE_PEM);
|
||||
CHK_SSL(err);
|
||||
|
||||
/* ----------------------------------------------- */
|
||||
/* Prepare TCP socket for receiving connections */
|
||||
|
||||
listen_sd = socket (AF_INET, SOCK_STREAM, 0); CHK_ERR(listen_sd, "socket");
|
||||
|
||||
memset (&sa_serv, '\0', sizeof(sa_serv));
|
||||
sa_serv.sin_family = AF_INET;
|
||||
sa_serv.sin_addr.s_addr = INADDR_ANY;
|
||||
sa_serv.sin_port = htons (1111); /* Server Port number */
|
||||
|
||||
err = bind(listen_sd, (struct sockaddr*) &sa_serv,
|
||||
sizeof (sa_serv)); CHK_ERR(err, "bind");
|
||||
|
||||
/* Receive a TCP connection. */
|
||||
|
||||
err = listen (listen_sd, 5); CHK_ERR(err, "listen");
|
||||
|
||||
client_len = sizeof(sa_cli);
|
||||
sd = accept (listen_sd, (struct sockaddr*) &sa_cli, &client_len);
|
||||
CHK_ERR(sd, "accept");
|
||||
close (listen_sd);
|
||||
|
||||
printf ("Connection from %lx, port %x\n",
|
||||
sa_cli.sin_addr.s_addr, sa_cli.sin_port);
|
||||
|
||||
/* ----------------------------------------------- */
|
||||
/* TCP connection is ready. Do server side SSL. */
|
||||
|
||||
ssl = SSL_new (ctx); CHK_NULL(ssl);
|
||||
SSL_set_fd (ssl, sd);
|
||||
err = SSL_accept (ssl); CHK_SSL(err);
|
||||
|
||||
/* Get the cipher - opt */
|
||||
|
||||
printf ("SSL connection using %s\n", SSL_get_cipher (ssl));
|
||||
|
||||
/* Get client's certificate (note: beware of dynamic allocation) - opt */
|
||||
|
||||
client_cert = SSL_get_peer_certificate (ssl);
|
||||
if (client_cert != NULL) {
|
||||
printf ("Client certificate:\n");
|
||||
|
||||
str = X509_NAME_oneline (X509_get_subject_name (client_cert));
|
||||
CHK_NULL(str);
|
||||
printf ("\t subject: %s\n", str);
|
||||
Free (str);
|
||||
|
||||
str = X509_NAME_oneline (X509_get_issuer_name (client_cert));
|
||||
CHK_NULL(str);
|
||||
printf ("\t issuer: %s\n", str);
|
||||
Free (str);
|
||||
|
||||
/* We could do all sorts of certificate verification stuff here before
|
||||
deallocating the certificate. */
|
||||
|
||||
X509_free (client_cert);
|
||||
} else
|
||||
printf ("Client does not have certificate.\n");
|
||||
|
||||
/* DATA EXCHANGE - Receive message and send reply. */
|
||||
|
||||
err = SSL_read (ssl, buf, sizeof(buf) - 1); CHK_SSL(err);
|
||||
buf[err] = '\0';
|
||||
printf ("Got %d chars:'%s'\n", err, buf);
|
||||
|
||||
err = SSL_write (ssl, "I hear you.", strlen("I hear you.")); CHK_SSL(err);
|
||||
|
||||
/* Clean up. */
|
||||
|
||||
close (sd);
|
||||
SSL_free (ssl);
|
||||
SSL_CTX_free (ctx);
|
||||
}
|
||||
/* EOF - serv.cpp */
|
||||
Reference in New Issue
Block a user