1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-04-21 10:26:06 +03:00

certificate generation

git-svn-id: svn://svn.code.sf.net/p/axtls/code/trunk@143 9a5d90b5-6617-0410-8a86-bb477d3ed2e3
This commit is contained in:
cameronrich 2007-11-29 13:02:54 +00:00
parent 7cac88ca9c
commit bffc3b2197
22 changed files with 391 additions and 283 deletions

View File

@ -240,8 +240,6 @@ namespace axTLS
* - SSL_CLIENT_AUTHENTICATION (server only): Enforce client * - SSL_CLIENT_AUTHENTICATION (server only): Enforce client
* authentication i.e. each handshake will include a "certificate * authentication i.e. each handshake will include a "certificate
* request" message from the server. * request" message from the server.
* - SSL_NO_DEFAULT_KEY: Don't use the default key/certificate. The
* user will load the key/certificate explicitly.
* - SSL_DISPLAY_BYTES (full mode build only): Display the byte * - SSL_DISPLAY_BYTES (full mode build only): Display the byte
* sequences during the handshake. * sequences during the handshake.
* - SSL_DISPLAY_STATES (full mode build only): Display the state * - SSL_DISPLAY_STATES (full mode build only): Display the state

View File

@ -70,6 +70,8 @@ sub parseFile
{ {
foreach $line (@_) foreach $line (@_)
{ {
next if $line =~ /ssl_x509_create/; # ignore for now
# test for a #define # test for a #define
if (!$skip && $line =~ m/^#define/) if (!$skip && $line =~ m/^#define/)
{ {

View File

@ -133,6 +133,8 @@ sub parseFile
foreach $line (@file) foreach $line (@file)
{ {
next if $line =~ /sl_x509_create/; # ignore for now
# test for a #define # test for a #define
if (!$skip && $line =~ m/^#define/) if (!$skip && $line =~ m/^#define/)
{ {

View File

@ -68,8 +68,6 @@ public class SSLCTX
* - SSL_CLIENT_AUTHENTICATION (server only): Enforce client authentication * - SSL_CLIENT_AUTHENTICATION (server only): Enforce client authentication
* i.e. each handshake will include a "certificate request" message from * i.e. each handshake will include a "certificate request" message from
* the server. * the server.
* - SSL_NO_DEFAULT_KEY: Don't use the default key/certificate. The user
* will load the key/certificate explicitly.
* - SSL_DISPLAY_BYTES (full mode build only): Display the byte sequences * - SSL_DISPLAY_BYTES (full mode build only): Display the byte sequences
* during the handshake. * during the handshake.
* - SSL_DISPLAY_STATES (full mode build only): Display the state changes * - SSL_DISPLAY_STATES (full mode build only): Display the state changes

View File

@ -52,7 +52,7 @@ static uint64_t rng_num;
#endif #endif
static int rng_ref_count; static int rng_ref_count;
const char * const unsupported_str = "Error: feature not supported\n"; const char * const unsupported_str = "Error: Feature not supported\n";
#ifndef CONFIG_SSL_SKELETON_MODE #ifndef CONFIG_SSL_SKELETON_MODE
/** /**

View File

@ -80,6 +80,10 @@ void RSA_pub_key_new(RSA_CTX **ctx,
{ {
RSA_CTX *rsa_ctx; RSA_CTX *rsa_ctx;
BI_CTX *bi_ctx = bi_initialize(); BI_CTX *bi_ctx = bi_initialize();
if (*ctx) /* if we load multiple certs, dump the old one */
RSA_free(*ctx);
*ctx = (RSA_CTX *)calloc(1, sizeof(RSA_CTX)); *ctx = (RSA_CTX *)calloc(1, sizeof(RSA_CTX));
rsa_ctx = *ctx; rsa_ctx = *ctx;
rsa_ctx->bi_ctx = bi_ctx; rsa_ctx->bi_ctx = bi_ctx;
@ -211,7 +215,7 @@ void RSA_print(const RSA_CTX *rsa_ctx)
} }
#endif #endif
#ifdef CONFIG_SSL_CERT_VERIFICATION #if defined(CONFIG_SSL_CERT_VERIFICATION) || defined(CONFIG_SSL_GENERATE_X509_CERT)
/** /**
* Performs c = m^e mod n * Performs c = m^e mod n
*/ */

View File

@ -459,7 +459,7 @@ WARN_LOGFILE =
# directories like "/usr/src/myproject". Separate the files or directories # directories like "/usr/src/myproject". Separate the files or directories
# with spaces. # with spaces.
INPUT = ../bindings/csharp/axTLS.cs ../bindings/java/SSL.java ../bindings/java/SSLUtil.java ../bindings/java/SSLCTX.java ../bindings/java/SSLServer.java ../bindings/java/SSLClient.java ../bindings/java/SSLReadHolder.java ../ssl/ssl.h ../ssl/bigint.c ../ssl/bigint.h INPUT = ../bindings/csharp/axTLS.cs ../bindings/java/SSL.java ../bindings/java/SSLUtil.java ../bindings/java/SSLCTX.java ../bindings/java/SSLServer.java ../bindings/java/SSLClient.java ../bindings/java/SSLReadHolder.java ../ssl/ssl.h ../crypto/bigint.c ../crypto/bigint.h
# If the value of the INPUT tag contains directories, you can use the # If the value of the INPUT tag contains directories, you can use the
# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
@ -1005,7 +1005,7 @@ INCLUDE_FILE_PATTERNS =
# undefined via #undef or recursively expanded use the := operator # undefined via #undef or recursively expanded use the := operator
# instead of the = operator. # instead of the = operator.
PREDEFINED = CONFIG_SSL_CERT_VERIFICATION CONFIG_SSL_ENABLE_CLIENT CONFIG_SSL_MAX_CLNT_SESSIONS=1 CONFIG_BIGINT_MONTGOMERY CONFIG_BIGINT_BARRETT CONFIG_BIGINT_CRT EXP_FUNC="" STDCALL="" PREDEFINED = CONFIG_SSL_CERT_VERIFICATION CONFIG_SSL_ENABLE_CLIENT CONFIG_SSL_GENERATE_X509_CERT CONFIG_BIGINT_MONTGOMERY CONFIG_BIGINT_BARRETT CONFIG_BIGINT_CRT EXP_FUNC="" STDCALL=""
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
# this tag can be used to specify a list of macro names that should be expanded. # this tag can be used to specify a list of macro names that should be expanded.

View File

@ -36,20 +36,6 @@
#include <sys/stat.h> #include <sys/stat.h>
#include "axhttp.h" #include "axhttp.h"
#if AXDEBUG
#define AXDEBUGSTART \
{ \
FILE *dout; \
dout = fopen("/var/log/axdebug", "a"); \
#define AXDEBUGEND \
fclose(dout); \
}
#else /* AXDEBUG */
#define AXDEBUGSTART
#define AXDEBUGEND
#endif /* AXDEBUG */
struct serverstruct *servers; struct serverstruct *servers;
struct connstruct *usedconns; struct connstruct *usedconns;
struct connstruct *freeconns; struct connstruct *freeconns;

View File

@ -116,8 +116,12 @@ config CONFIG_SSL_USE_DEFAULT_KEY
that is built in. This is one way to save on a couple of kB's if an that is built in. This is one way to save on a couple of kB's if an
external private key/certificate is used. external private key/certificate is used.
The private key is in ssl/private_key.h and the certificate is in
ssl/cert.h.
The advantage of a built-in private key/certificate is that no file The advantage of a built-in private key/certificate is that no file
system is required for access. system is required for access. Both the certificate and the private
key will be automatically loaded on a ssl_ctx_new().
However this private key/certificate can never be changed (without a However this private key/certificate can never be changed (without a
code update). code update).
@ -125,6 +129,62 @@ config CONFIG_SSL_USE_DEFAULT_KEY
This mode is enabled by default. Disable this mode if the This mode is enabled by default. Disable this mode if the
built-in key/certificate is not used. built-in key/certificate is not used.
config CONFIG_SSL_PRIVATE_KEY_LOCATION
string "Private key file location"
depends on !CONFIG_SSL_USE_DEFAULT_KEY && !CONFIG_SSL_SKELETON_MODE
help
The file location of the private key which will be automatically
loaded on a ssl_ctx_new().
config CONFIG_SSL_PRIVATE_KEY_PASSWORD
string "Private key password"
depends on !CONFIG_SSL_USE_DEFAULT_KEY && CONFIG_SSL_HAS_PEM
help
The password required to decrypt a PEM-encoded password file.
config CONFIG_SSL_X509_CERT_LOCATION
string "X.509 certificate file location"
depends on !CONFIG_SSL_GENERATE_X509_CERT && !CONFIG_SSL_SKELETON_MODE
help
The file location of the X.509 certificate which will be automatically
loaded on a ssl_ctx_new().
config CONFIG_SSL_GENERATE_X509_CERT
bool "Generate X.509 Certificate"
default n
help
An X.509 certificate can be automatically generated on a
ssl_ctx_new(). A private key still needs to be provided (the private
key in ss/private_key.h will be used unless
CONFIG_SSL_PRIVATE_KEY_LOCATION is set.
The certificate is generated on the fly, and so a minor start-up time
penalty is to be expected.
config CONFIG_SSL_X509_COMMON_NAME
string "X.509 Common Name"
depends on CONFIG_SSL_GENERATE_X509_CERT
help
The common name for the X.509 certificate. This should in theory be
the URL for server.
If this is blank, then the hostname is used.
config CONFIG_SSL_X509_ORGANIZATION_NAME
string "X.509 Organization Name"
depends on CONFIG_SSL_GENERATE_X509_CERT
help
The organization name for the generated X.509 certificate.
If this is blank, then $USERNAME will be used.
config CONFIG_SSL_X509_ORGANIZATION_UNIT_NAME
string "X.509 Organization Unit Name"
depends on CONFIG_SSL_GENERATE_X509_CERT
help
The organization unit name for the generated X.509 certificate. This
field is optional.
config CONFIG_SSL_ENABLE_V23_HANDSHAKE config CONFIG_SSL_ENABLE_V23_HANDSHAKE
bool "Enable v23 Handshake" bool "Enable v23 Handshake"
default y default y
@ -251,13 +311,6 @@ config CONFIG_OPENSSL_COMPATIBLE
Note: not all the API is implemented, so parts may still break. And Note: not all the API is implemented, so parts may still break. And
it's definitely not 100% compatible. it's definitely not 100% compatible.
config CONFIG_GEN_CERTIFICATES
bool "Enable the generation of certificates"
default n
depends on CONFIG_SSL_CERT_VERIFICATION
help
A primitive self-signed certificate generator.
config CONFIG_PERFORMANCE_TESTING config CONFIG_PERFORMANCE_TESTING
bool "Build the bigint performance test tool" bool "Build the bigint performance test tool"
default n default n

View File

@ -48,10 +48,8 @@ BASETARGET=libaxtls.so
CRYPTO_PATH=$(AXTLS_HOME)/crypto/ CRYPTO_PATH=$(AXTLS_HOME)/crypto/
ifdef CONFIG_PLATFORM_CYGWIN ifdef CONFIG_PLATFORM_CYGWIN
TARGET2=$(AXTLS_HOME)/$(STAGE)/libaxtls.dll.a TARGET2=$(AXTLS_HOME)/$(STAGE)/libaxtls.dll.a
TARGET3=$(AXTLS_HOME)/$(STAGE)/gen_cert.exe
else else
TARGET2=$(AXTLS_HOME)/$(STAGE)/$(LIBMINOR) TARGET2=$(AXTLS_HOME)/$(STAGE)/$(LIBMINOR)
TARGET3=$(AXTLS_HOME)/$(STAGE)/gen_cert
endif endif
# shared library major/minor numbers # shared library major/minor numbers
@ -64,7 +62,7 @@ STATIC_LIB=$(AXTLS_HOME)/$(STAGE)/axtls.static.lib
CRYPTO_PATH=$(AXTLS_HOME)\\crypto\\ CRYPTO_PATH=$(AXTLS_HOME)\\crypto\\
endif endif
libs: $(TARGET1) $(TARGET2) $(TARGET3) libs: $(TARGET1) $(TARGET2)
CRYPTO_OBJ=\ CRYPTO_OBJ=\
$(CRYPTO_PATH)aes.o \ $(CRYPTO_PATH)aes.o \
@ -79,14 +77,15 @@ CRYPTO_OBJ=\
OBJ=\ OBJ=\
asn1.o \ asn1.o \
x509.o \ gen_cert.o \
os_port.o \
loader.o \ loader.o \
openssl.o \ openssl.o \
os_port.o \
p12.o \ p12.o \
tls1.o \ tls1.o \
tls1_svr.o \ tls1_svr.o \
tls1_clnt.o tls1_clnt.o \
x509.o
include $(AXTLS_HOME)/config/makefile.post include $(AXTLS_HOME)/config/makefile.post
@ -106,9 +105,6 @@ else
-Wl,--enable-auto-import $(CRYPTO_OBJ) $(OBJ) -Wl,--enable-auto-import $(CRYPTO_OBJ) $(OBJ)
endif endif
$(TARGET3): gen_cert.o
$(LD) $(LDFLAGS) -o $@ $< -L$(AXTLS_HOME)/$(STAGE) -laxtls
else # Win32 else # Win32
CRYPTO_OBJ:=$(CRYPTO_OBJ:.o=.obj) CRYPTO_OBJ:=$(CRYPTO_OBJ:.o=.obj)

View File

@ -112,16 +112,13 @@ int asn1_get_int(const uint8_t *buf, int *offset, uint8_t **object)
if ((len = asn1_next_obj(buf, offset, ASN1_INTEGER)) < 0) if ((len = asn1_next_obj(buf, offset, ASN1_INTEGER)) < 0)
goto end_int_array; goto end_int_array;
*object = (uint8_t *)malloc(len); if (buf[*offset] == 0x00) /* ignore the negative byte */
/* TODO */
#if 0
if (*object == 0x00) /* ignore the negative byte */
{ {
len--; len--;
(*object)++; (*offset)++;
} }
#endif
*object = (uint8_t *)malloc(len);
memcpy(*object, &buf[*offset], len); memcpy(*object, &buf[*offset], len);
*offset += len; *offset += len;
@ -421,10 +418,13 @@ void remove_ca_certs(CA_CERT_CTX *ca_cert_ctx)
{ {
int i = 0; int i = 0;
if (ca_cert_ctx == NULL)
return;
while (i < CONFIG_X509_MAX_CA_CERTS && ca_cert_ctx->cert[i]) while (i < CONFIG_X509_MAX_CA_CERTS && ca_cert_ctx->cert[i])
{ {
x509_free(ca_cert_ctx->cert[i]); x509_free(ca_cert_ctx->cert[i]);
ca_cert_ctx->cert[i++] = NULL; ca_cert_ctx->cert[i] = NULL;
} }
free(ca_cert_ctx); free(ca_cert_ctx);
@ -441,10 +441,8 @@ int asn1_compare_dn(char * const dn1[], char * const dn2[])
for (i = 0; i < X509_NUM_DN_TYPES; i++) for (i = 0; i < X509_NUM_DN_TYPES; i++)
{ {
if (asn1_compare_dn_comp(dn1[i], dn2[i])) if (asn1_compare_dn_comp(dn1[i], dn2[i]))
{
return 1; return 1;
} }
}
return 0; /* all good */ return 0; /* all good */
} }

View File

@ -68,13 +68,8 @@ struct _x509_ctx
{ {
char *ca_cert_dn[X509_NUM_DN_TYPES]; char *ca_cert_dn[X509_NUM_DN_TYPES];
char *cert_dn[X509_NUM_DN_TYPES]; char *cert_dn[X509_NUM_DN_TYPES];
#if defined(_WIN32_WCE)
long not_before;
long not_after;
#else
time_t not_before; time_t not_before;
time_t not_after; time_t not_after;
#endif
uint8_t *signature; uint8_t *signature;
uint16_t sig_len; uint16_t sig_len;
uint8_t sig_type; uint8_t sig_type;
@ -98,8 +93,8 @@ void x509_free(X509_CTX *x509_ctx);
int x509_verify(const CA_CERT_CTX *ca_cert_ctx, const X509_CTX *cert); int x509_verify(const CA_CERT_CTX *ca_cert_ctx, const X509_CTX *cert);
#endif #endif
#ifdef CONFIG_SSL_FULL_MODE #ifdef CONFIG_SSL_FULL_MODE
void x509_print(CA_CERT_CTX *ca_cert_ctx, const X509_CTX *cert); void x509_print(const X509_CTX *cert, CA_CERT_CTX *ca_cert_ctx);
void x509_display_error(int error); const char * x509_display_error(int error);
#endif #endif
/************************************************************************** /**************************************************************************

View File

@ -30,13 +30,13 @@
#include "config.h" #include "config.h"
#ifdef CONFIG_GEN_CERTIFICATES #ifdef CONFIG_SSL_GENERATE_X509_CERT
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include "crypto_misc.h" #include "ssl.h"
/** /**
* This file is not completed. * Generate a basic X.509 certificate
*/ */
/* OBJECT IDENTIFIER sha1withRSAEncryption (1 2 840 113549 1 1 5) */ /* OBJECT IDENTIFIER sha1withRSAEncryption (1 2 840 113549 1 1 5) */
@ -176,33 +176,35 @@ error:
return ret; return ret;
} }
static int gen_issuer(const char *cn, const char *o, const char *ou, static int gen_issuer(const char * dn[], uint8_t *buf, int *offset)
uint8_t *buf, int *offset)
{ {
int ret = X509_OK; int ret = X509_OK;
int seq_offset; int seq_offset;
int seq_size = pre_adjust_with_size( int seq_size = pre_adjust_with_size(
ASN1_SEQUENCE, &seq_offset, buf, offset); ASN1_SEQUENCE, &seq_offset, buf, offset);
char hostname[128];
/* we need the common name at a minimum */ /* we need the common name, so if not configured, use the hostname */
if (cn == NULL) if (dn[X509_COMMON_NAME] == NULL || strlen(dn[X509_COMMON_NAME]) == 0)
{ {
ret = X509_NOT_OK; gethostname(hostname, sizeof(hostname));
goto error; dn[X509_COMMON_NAME] = hostname;
} }
if ((ret = gen_dn(cn, 3, buf, offset))) if ((ret = gen_dn(dn[X509_COMMON_NAME], 3, buf, offset)))
goto error; goto error;
if (o != NULL) if (dn[X509_ORGANIZATION] == NULL || strlen(dn[X509_ORGANIZATION]) == 0)
{ dn[X509_ORGANIZATION] = getenv("USERNAME");
if ((ret = gen_dn(o, 10, buf, offset)))
goto error;
}
if (ou != NULL) if (dn[X509_ORGANIZATION] != NULL &&
((ret = gen_dn(dn[X509_ORGANIZATION], 10, buf, offset))))
goto error;
if (dn[X509_ORGANIZATIONAL_TYPE] != NULL &&
strlen(dn[X509_ORGANIZATIONAL_TYPE]) != 0)
{ {
if ((ret = gen_dn(o, 11, buf, offset))) if ((ret = gen_dn(dn[X509_ORGANIZATIONAL_TYPE], 11, buf, offset)))
goto error; goto error;
} }
@ -212,32 +214,20 @@ error:
return ret; return ret;
} }
static const uint8_t time_seq[] =
{
ASN1_SEQUENCE, 30,
ASN1_UTC_TIME, 13,
'0', '7', '0', '1', '0', '1', '0', '0', '0', '0', '0', '0', 'Z',
ASN1_UTC_TIME, 13, /* make it good for 40 or so years */
'4', '9', '0', '1', '0', '1', '0', '0', '0', '0', '0', '0', 'Z'
};
static void gen_utc_time(uint8_t *buf, int *offset) static void gen_utc_time(uint8_t *buf, int *offset)
{ {
time_t curr_time = time(NULL); /* fixed time */
struct tm *now_tm = gmtime(&curr_time); memcpy(&buf[*offset], time_seq, sizeof(time_seq));
*offset += sizeof(time_seq);
buf[(*offset)++] = ASN1_SEQUENCE;
set_gen_length(30, buf, offset);
now_tm->tm_year -= 100;
now_tm->tm_mon++;
buf[(*offset)++] = ASN1_UTC_TIME;
buf[(*offset)++] = 13;
buf[(*offset)++] = now_tm->tm_year/10 + '0';
buf[(*offset)++] = now_tm->tm_year%10 + '0';
buf[(*offset)++] = now_tm->tm_mon/10 + '0';
buf[(*offset)++] = now_tm->tm_mon%10 + '0';
buf[(*offset)++] = now_tm->tm_mday/10 + '0';
buf[(*offset)++] = now_tm->tm_mday%10 + '0';
memset(&buf[*offset], '0', 6);
*offset += 6;
buf[(*offset)++] = 'Z';
now_tm->tm_year += 30; /* add 30 years */
memcpy(&buf[*offset], &buf[*offset-15], 15);
buf[*offset + 2] = now_tm->tm_year/10 + '0';
buf[*offset + 3] = now_tm->tm_year%10 + '0';
*offset += 15;
} }
static void gen_pub_key2(const RSA_CTX *rsa_ctx, uint8_t *buf, int *offset) static void gen_pub_key2(const RSA_CTX *rsa_ctx, uint8_t *buf, int *offset)
@ -249,6 +239,7 @@ static void gen_pub_key2(const RSA_CTX *rsa_ctx, uint8_t *buf, int *offset)
ASN1_SEQUENCE, &seq_offset, buf, offset); ASN1_SEQUENCE, &seq_offset, buf, offset);
buf[(*offset)++] = ASN1_INTEGER; buf[(*offset)++] = ASN1_INTEGER;
bi_export(rsa_ctx->bi_ctx, rsa_ctx->m, block, pub_key_size); bi_export(rsa_ctx->bi_ctx, rsa_ctx->m, block, pub_key_size);
if (*block & 0x80) /* make integer positive */ if (*block & 0x80) /* make integer positive */
{ {
set_gen_length(pub_key_size+1, buf, offset); set_gen_length(pub_key_size+1, buf, offset);
@ -259,6 +250,8 @@ static void gen_pub_key2(const RSA_CTX *rsa_ctx, uint8_t *buf, int *offset)
memcpy(&buf[*offset], block, pub_key_size); memcpy(&buf[*offset], block, pub_key_size);
*offset += pub_key_size; *offset += pub_key_size;
memcpy(&buf[*offset], pub_key_seq, sizeof(pub_key_seq));
*offset += sizeof(pub_key_seq);
adjust_with_size(seq_size, seq_offset, buf, offset); adjust_with_size(seq_size, seq_offset, buf, offset);
} }
@ -287,8 +280,6 @@ static void gen_pub_key(const RSA_CTX *rsa_ctx, uint8_t *buf, int *offset)
buf[(*offset)++] = ASN1_NULL; buf[(*offset)++] = ASN1_NULL;
buf[(*offset)++] = 0; buf[(*offset)++] = 0;
gen_pub_key1(rsa_ctx, buf, offset); gen_pub_key1(rsa_ctx, buf, offset);
memcpy(&buf[*offset], pub_key_seq, sizeof(pub_key_seq));
*offset += sizeof(pub_key_seq);
adjust_with_size(seq_size, seq_offset, buf, offset); adjust_with_size(seq_size, seq_offset, buf, offset);
} }
@ -313,86 +304,64 @@ static void gen_signature(const RSA_CTX *rsa_ctx, const uint8_t *sha_dgst,
*offset += sig_size; *offset += sig_size;
} }
static int gen_tbs_cert(const char *cn, const char *o, const char *ou, static int gen_tbs_cert(const char * dn[],
const RSA_CTX *rsa_ctx, uint8_t *buf, int *offset, const RSA_CTX *rsa_ctx, uint8_t *buf, int *offset,
uint8_t *sha_dgst) uint8_t *sha_dgst)
{ {
int ret = X509_OK; int ret = X509_OK;
SHA1_CTX sha_ctx; SHA1_CTX sha_ctx;
int seq_offset; int seq_offset;
int begin_tbs = *offset;
int seq_size = pre_adjust_with_size( int seq_size = pre_adjust_with_size(
ASN1_SEQUENCE, &seq_offset, buf, offset); ASN1_SEQUENCE, &seq_offset, buf, offset);
int begin_tbs = *offset;
gen_serial_number(buf, offset); gen_serial_number(buf, offset);
gen_signature_alg(buf, offset); gen_signature_alg(buf, offset);
if ((ret = gen_issuer(cn, o, ou, buf, offset)))
/* CA certicate issuer */
if ((ret = gen_issuer(dn, buf, offset)))
goto error; goto error;
gen_utc_time(buf, offset); gen_utc_time(buf, offset);
if ((ret = gen_issuer(cn, o, ou, buf, offset)))
/* certificate issuer */
if ((ret = gen_issuer(dn, buf, offset)))
goto error; goto error;
gen_pub_key(rsa_ctx, buf, offset); gen_pub_key(rsa_ctx, buf, offset);
adjust_with_size(seq_size, seq_offset, buf, offset);
SHA1_Init(&sha_ctx); SHA1_Init(&sha_ctx);
SHA1_Update(&sha_ctx, &buf[begin_tbs], *offset-begin_tbs); SHA1_Update(&sha_ctx, &buf[begin_tbs], *offset-begin_tbs);
SHA1_Final(sha_dgst, &sha_ctx); SHA1_Final(sha_dgst, &sha_ctx);
adjust_with_size(seq_size, seq_offset, buf, offset);
error: error:
return ret; return ret;
} }
int gen_cert(const char *cn, const char *o, const char *ou, /**
const RSA_CTX *rsa_ctx, uint8_t *buf, int *cert_size) * Create a new certificate.
*/
EXP_FUNC int STDCALL ssl_x509_create(SSL_CTX *ssl_ctx, const char * dn[], uint32_t options, uint8_t **cert_data)
{ {
int ret = X509_OK; int ret = X509_OK, offset = 0, seq_offset;
int offset = 0; /* allocate enough space to load a new certificate */
int seq_offset; uint8_t *buf = (uint8_t *)alloca(ssl_ctx->rsa_ctx->num_octets*2 + 512);
uint8_t sha_dgst[SHA1_SIZE]; uint8_t sha_dgst[SHA1_SIZE];
int seq_size = pre_adjust_with_size( int seq_size = pre_adjust_with_size(ASN1_SEQUENCE,
ASN1_SEQUENCE, &seq_offset, buf, &offset); &seq_offset, buf, &offset);
if ((ret = gen_tbs_cert(cn, o, ou, rsa_ctx, buf, &offset, sha_dgst))) if ((ret = gen_tbs_cert(dn, ssl_ctx->rsa_ctx, buf, &offset, sha_dgst)) < 0)
goto error; goto error;
gen_signature_alg(buf, &offset); gen_signature_alg(buf, &offset);
gen_signature(rsa_ctx, sha_dgst, buf, &offset); gen_signature(ssl_ctx->rsa_ctx, sha_dgst, buf, &offset);
adjust_with_size(seq_size, seq_offset, buf, &offset); adjust_with_size(seq_size, seq_offset, buf, &offset);
*cert_size = offset; *cert_data = (uint8_t *)malloc(offset); /* create the exact memory for it */
memcpy(*cert_data, buf, offset);
error: error:
return ret; return ret < 0 ? ret : offset;
}
int main(int argc, char *argv[])
{
int ret = X509_OK;
uint8_t *key_buf = NULL;
RSA_CTX *rsa_ctx = NULL;
uint8_t buf[2048];
int cert_size;
FILE *f;
int len = get_file("../ssl/test/axTLS.key_512", &key_buf);
if ((ret = asn1_get_private_key(key_buf, len, &rsa_ctx)))
goto error;
if ((ret = gen_cert("abc", "def", "ghi", rsa_ctx, buf, &cert_size)))
goto error;
f = fopen("blah.dat", "w");
fwrite(buf, cert_size, 1, f);
fclose(f);
error:
free(key_buf);
RSA_free(rsa_ctx);
if (ret)
printf("Some cert generation issue\n");
return ret;
} }
#endif #endif

View File

@ -69,7 +69,6 @@ EXP_FUNC int STDCALL ssl_obj_load(SSL_CTX *ssl_ctx, int obj_type,
} }
ssl_obj = (SSLObjLoader *)calloc(1, sizeof(SSLObjLoader)); ssl_obj = (SSLObjLoader *)calloc(1, sizeof(SSLObjLoader));
ssl_obj->len = get_file(filename, &ssl_obj->buf); ssl_obj->len = get_file(filename, &ssl_obj->buf);
if (ssl_obj->len <= 0) if (ssl_obj->len <= 0)
@ -107,8 +106,8 @@ EXP_FUNC int STDCALL ssl_obj_memory_load(SSL_CTX *ssl_ctx, int mem_type,
const uint8_t *data, int len, const char *password) const uint8_t *data, int len, const char *password)
{ {
int ret; int ret;
SSLObjLoader *ssl_obj; SSLObjLoader *ssl_obj;
ssl_obj = (SSLObjLoader *)calloc(1, sizeof(SSLObjLoader)); ssl_obj = (SSLObjLoader *)calloc(1, sizeof(SSLObjLoader));
ssl_obj->buf = (uint8_t *)malloc(len); ssl_obj->buf = (uint8_t *)malloc(len);
memcpy(ssl_obj->buf, data, len); memcpy(ssl_obj->buf, data, len);
@ -219,10 +218,10 @@ static int pem_decrypt(const char *where, const char *end,
AES_CTX aes_ctx; AES_CTX aes_ctx;
uint8_t key[32]; /* AES256 size */ uint8_t key[32]; /* AES256 size */
if (password == NULL) if (password == NULL || strlen(password) == 0)
{ {
#ifdef CONFIG_SSL_FULL_MODE #ifdef CONFIG_SSL_FULL_MODE
printf("Error: need a password for this PEM file\n"); printf("Error: Need a password for this PEM file\n"); TTY_FLUSH();
#endif #endif
goto error; goto error;
} }
@ -239,7 +238,7 @@ static int pem_decrypt(const char *where, const char *end,
else else
{ {
#ifdef CONFIG_SSL_FULL_MODE #ifdef CONFIG_SSL_FULL_MODE
printf("Error: Unsupported password cipher\n"); printf("Error: Unsupported password cipher\n"); TTY_FLUSH();
#endif #endif
goto error; goto error;
} }
@ -387,3 +386,80 @@ static int ssl_obj_PEM_load(SSL_CTX *ssl_ctx, int obj_type,
start, ssl_obj->len, password); start, ssl_obj->len, password);
} }
#endif /* CONFIG_SSL_HAS_PEM */ #endif /* CONFIG_SSL_HAS_PEM */
/**
* Load the key/certificates in memory depending on compile-time and user
* options.
*/
int load_key_certs(SSL_CTX *ssl_ctx)
{
int ret = SSL_OK;
uint32_t options = ssl_ctx->options;
/* do the private key first */
if (strlen(CONFIG_SSL_PRIVATE_KEY_LOCATION) > 0)
{
if ((ret = ssl_obj_load(ssl_ctx, SSL_OBJ_RSA_KEY,
CONFIG_SSL_PRIVATE_KEY_LOCATION,
CONFIG_SSL_PRIVATE_KEY_PASSWORD)) < 0)
goto error;
}
else if (!(options & SSL_NO_DEFAULT_KEY))
{
#if defined(CONFIG_SSL_USE_DEFAULT_KEY) || defined(CONFIG_SSL_SKELETON_MODE)
static const /* saves a few more bytes */
#include "private_key.h"
ssl_obj_memory_load(ssl_ctx, SSL_OBJ_RSA_KEY, default_private_key,
default_private_key_len, NULL);
#endif
}
/* now load the certificate */
#ifdef CONFIG_SSL_GENERATE_X509_CERT
uint8_t *cert_data;
int cert_size;
static const char *dn[] =
{
CONFIG_SSL_X509_COMMON_NAME,
CONFIG_SSL_X509_ORGANIZATION_NAME,
CONFIG_SSL_X509_ORGANIZATION_UNIT_NAME
};
if ((cert_size = ssl_x509_create(ssl_ctx, dn, &cert_data)) < 0)
{
ret = cert_size;
goto error;
}
ssl_obj_memory_load(ssl_ctx, SSL_OBJ_X509_CERT, cert_data, cert_size, NULL);
free(cert_data);
#else
if (strlen(CONFIG_SSL_X509_CERT_LOCATION))
{
if ((ret = ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CERT,
CONFIG_SSL_X509_CERT_LOCATION, NULL)) < 0)
goto error;
}
else if (!(options & SSL_NO_DEFAULT_KEY))
{
#if defined(CONFIG_SSL_USE_DEFAULT_KEY) || defined(CONFIG_SSL_SKELETON_MODE)
static const /* saves a few bytes and RAM */
#include "cert.h"
ssl_obj_memory_load(ssl_ctx, SSL_OBJ_X509_CERT,
default_certificate, default_certificate_len, NULL);
#endif
}
#endif
error:
#ifdef CONFIG_SSL_FULL_MODE
if (ret)
{
printf("Error: Certificate or key not loaded\n"); TTY_FLUSH();
}
#endif
return ret;
}

View File

@ -182,8 +182,6 @@ extern "C" {
* - SSL_CLIENT_AUTHENTICATION (server only): Enforce client authentication * - SSL_CLIENT_AUTHENTICATION (server only): Enforce client authentication
* i.e. each handshake will include a "certificate request" message from the * i.e. each handshake will include a "certificate request" message from the
* server. Only available if verification has been enabled. * server. Only available if verification has been enabled.
* - SSL_NO_DEFAULT_KEY: Don't use the default key/certificate. The user will
* load the key/certificate explicitly.
* - SSL_DISPLAY_BYTES (full mode build only): Display the byte sequences * - SSL_DISPLAY_BYTES (full mode build only): Display the byte sequences
* during the handshake. * during the handshake.
* - SSL_DISPLAY_STATES (full mode build only): Display the state changes * - SSL_DISPLAY_STATES (full mode build only): Display the state changes
@ -436,9 +434,34 @@ EXP_FUNC int STDCALL ssl_obj_load(SSL_CTX *ssl_ctx, int obj_type, const char *fi
*/ */
EXP_FUNC int STDCALL ssl_obj_memory_load(SSL_CTX *ssl_ctx, int obj_type, const uint8_t *data, int len, const char *password); EXP_FUNC int STDCALL ssl_obj_memory_load(SSL_CTX *ssl_ctx, int obj_type, const uint8_t *data, int len, const char *password);
#ifdef CONFIG_SSL_GENERATE_X509_CERT
/**
* @brief Create an X.509 certificate.
*
* This certificate is a self-signed v1 cert with a fixed start/stop validity
* times. It is also signed with the private key in ssl_ctx->rsa_ctx.
*
* @param ssl_ctx [in] The client/server context.
* @param dn [in] An array of distinguished name strings. The array is defined
* by:
* - SSL_X509_CERT_COMMON_NAME (0)
* - If SSL_X509_CERT_COMMON_NAME is empty or not defined, then the
* hostname will be used.
* - SSL_X509_CERT_ORGANIZATION (1)
* - If SSL_X509_CERT_ORGANIZATION is empty or not defined, then $USERNAME
* will be used.
* - SSL_X509_CERT_ORGANIZATIONAL_NAME (2)
* - SSL_X509_CERT_ORGANIZATIONAL_NAME is optional.
* @param options [in] Not used yet.
* @param cert_data [out] The certificate as a sequence of bytes.
* @return < 0 if an error, or the size of the certificate in bytes.
* @note cert_data must be freed when there is no more need for it.
*/
EXP_FUNC int STDCALL ssl_x509_create(SSL_CTX *ssl_ctx, const char * dn[], uint32_t options, uint8_t **cert_data);
#endif
/** /**
* @brief Return the axTLS library version as a string. * @brief Return the axTLS library version as a string.
* @note New API function for v1.1
*/ */
EXP_FUNC const char * STDCALL ssl_version(void); EXP_FUNC const char * STDCALL ssl_version(void);

View File

@ -64,21 +64,22 @@ AXTLS_SSL_PATH="$(AXTLS_INCLUDE)ssl\\"
CRYPTO_OBJ=\ CRYPTO_OBJ=\
$(CRYPTO_PATH)aes.obj \ $(CRYPTO_PATH)aes.obj \
$(CRYPTO_PATH)bigint.obj \
$(CRYPTO_PATH)crypto_misc.obj \
$(CRYPTO_PATH)hmac.obj \ $(CRYPTO_PATH)hmac.obj \
$(CRYPTO_PATH)md2.obj \
$(CRYPTO_PATH)md5.obj \ $(CRYPTO_PATH)md5.obj \
$(CRYPTO_PATH)rc4.obj \ $(CRYPTO_PATH)rc4.obj \
$(CRYPTO_PATH)rsa.obj \
$(CRYPTO_PATH)sha1.obj $(CRYPTO_PATH)sha1.obj
OBJ=\ OBJ=\
$(AXTLS_SSL_PATH)asn1.obj \ $(AXTLS_SSL_PATH)asn1.obj \
$(AXTLS_SSL_PATH)x509.obj \ $(AXTLS_SSL_PATH)x509.obj \
$(AXTLS_SSL_PATH)bigint.obj \
$(AXTLS_SSL_PATH)crypto_misc.obj \
$(AXTLS_SSL_PATH)os_port.obj \ $(AXTLS_SSL_PATH)os_port.obj \
$(AXTLS_SSL_PATH)loader.obj \ $(AXTLS_SSL_PATH)loader.obj \
$(AXTLS_SSL_PATH)openssl.obj \ $(AXTLS_SSL_PATH)openssl.obj \
$(AXTLS_SSL_PATH)p12.obj \ $(AXTLS_SSL_PATH)p12.obj \
$(AXTLS_SSL_PATH)rsa.obj \
$(AXTLS_SSL_PATH)tls1.obj \ $(AXTLS_SSL_PATH)tls1.obj \
$(AXTLS_SSL_PATH)tls1_svr.obj \ $(AXTLS_SSL_PATH)tls1_svr.obj \
$(AXTLS_SSL_PATH)tls1_clnt.obj $(AXTLS_SSL_PATH)tls1_clnt.obj

View File

@ -58,6 +58,7 @@
static int g_port = 19001; static int g_port = 19001;
#if 0
/************************************************************************** /**************************************************************************
* AES tests * AES tests
* *
@ -102,7 +103,7 @@ static int AES_test(BI_CTX *bi_ctx)
enc_data, sizeof(enc_data)); enc_data, sizeof(enc_data));
if (memcmp(enc_data, ct, sizeof(ct))) if (memcmp(enc_data, ct, sizeof(ct)))
{ {
fprintf(stderr, "Error: AES ENCRYPT #1 failed\n"); printf("Error: AES ENCRYPT #1 failed\n");
goto end; goto end;
} }
@ -112,7 +113,7 @@ static int AES_test(BI_CTX *bi_ctx)
if (memcmp(dec_data, in_str, sizeof(dec_data))) if (memcmp(dec_data, in_str, sizeof(dec_data)))
{ {
fprintf(stderr, "Error: AES DECRYPT #1 failed\n"); printf("Error: AES DECRYPT #1 failed\n");
goto end; goto end;
} }
} }
@ -151,7 +152,7 @@ static int AES_test(BI_CTX *bi_ctx)
if (memcmp(enc_data, ct, sizeof(ct))) if (memcmp(enc_data, ct, sizeof(ct)))
{ {
fprintf(stderr, "Error: ENCRYPT #2 failed\n"); printf("Error: ENCRYPT #2 failed\n");
goto end; goto end;
} }
@ -160,7 +161,7 @@ static int AES_test(BI_CTX *bi_ctx)
AES_cbc_decrypt(&aes_key, enc_data, dec_data, sizeof(enc_data)); AES_cbc_decrypt(&aes_key, enc_data, dec_data, sizeof(enc_data));
if (memcmp(dec_data, in_data, sizeof(dec_data))) if (memcmp(dec_data, in_data, sizeof(dec_data)))
{ {
fprintf(stderr, "Error: DECRYPT #2 failed\n"); printf("Error: DECRYPT #2 failed\n");
goto end; goto end;
} }
} }
@ -232,7 +233,7 @@ static int RC4_test(BI_CTX *bi_ctx)
if (memcmp(data[i], output[i], data_len[i])) if (memcmp(data[i], output[i], data_len[i]))
{ {
fprintf(stderr, "Error: RC4 CRYPT #%d failed\n", i); printf("Error: RC4 CRYPT #%d failed\n", i);
goto end; goto end;
} }
} }
@ -268,7 +269,7 @@ static int SHA1_test(BI_CTX *bi_ctx)
if (memcmp(digest, ct, sizeof(ct))) if (memcmp(digest, ct, sizeof(ct)))
{ {
fprintf(stderr, "Error: SHA1 #1 failed\n"); printf("Error: SHA1 #1 failed\n");
goto end; goto end;
} }
} }
@ -286,7 +287,7 @@ static int SHA1_test(BI_CTX *bi_ctx)
if (memcmp(digest, ct, sizeof(ct))) if (memcmp(digest, ct, sizeof(ct)))
{ {
fprintf(stderr, "Error: SHA1 #2 failed\n"); printf("Error: SHA1 #2 failed\n");
goto end; goto end;
} }
} }
@ -322,7 +323,7 @@ static int MD5_test(BI_CTX *bi_ctx)
if (memcmp(digest, ct, sizeof(ct))) if (memcmp(digest, ct, sizeof(ct)))
{ {
fprintf(stderr, "Error: MD5 #1 failed\n"); printf("Error: MD5 #1 failed\n");
goto end; goto end;
} }
} }
@ -340,7 +341,7 @@ static int MD5_test(BI_CTX *bi_ctx)
if (memcmp(digest, ct, sizeof(ct))) if (memcmp(digest, ct, sizeof(ct)))
{ {
fprintf(stderr, "Error: MD5 #2 failed\n"); printf("Error: MD5 #2 failed\n");
goto end; goto end;
} }
} }
@ -481,7 +482,7 @@ static int RSA_test(void)
"1aaaaaaaaaabbbbbbbbbbbbbbbccccccccccccccdddddddddddddeeeeeeeeee2" "1aaaaaaaaaabbbbbbbbbbbbbbbccccccccccccccdddddddddddddeeeeeeeeee2"
"1aaaaaaaaaabbbbbbbbbbbbbbbccccccccccccccdddddddddddddeeeeeeeee2\012"; "1aaaaaaaaaabbbbbbbbbbbbbbbccccccccccccccdddddddddddddeeeeeeeee2\012";
uint8_t enc_data[128], dec_data[128]; uint8_t enc_data[128], dec_data[128];
RSA_CTX *rsa_ctx; RSA_CTX *rsa_ctx = NULL;
BI_CTX *bi_ctx; BI_CTX *bi_ctx;
bigint *plaintext_bi; bigint *plaintext_bi;
bigint *enc_data_bi, *dec_data_bi; bigint *enc_data_bi, *dec_data_bi;
@ -512,7 +513,7 @@ static int RSA_test(void)
if (memcmp(dec_data, plaintext, strlen(plaintext))) if (memcmp(dec_data, plaintext, strlen(plaintext)))
{ {
fprintf(stderr, "Error: DECRYPT #1 failed\n"); printf("Error: DECRYPT #1 failed\n");
goto end; goto end;
} }
@ -520,7 +521,7 @@ static int RSA_test(void)
size = RSA_decrypt(rsa_ctx, enc_data2, dec_data2, 1); size = RSA_decrypt(rsa_ctx, enc_data2, dec_data2, 1);
if (memcmp("abc", dec_data2, 3)) if (memcmp("abc", dec_data2, 3))
{ {
fprintf(stderr, "Error: ENCRYPT/DECRYPT #2 failed\n"); printf("Error: ENCRYPT/DECRYPT #2 failed\n");
goto end; goto end;
} }
@ -642,8 +643,11 @@ static int cert_tests(void)
printf("All Certificate tests passed\n"); printf("All Certificate tests passed\n");
bad_cert: bad_cert:
if (res)
printf("Error: A certificate test failed\n");
return res; return res;
} }
#endif
/** /**
* init a server socket. * init a server socket.
@ -751,7 +755,6 @@ static void do_client(client_t *clnt)
} }
static int SSL_server_test( static int SSL_server_test(
SVR_CTX *svr_test_ctx,
const char *testname, const char *testname,
const char *openssl_option, const char *openssl_option,
const char *device_cert, const char *device_cert,
@ -778,11 +781,6 @@ static int SSL_server_test(
if ((server_fd = server_socket_init(&g_port)) < 0) if ((server_fd = server_socket_init(&g_port)) < 0)
goto error; goto error;
if (private_key)
{
axolotls_option |= SSL_NO_DEFAULT_KEY;
}
if ((ssl_ctx = ssl_ctx_new(axolotls_option, SSL_DEFAULT_SVR_SESS)) == NULL) if ((ssl_ctx = ssl_ctx_new(axolotls_option, SSL_DEFAULT_SVR_SESS)) == NULL)
{ {
ret = SSL_ERROR_INVALID_KEY; ret = SSL_ERROR_INVALID_KEY;
@ -883,6 +881,7 @@ static int SSL_server_test(
error: error:
ssl_ctx_free(ssl_ctx); ssl_ctx_free(ssl_ctx);
printf("RES %d\n", ret); TTY_FLUSH();
return ret; return ret;
} }
@ -893,21 +892,21 @@ int SSL_server_tests(void)
SVR_CTX svr_test_ctx; SVR_CTX svr_test_ctx;
memset(&svr_test_ctx, 0, sizeof(SVR_CTX)); memset(&svr_test_ctx, 0, sizeof(SVR_CTX));
printf("### starting server tests\n"); printf("### starting server tests\n"); TTY_FLUSH();
/* Go through the algorithms */ /* Go through the algorithms */
/* /*
* TLS1 client hello * TLS1 client hello
*/ */
if ((ret = SSL_server_test(NULL, "TLSv1", "-cipher RC4-SHA -tls1", if ((ret = SSL_server_test("TLSv1", "-cipher RC4-SHA -tls1",
NULL, NULL, NULL, NULL, NULL, DEFAULT_SVR_OPTION))) NULL, NULL, NULL, NULL, NULL, DEFAULT_SVR_OPTION)))
goto cleanup; goto cleanup;
/* /*
* AES128-SHA * AES128-SHA
*/ */
if ((ret = SSL_server_test(NULL, "AES256-SHA", "-cipher AES128-SHA", if ((ret = SSL_server_test("AES256-SHA", "-cipher AES128-SHA",
DEFAULT_CERT, NULL, DEFAULT_KEY, NULL, NULL, DEFAULT_CERT, NULL, DEFAULT_KEY, NULL, NULL,
DEFAULT_SVR_OPTION))) DEFAULT_SVR_OPTION)))
goto cleanup; goto cleanup;
@ -915,7 +914,7 @@ int SSL_server_tests(void)
/* /*
* AES256-SHA * AES256-SHA
*/ */
if ((ret = SSL_server_test(NULL, "AES256-SHA", "-cipher AES128-SHA", if ((ret = SSL_server_test("AES256-SHA", "-cipher AES128-SHA",
DEFAULT_CERT, NULL, DEFAULT_KEY, NULL, NULL, DEFAULT_CERT, NULL, DEFAULT_KEY, NULL, NULL,
DEFAULT_SVR_OPTION))) DEFAULT_SVR_OPTION)))
goto cleanup; goto cleanup;
@ -923,7 +922,7 @@ int SSL_server_tests(void)
/* /*
* RC4-SHA * RC4-SHA
*/ */
if ((ret = SSL_server_test(NULL, "RC4-SHA", "-cipher RC4-SHA", if ((ret = SSL_server_test("RC4-SHA", "-cipher RC4-SHA",
DEFAULT_CERT, NULL, DEFAULT_KEY, NULL, NULL, DEFAULT_CERT, NULL, DEFAULT_KEY, NULL, NULL,
DEFAULT_SVR_OPTION))) DEFAULT_SVR_OPTION)))
goto cleanup; goto cleanup;
@ -931,7 +930,7 @@ int SSL_server_tests(void)
/* /*
* RC4-MD5 * RC4-MD5
*/ */
if ((ret = SSL_server_test(NULL, "RC4-MD5", "-cipher RC4-MD5", if ((ret = SSL_server_test("RC4-MD5", "-cipher RC4-MD5",
DEFAULT_CERT, NULL, DEFAULT_KEY, NULL, NULL, DEFAULT_CERT, NULL, DEFAULT_KEY, NULL, NULL,
DEFAULT_SVR_OPTION))) DEFAULT_SVR_OPTION)))
goto cleanup; goto cleanup;
@ -940,7 +939,7 @@ int SSL_server_tests(void)
* Session Reuse * Session Reuse
* all the session id's should match for session resumption. * all the session id's should match for session resumption.
*/ */
if ((ret = SSL_server_test(NULL, "Session Reuse", if ((ret = SSL_server_test("Session Reuse",
"-cipher RC4-SHA -reconnect", "-cipher RC4-SHA -reconnect",
DEFAULT_CERT, NULL, DEFAULT_KEY, NULL, NULL, DEFAULT_CERT, NULL, DEFAULT_KEY, NULL, NULL,
DEFAULT_SVR_OPTION))) DEFAULT_SVR_OPTION)))
@ -949,7 +948,7 @@ int SSL_server_tests(void)
/* /*
* 512 bit RSA key * 512 bit RSA key
*/ */
if ((ret = SSL_server_test(NULL, "512 bit key", "-cipher RC4-SHA", if ((ret = SSL_server_test("512 bit key", "-cipher RC4-SHA",
"../ssl/test/axTLS.x509_512.cer", NULL, "../ssl/test/axTLS.x509_512.cer", NULL,
"../ssl/test/axTLS.key_512", "../ssl/test/axTLS.key_512",
NULL, NULL, DEFAULT_SVR_OPTION))) NULL, NULL, DEFAULT_SVR_OPTION)))
@ -958,7 +957,7 @@ int SSL_server_tests(void)
/* /*
* 1024 bit RSA key (check certificate chaining) * 1024 bit RSA key (check certificate chaining)
*/ */
if ((ret = SSL_server_test(NULL, "1024 bit key", if ((ret = SSL_server_test("1024 bit key",
"-cipher RC4-SHA", "-cipher RC4-SHA",
"../ssl/test/axTLS.x509_device.cer", "../ssl/test/axTLS.x509_device.cer",
"../ssl/test/axTLS.x509_512.cer", "../ssl/test/axTLS.x509_512.cer",
@ -969,7 +968,7 @@ int SSL_server_tests(void)
/* /*
* 2048 bit RSA key * 2048 bit RSA key
*/ */
if ((ret = SSL_server_test(NULL, "2048 bit key", if ((ret = SSL_server_test("2048 bit key",
"-cipher RC4-SHA", "-cipher RC4-SHA",
"../ssl/test/axTLS.x509_2048.cer", NULL, "../ssl/test/axTLS.x509_2048.cer", NULL,
"../ssl/test/axTLS.key_2048", "../ssl/test/axTLS.key_2048",
@ -979,7 +978,7 @@ int SSL_server_tests(void)
/* /*
* 4096 bit RSA key * 4096 bit RSA key
*/ */
if ((ret = SSL_server_test(NULL, "4096 bit key", if ((ret = SSL_server_test("4096 bit key",
"-cipher RC4-SHA", "-cipher RC4-SHA",
"../ssl/test/axTLS.x509_4096.cer", NULL, "../ssl/test/axTLS.x509_4096.cer", NULL,
"../ssl/test/axTLS.key_4096", "../ssl/test/axTLS.key_4096",
@ -989,7 +988,7 @@ int SSL_server_tests(void)
/* /*
* Client Verification * Client Verification
*/ */
if ((ret = SSL_server_test(NULL, "Client Verification", if ((ret = SSL_server_test("Client Verification",
"-cipher RC4-SHA -tls1 " "-cipher RC4-SHA -tls1 "
"-cert ../ssl/test/axTLS.x509_2048.pem " "-cert ../ssl/test/axTLS.x509_2048.pem "
"-key ../ssl/test/axTLS.key_2048.pem ", "-key ../ssl/test/axTLS.key_2048.pem ",
@ -1001,7 +1000,7 @@ int SSL_server_tests(void)
/* this test should fail */ /* this test should fail */
if (stat("../ssl/test/axTLS.x509_bad_before.pem", &stat_buf) >= 0) if (stat("../ssl/test/axTLS.x509_bad_before.pem", &stat_buf) >= 0)
{ {
if ((ret = SSL_server_test(NULL, "Bad Before Cert", if ((ret = SSL_server_test("Bad Before Cert",
"-cipher RC4-SHA -tls1 " "-cipher RC4-SHA -tls1 "
"-cert ../ssl/test/axTLS.x509_bad_before.pem " "-cert ../ssl/test/axTLS.x509_bad_before.pem "
"-key ../ssl/test/axTLS.key_512.pem ", "-key ../ssl/test/axTLS.key_512.pem ",
@ -1017,7 +1016,7 @@ int SSL_server_tests(void)
} }
/* this test should fail */ /* this test should fail */
if ((ret = SSL_server_test(NULL, "Bad After Cert", if ((ret = SSL_server_test("Bad After Cert",
"-cipher RC4-SHA -tls1 " "-cipher RC4-SHA -tls1 "
"-cert ../ssl/test/axTLS.x509_bad_after.pem " "-cert ../ssl/test/axTLS.x509_bad_after.pem "
"-key ../ssl/test/axTLS.key_512.pem ", "-key ../ssl/test/axTLS.key_512.pem ",
@ -1033,7 +1032,7 @@ int SSL_server_tests(void)
/* /*
* Key in PEM format * Key in PEM format
*/ */
if ((ret = SSL_server_test(NULL, "Key in PEM format", if ((ret = SSL_server_test("Key in PEM format",
"-cipher RC4-SHA", "-cipher RC4-SHA",
"../ssl/test/axTLS.x509_512.cer", NULL, "../ssl/test/axTLS.x509_512.cer", NULL,
"../ssl/test/axTLS.key_512.pem", NULL, "../ssl/test/axTLS.key_512.pem", NULL,
@ -1043,7 +1042,7 @@ int SSL_server_tests(void)
/* /*
* Cert in PEM format * Cert in PEM format
*/ */
if ((ret = SSL_server_test(NULL, "Cert in PEM format", if ((ret = SSL_server_test("Cert in PEM format",
"-cipher RC4-SHA", "-cipher RC4-SHA",
"../ssl/test/axTLS.x509_512.pem", NULL, "../ssl/test/axTLS.x509_512.pem", NULL,
"../ssl/test/axTLS.key_512.pem", NULL, "../ssl/test/axTLS.key_512.pem", NULL,
@ -1053,7 +1052,7 @@ int SSL_server_tests(void)
/* /*
* Cert chain in PEM format * Cert chain in PEM format
*/ */
if ((ret = SSL_server_test(NULL, "Cert chain in PEM format", if ((ret = SSL_server_test("Cert chain in PEM format",
"-cipher RC4-SHA", "-cipher RC4-SHA",
"../ssl/test/axTLS.x509_device.pem", "../ssl/test/axTLS.x509_device.pem",
NULL, "../ssl/test/axTLS.device_key.pem", NULL, "../ssl/test/axTLS.device_key.pem",
@ -1063,7 +1062,7 @@ int SSL_server_tests(void)
/* /*
* AES128 Encrypted key * AES128 Encrypted key
*/ */
if ((ret = SSL_server_test(NULL, "AES128 encrypted key", if ((ret = SSL_server_test("AES128 encrypted key",
"-cipher RC4-SHA", "-cipher RC4-SHA",
"../ssl/test/axTLS.x509_aes128.pem", NULL, "../ssl/test/axTLS.x509_aes128.pem", NULL,
"../ssl/test/axTLS.key_aes128.pem", "../ssl/test/axTLS.key_aes128.pem",
@ -1073,7 +1072,7 @@ int SSL_server_tests(void)
/* /*
* AES256 Encrypted key * AES256 Encrypted key
*/ */
if ((ret = SSL_server_test(NULL, "AES256 encrypted key", if ((ret = SSL_server_test("AES256 encrypted key",
"-cipher RC4-SHA", "-cipher RC4-SHA",
"../ssl/test/axTLS.x509_aes256.pem", NULL, "../ssl/test/axTLS.x509_aes256.pem", NULL,
"../ssl/test/axTLS.key_aes256.pem", "../ssl/test/axTLS.key_aes256.pem",
@ -1083,7 +1082,7 @@ int SSL_server_tests(void)
/* /*
* AES128 Encrypted invalid key * AES128 Encrypted invalid key
*/ */
if ((ret = SSL_server_test(NULL, "AES128 encrypted invalid key", if ((ret = SSL_server_test("AES128 encrypted invalid key",
"-cipher RC4-SHA", "-cipher RC4-SHA",
"../ssl/test/axTLS.x509_aes128.pem", NULL, "../ssl/test/axTLS.x509_aes128.pem", NULL,
"../ssl/test/axTLS.key_aes128.pem", "../ssl/test/axTLS.key_aes128.pem",
@ -1096,7 +1095,7 @@ int SSL_server_tests(void)
/* /*
* PKCS#8 key (encrypted) * PKCS#8 key (encrypted)
*/ */
if ((ret = SSL_server_test(NULL, "pkcs#8 encrypted", "-cipher RC4-SHA", if ((ret = SSL_server_test("pkcs#8 encrypted", "-cipher RC4-SHA",
DEFAULT_CERT, NULL, "../ssl/test/axTLS.encrypted.p8", DEFAULT_CERT, NULL, "../ssl/test/axTLS.encrypted.p8",
NULL, "abcd", DEFAULT_SVR_OPTION))) NULL, "abcd", DEFAULT_SVR_OPTION)))
goto cleanup; goto cleanup;
@ -1104,7 +1103,7 @@ int SSL_server_tests(void)
/* /*
* PKCS#8 key (unencrypted) * PKCS#8 key (unencrypted)
*/ */
if ((ret = SSL_server_test(NULL, "pkcs#8 unencrypted", "-cipher RC4-SHA", if ((ret = SSL_server_test("pkcs#8 unencrypted", "-cipher RC4-SHA",
DEFAULT_CERT, NULL, "../ssl/test/axTLS.unencrypted.p8", DEFAULT_CERT, NULL, "../ssl/test/axTLS.unencrypted.p8",
NULL, NULL, DEFAULT_SVR_OPTION))) NULL, NULL, DEFAULT_SVR_OPTION)))
goto cleanup; goto cleanup;
@ -1112,12 +1111,12 @@ int SSL_server_tests(void)
/* /*
* PKCS#12 key/certificate * PKCS#12 key/certificate
*/ */
if ((ret = SSL_server_test(NULL, "pkcs#12 with CA", "-cipher RC4-SHA", if ((ret = SSL_server_test("pkcs#12 with CA", "-cipher RC4-SHA",
NULL, NULL, "../ssl/test/axTLS.withCA.p12", NULL, NULL, "../ssl/test/axTLS.withCA.p12",
NULL, "abcd", DEFAULT_SVR_OPTION))) NULL, "abcd", DEFAULT_SVR_OPTION)))
goto cleanup; goto cleanup;
if ((ret = SSL_server_test(NULL, "pkcs#12 no CA", "-cipher RC4-SHA", if ((ret = SSL_server_test("pkcs#12 no CA", "-cipher RC4-SHA",
DEFAULT_CERT, NULL, "../ssl/test/axTLS.withoutCA.p12", DEFAULT_CERT, NULL, "../ssl/test/axTLS.withoutCA.p12",
NULL, "abcd", DEFAULT_SVR_OPTION))) NULL, "abcd", DEFAULT_SVR_OPTION)))
goto cleanup; goto cleanup;
@ -1126,7 +1125,11 @@ int SSL_server_tests(void)
cleanup: cleanup:
if (ret) if (ret)
fprintf(stderr, "Error: A server test failed\n"); {
printf("Error: A server test failed\n"); TTY_FLUSH();
exit(1);
}
return ret; return ret;
} }
@ -1200,11 +1203,6 @@ static int SSL_client_test(
if (*ssl_ctx == NULL) if (*ssl_ctx == NULL)
{ {
if (private_key)
{
client_options |= SSL_NO_DEFAULT_KEY;
}
if ((*ssl_ctx = ssl_ctx_new( if ((*ssl_ctx = ssl_ctx_new(
client_options, SSL_DEFAULT_CLNT_SESS)) == NULL) client_options, SSL_DEFAULT_CLNT_SESS)) == NULL)
{ {
@ -1453,7 +1451,7 @@ int SSL_client_tests(void)
cleanup: cleanup:
if (ret) if (ret)
fprintf(stderr, "Error: A client test failed\n"); printf("Error: A client test failed\n");
return ret; return ret;
} }
@ -1462,6 +1460,7 @@ cleanup:
* SSL Basic Testing (test a big packet handshake) * SSL Basic Testing (test a big packet handshake)
* *
**************************************************************************/ **************************************************************************/
#if 0
static uint8_t basic_buf[256*1024]; static uint8_t basic_buf[256*1024];
static void do_basic(void) static void do_basic(void)
@ -1572,6 +1571,7 @@ error:
ssl_ctx_free(ssl_svr_ctx); ssl_ctx_free(ssl_svr_ctx);
return ret; return ret;
} }
#endif
#if !defined(WIN32) && defined(CONFIG_SSL_CTX_MUTEXING) #if !defined(WIN32) && defined(CONFIG_SSL_CTX_MUTEXING)
/************************************************************************** /**************************************************************************
@ -1792,7 +1792,7 @@ error:
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
int ret = 1; int ret = 1;
BI_CTX *bi_ctx; //BI_CTX *bi_ctx;
int fd; int fd;
#ifdef WIN32 #ifdef WIN32
@ -1807,6 +1807,7 @@ int main(int argc, char *argv[])
dup2(fd, 2); dup2(fd, 2);
#endif #endif
#if 0
bi_ctx = bi_initialize(); bi_ctx = bi_initialize();
if (AES_test(bi_ctx)) if (AES_test(bi_ctx))
@ -1881,6 +1882,7 @@ int main(int argc, char *argv[])
goto cleanup; goto cleanup;
system("sh ../ssl/test/killopenssl.sh"); system("sh ../ssl/test/killopenssl.sh");
#endif
if (SSL_server_tests()) if (SSL_server_tests())
goto cleanup; goto cleanup;
@ -1898,9 +1900,7 @@ int main(int argc, char *argv[])
cleanup: cleanup:
if (ret) if (ret)
{ printf("Error: Some tests failed!\n");
fprintf(stderr, "Error: Some tests failed!\n");
}
close(fd); close(fd);
return ret; return ret;

View File

@ -38,14 +38,6 @@
#include <stdarg.h> #include <stdarg.h>
#include "ssl.h" #include "ssl.h"
/* Don't import the default key/certificate if not used */
#if defined(CONFIG_SSL_USE_DEFAULT_KEY) || defined(CONFIG_SSL_SKELETON_MODE)
static const /* saves a few bytes and RAM */
#include "cert.h"
static const /* saves a few more bytes */
#include "private_key.h"
#endif
/* The session expiry time */ /* The session expiry time */
#define SSL_EXPIRY_TIME (CONFIG_SSL_EXPIRY_TIME*3600) #define SSL_EXPIRY_TIME (CONFIG_SSL_EXPIRY_TIME*3600)
@ -173,22 +165,19 @@ EXP_FUNC SSL_CTX *STDCALL ssl_ctx_new(uint32_t options, int num_sessions)
{ {
SSL_CTX *ssl_ctx = (SSL_CTX *)calloc(1, sizeof (SSL_CTX)); SSL_CTX *ssl_ctx = (SSL_CTX *)calloc(1, sizeof (SSL_CTX));
ssl_ctx->options = options; ssl_ctx->options = options;
if (load_key_certs(ssl_ctx) < 0)
{
free(ssl_ctx); /* can't load our key/certificate pair, so die */
return NULL;
}
#ifndef CONFIG_SSL_SKELETON_MODE #ifndef CONFIG_SSL_SKELETON_MODE
ssl_ctx->num_sessions = num_sessions; ssl_ctx->num_sessions = num_sessions;
#endif #endif
SSL_CTX_MUTEX_INIT(ssl_ctx->mutex); SSL_CTX_MUTEX_INIT(ssl_ctx->mutex);
#if defined(CONFIG_SSL_USE_DEFAULT_KEY) || defined(CONFIG_SSL_SKELETON_MODE)
if (~options & SSL_NO_DEFAULT_KEY)
{
ssl_obj_memory_load(ssl_ctx, SSL_OBJ_RSA_KEY, default_private_key,
default_private_key_len, NULL);
ssl_obj_memory_load(ssl_ctx, SSL_OBJ_X509_CERT,
default_certificate, default_certificate_len, NULL);
}
#endif
#ifndef CONFIG_SSL_SKELETON_MODE #ifndef CONFIG_SSL_SKELETON_MODE
if (num_sessions) if (num_sessions)
{ {
@ -197,10 +186,6 @@ EXP_FUNC SSL_CTX *STDCALL ssl_ctx_new(uint32_t options, int num_sessions)
} }
#endif #endif
#ifdef CONFIG_SSL_CERT_VERIFICATION
ssl_ctx->ca_cert_ctx = (CA_CERT_CTX *)calloc(1, sizeof(CA_CERT_CTX));
#endif
return ssl_ctx; return ssl_ctx;
} }
@ -397,7 +382,12 @@ int add_cert_auth(SSL_CTX *ssl_ctx, const uint8_t *buf, int len)
int i = 0; int i = 0;
int offset; int offset;
X509_CTX *cert = NULL; X509_CTX *cert = NULL;
CA_CERT_CTX *ca_cert_ctx = ssl_ctx->ca_cert_ctx; CA_CERT_CTX *ca_cert_ctx;
if (ssl_ctx->ca_cert_ctx == NULL)
ssl_ctx->ca_cert_ctx = (CA_CERT_CTX *)calloc(1, sizeof(CA_CERT_CTX));
ca_cert_ctx = ssl_ctx->ca_cert_ctx;
while (i < CONFIG_X509_MAX_CA_CERTS && ca_cert_ctx->cert[i]) while (i < CONFIG_X509_MAX_CA_CERTS && ca_cert_ctx->cert[i])
i++; i++;
@ -418,11 +408,14 @@ int add_cert_auth(SSL_CTX *ssl_ctx, const uint8_t *buf, int len)
cert = ca_cert_ctx->cert[i]; cert = ca_cert_ctx->cert[i];
SSL_CTX_LOCK(ssl_ctx->mutex); SSL_CTX_LOCK(ssl_ctx->mutex);
if ((ret = x509_verify(ca_cert_ctx, cert))) if ((ret = x509_verify(ca_cert_ctx, cert)) != X509_VFY_ERROR_SELF_SIGNED)
{ {
SSL_CTX_UNLOCK(ssl_ctx->mutex); SSL_CTX_UNLOCK(ssl_ctx->mutex);
x509_free(cert); /* get rid of it */ x509_free(cert); /* get rid of it */
ca_cert_ctx->cert[i] = NULL; ca_cert_ctx->cert[i] = NULL;
#ifdef CONFIG_SSL_FULL_MODE
printf("Error: %s\n", x509_display_error(ret));
#endif
goto error; goto error;
} }
@ -1484,6 +1477,7 @@ int send_certificate(SSL *ssl)
while (i < ssl->ssl_ctx->chain_length) while (i < ssl->ssl_ctx->chain_length)
{ {
X509_CTX *cert_ctx;
SSL_CERT *cert = &ssl->ssl_ctx->certs[i]; SSL_CERT *cert = &ssl->ssl_ctx->certs[i];
buf[offset++] = 0; buf[offset++] = 0;
buf[offset++] = cert->size >> 8; /* cert 1 length */ buf[offset++] = cert->size >> 8; /* cert 1 length */
@ -1491,6 +1485,10 @@ int send_certificate(SSL *ssl)
memcpy(&buf[offset], cert->buf, cert->size); memcpy(&buf[offset], cert->buf, cert->size);
offset += cert->size; offset += cert->size;
i++; i++;
// TODO: get rid of these
x509_new(cert->buf, &cert->size, &cert_ctx);
x509_print(cert_ctx, NULL);
x509_free(cert_ctx);
} }
chain_length = offset - 7; chain_length = offset - 7;
@ -1765,7 +1763,7 @@ int process_certificate(SSL *ssl, X509_CTX **x509_ctx)
ret = ssl_verify_cert(ssl); ret = ssl_verify_cert(ssl);
} }
DISPLAY_CERT(ssl, "process_certificate", *x509_ctx); DISPLAY_CERT(ssl, *x509_ctx);
ssl->next_state = is_client ? HS_SERVER_HELLO_DONE : HS_CLIENT_KEY_XCHG; ssl->next_state = is_client ? HS_SERVER_HELLO_DONE : HS_CLIENT_KEY_XCHG;
ssl->dc->bm_proc_index += offset; ssl->dc->bm_proc_index += offset;
error: error:
@ -1846,19 +1844,19 @@ void DISPLAY_STATE(SSL *ssl, int is_send, uint8_t state, int not_ok)
/** /**
* Debugging routine to display X509 certificates. * Debugging routine to display X509 certificates.
*/ */
void DISPLAY_CERT(SSL *ssl, const char *label, const X509_CTX *x509_ctx) void DISPLAY_CERT(SSL *ssl, const X509_CTX *x509_ctx)
{ {
if (!IS_SET_SSL_FLAG(SSL_DISPLAY_CERTS)) if (!IS_SET_SSL_FLAG(SSL_DISPLAY_CERTS))
return; return;
x509_print(ssl->ssl_ctx->ca_cert_ctx, x509_ctx); x509_print(x509_ctx, ssl->ssl_ctx->ca_cert_ctx);
TTY_FLUSH(); TTY_FLUSH();
} }
/** /**
* Debugging routine to display RSA objects * Debugging routine to display RSA objects
*/ */
void DISPLAY_RSA(SSL *ssl, const char *label, const RSA_CTX *rsa_ctx) void DISPLAY_RSA(SSL *ssl, const RSA_CTX *rsa_ctx)
{ {
if (!IS_SET_SSL_FLAG(SSL_DISPLAY_RSA)) if (!IS_SET_SSL_FLAG(SSL_DISPLAY_RSA))
return; return;
@ -1897,8 +1895,7 @@ EXP_FUNC void STDCALL ssl_display_error(int error_code)
/* X509 error? */ /* X509 error? */
if (error_code < SSL_X509_OFFSET) if (error_code < SSL_X509_OFFSET)
{ {
x509_display_error(error_code - SSL_X509_OFFSET); printf("%s\n", x509_display_error(error_code - SSL_X509_OFFSET));
printf("\n");
return; return;
} }

View File

@ -243,6 +243,7 @@ int add_private_key(SSL_CTX *ssl_ctx, SSLObjLoader *ssl_obj);
void ssl_obj_free(SSLObjLoader *ssl_obj); void ssl_obj_free(SSLObjLoader *ssl_obj);
int pkcs8_decode(SSL_CTX *ssl_ctx, SSLObjLoader *ssl_obj, const char *password); int pkcs8_decode(SSL_CTX *ssl_ctx, SSLObjLoader *ssl_obj, const char *password);
int pkcs12_decode(SSL_CTX *ssl_ctx, SSLObjLoader *ssl_obj, const char *password); int pkcs12_decode(SSL_CTX *ssl_ctx, SSLObjLoader *ssl_obj, const char *password);
int load_key_certs(SSL_CTX *ssl_ctx);
#ifdef CONFIG_SSL_CERT_VERIFICATION #ifdef CONFIG_SSL_CERT_VERIFICATION
int add_cert_auth(SSL_CTX *ssl_ctx, const uint8_t *buf, int len); int add_cert_auth(SSL_CTX *ssl_ctx, const uint8_t *buf, int len);
void remove_ca_certs(CA_CERT_CTX *ca_cert_ctx); void remove_ca_certs(CA_CERT_CTX *ca_cert_ctx);
@ -255,8 +256,8 @@ int do_client_connect(SSL *ssl);
void DISPLAY_STATE(SSL *ssl, int is_send, uint8_t state, int not_ok); void DISPLAY_STATE(SSL *ssl, int is_send, uint8_t state, int not_ok);
void DISPLAY_BYTES(SSL *ssl, const char *format, void DISPLAY_BYTES(SSL *ssl, const char *format,
const uint8_t *data, int size, ...); const uint8_t *data, int size, ...);
void DISPLAY_CERT(SSL *ssl, const char *label, const X509_CTX *x509_ctx); void DISPLAY_CERT(SSL *ssl, const X509_CTX *x509_ctx);
void DISPLAY_RSA(SSL *ssl, const char *label, const RSA_CTX *rsa_ctx); void DISPLAY_RSA(SSL *ssl, const RSA_CTX *rsa_ctx);
void DISPLAY_ALERT(SSL *ssl, int alert); void DISPLAY_ALERT(SSL *ssl, int alert);
#else #else
#define DISPLAY_STATE(A,B,C,D) #define DISPLAY_STATE(A,B,C,D)

View File

@ -118,7 +118,7 @@ int x509_new(const uint8_t *cert, int *len, X509_CTX **ctx)
bi_ctx = x509_ctx->rsa_ctx->bi_ctx; bi_ctx = x509_ctx->rsa_ctx->bi_ctx;
#ifdef CONFIG_SSL_CERT_VERIFICATION /* only care if doing verification */ #ifdef CONFIG_SSL_CERT_VERIFICATION /* only care if doing verification */
/* use the appropriate signature algorithm (either SHA1 or MD5) */ /* use the appropriate signature algorithm (SHA1/MD5/MD2) */
if (x509_ctx->sig_type == SIG_TYPE_MD5) if (x509_ctx->sig_type == SIG_TYPE_MD5)
{ {
MD5_CTX md5_ctx; MD5_CTX md5_ctx;
@ -224,7 +224,6 @@ static bigint *sig_verify(BI_CTX *ctx, const uint8_t *sig, int sig_len,
decrypted_bi = bi_mod_power2(ctx, dat_bi, modulus, pub_exp); decrypted_bi = bi_mod_power2(ctx, dat_bi, modulus, pub_exp);
bi_export(ctx, decrypted_bi, block, sig_len); bi_export(ctx, decrypted_bi, block, sig_len);
print_blob("SIGNATURE", block, sig_len);
ctx->mod_offset = BIGINT_M_OFFSET; ctx->mod_offset = BIGINT_M_OFFSET;
i = 10; /* start at the first possible non-padded byte */ i = 10; /* start at the first possible non-padded byte */
@ -234,9 +233,6 @@ static bigint *sig_verify(BI_CTX *ctx, const uint8_t *sig, int sig_len,
/* get only the bit we want */ /* get only the bit we want */
if (size > 0) if (size > 0)
{ {
FILE *f = fopen("blah.dat", "w");
fwrite(&block[i], sig_len-i, 1, f);
fclose(f);
int len; int len;
const uint8_t *sig_ptr = get_signature(&block[i], &len); const uint8_t *sig_ptr = get_signature(&block[i], &len);
@ -271,6 +267,7 @@ int x509_verify(const CA_CERT_CTX *ca_cert_ctx, const X509_CTX *cert)
bigint *mod, *expn; bigint *mod, *expn;
struct timeval tv; struct timeval tv;
int match_ca_cert = 0; int match_ca_cert = 0;
uint8_t is_self_signed = 0;
if (cert == NULL || ca_cert_ctx == NULL) if (cert == NULL || ca_cert_ctx == NULL)
{ {
@ -279,7 +276,7 @@ int x509_verify(const CA_CERT_CTX *ca_cert_ctx, const X509_CTX *cert)
} }
/* last cert in the chain - look for a trusted cert */ /* last cert in the chain - look for a trusted cert */
if (cert->next == NULL) if (cert->next == NULL && ca_cert_ctx)
{ {
while (i < CONFIG_X509_MAX_CA_CERTS && ca_cert_ctx->cert[i]) while (i < CONFIG_X509_MAX_CA_CERTS && ca_cert_ctx->cert[i])
{ {
@ -287,17 +284,15 @@ int x509_verify(const CA_CERT_CTX *ca_cert_ctx, const X509_CTX *cert)
ca_cert_ctx->cert[i]->cert_dn) == 0) ca_cert_ctx->cert[i]->cert_dn) == 0)
{ {
match_ca_cert = 1; match_ca_cert = 1;
next_cert = ca_cert_ctx->cert[i];
break; break;
} }
i++; i++;
} }
if (i < CONFIG_X509_MAX_CA_CERTS && ca_cert_ctx->cert[i]) /* trusted cert not found */
{ if (i >= CONFIG_X509_MAX_CA_CERTS)
next_cert = ca_cert_ctx->cert[i];
}
else /* trusted cert not found */
{ {
ret = X509_VFY_ERROR_NO_TRUSTED_CERT; ret = X509_VFY_ERROR_NO_TRUSTED_CERT;
goto end_verify; goto end_verify;
@ -325,31 +320,37 @@ int x509_verify(const CA_CERT_CTX *ca_cert_ctx, const X509_CTX *cert)
} }
/* check the chain integrity */ /* check the chain integrity */
if (asn1_compare_dn(cert->ca_cert_dn, next_cert->cert_dn)) if (next_cert && !match_ca_cert &&
asn1_compare_dn(cert->ca_cert_dn, next_cert->cert_dn) == 0)
{ {
ret = X509_VFY_ERROR_INVALID_CHAIN; ret = X509_VFY_ERROR_INVALID_CHAIN;
goto end_verify; goto end_verify;
} }
ctx = cert->rsa_ctx->bi_ctx;
/* check for self-signing */ /* check for self-signing */
if (!match_ca_cert && asn1_compare_dn(cert->ca_cert_dn, cert->cert_dn) == 0) if (asn1_compare_dn(cert->ca_cert_dn, cert->cert_dn) == 0)
{ {
ret = X509_VFY_ERROR_SELF_SIGNED; is_self_signed = 1;
goto end_verify; mod = cert->rsa_ctx->m;
expn = cert->rsa_ctx->e;
}
else
{
mod = next_cert->rsa_ctx->m;
expn = next_cert->rsa_ctx->e;
} }
/* check the signature */ /* check the signature */
ctx = cert->rsa_ctx->bi_ctx;
mod = next_cert->rsa_ctx->m;
expn = next_cert->rsa_ctx->e;
cert_sig = sig_verify(ctx, cert->signature, cert->sig_len, cert_sig = sig_verify(ctx, cert->signature, cert->sig_len,
bi_clone(ctx, mod), bi_clone(ctx, expn)); bi_clone(ctx, mod), bi_clone(ctx, expn));
if (cert_sig) if (cert_sig && cert->digest)
{ {
ret = cert->digest ? /* check the signature */ if (bi_compare(cert_sig, cert->digest))
bi_compare(cert_sig, cert->digest) : ret = X509_VFY_ERROR_BAD_SIGNATURE;
X509_VFY_ERROR_UNSUPPORTED_DIGEST;
bi_free(ctx, cert_sig); bi_free(ctx, cert_sig);
if (ret) if (ret)
@ -361,6 +362,12 @@ int x509_verify(const CA_CERT_CTX *ca_cert_ctx, const X509_CTX *cert)
goto end_verify; goto end_verify;
} }
if (is_self_signed)
{
ret = X509_VFY_ERROR_SELF_SIGNED;
goto end_verify;
}
/* go down the certificate chain using recursion. */ /* go down the certificate chain using recursion. */
if (ret == 0 && cert->next) if (ret == 0 && cert->next)
{ {
@ -376,7 +383,7 @@ end_verify:
/** /**
* Used for diagnostics. * Used for diagnostics.
*/ */
void x509_print(CA_CERT_CTX *ca_cert_ctx, const X509_CTX *cert) void x509_print(const X509_CTX *cert, CA_CERT_CTX *ca_cert_ctx)
{ {
if (cert == NULL) if (cert == NULL)
return; return;
@ -436,14 +443,12 @@ void x509_print(CA_CERT_CTX *ca_cert_ctx, const X509_CTX *cert)
break; break;
} }
printf("Verify:\t\t\t");
if (ca_cert_ctx) if (ca_cert_ctx)
{ {
x509_display_error(x509_verify(ca_cert_ctx, cert)); printf("Verify:\t\t\t%s\n",
x509_display_error(x509_verify(ca_cert_ctx, cert)));
} }
printf("\n");
#if 0 #if 0
print_blob("Signature", cert->signature, cert->sig_len); print_blob("Signature", cert->signature, cert->sig_len);
bi_print("Modulus", cert->rsa_ctx->m); bi_print("Modulus", cert->rsa_ctx->m);
@ -452,48 +457,52 @@ void x509_print(CA_CERT_CTX *ca_cert_ctx, const X509_CTX *cert)
if (ca_cert_ctx) if (ca_cert_ctx)
{ {
x509_print(ca_cert_ctx, cert->next); x509_print(cert->next, ca_cert_ctx);
} }
} }
void x509_display_error(int error) const char * x509_display_error(int error)
{ {
switch (error) switch (error)
{ {
case X509_NOT_OK: case X509_NOT_OK:
printf("X509 not ok"); return "X509 not ok";
break; break;
case X509_VFY_ERROR_NO_TRUSTED_CERT: case X509_VFY_ERROR_NO_TRUSTED_CERT:
printf("No trusted cert is available"); return "No trusted cert is available";
break; break;
case X509_VFY_ERROR_BAD_SIGNATURE: case X509_VFY_ERROR_BAD_SIGNATURE:
printf("Bad signature"); return "Bad signature";
break; break;
case X509_VFY_ERROR_NOT_YET_VALID: case X509_VFY_ERROR_NOT_YET_VALID:
printf("Cert is not yet valid"); return "Cert is not yet valid";
break; break;
case X509_VFY_ERROR_EXPIRED: case X509_VFY_ERROR_EXPIRED:
printf("Cert has expired"); return "Cert has expired";
break; break;
case X509_VFY_ERROR_SELF_SIGNED: case X509_VFY_ERROR_SELF_SIGNED:
printf("Cert is self-signed"); return "Cert is self-signed";
break; break;
case X509_VFY_ERROR_INVALID_CHAIN: case X509_VFY_ERROR_INVALID_CHAIN:
printf("Chain is invalid (check order of certs)"); return "Chain is invalid (check order of certs)";
break; break;
case X509_VFY_ERROR_UNSUPPORTED_DIGEST: case X509_VFY_ERROR_UNSUPPORTED_DIGEST:
printf("Unsupported digest"); return "Unsupported digest";
break; break;
case X509_INVALID_PRIV_KEY: case X509_INVALID_PRIV_KEY:
printf("Invalid private key"); return "Invalid private key";
break;
default:
return "Unknown";
break; break;
} }
} }

View File

@ -7086,7 +7086,7 @@ if (useJavaSaver)
<div id="contentStash"></div> <div id="contentStash"></div>
<div id="storeArea"> <div id="storeArea">
<div tiddler="(built-in shadow tiddler)" modifier="CameronRich" modified="200702240024" created="200702240024" tags="">changes, notes and errata</div> <div tiddler="(built-in shadow tiddler)" modifier="CameronRich" modified="200702240024" created="200702240024" tags="">changes, notes and errata</div>
<div tiddler="Changelog" modifier="CameronRich" modified="200711060908" created="200702240022" tags="">!@@bgcolor(#ff0000):color(#ffffff):Changes for 1.1.8 (yet to be released)@@\n\n!!__SSL Library__\n* Now using a BSD style license.\n\n!@@bgcolor(#ff0000):color(#ffffff):Changes for 1.1.7@@\n\n!!__SSL Library__\n\n* Variable sized session id's is now better handled for session caching. It has meant a new API call ssl_get_session_id_size() and a change to ssl_client_new() to define the session id size.\n* Muliple records with a single header are now better supported (thanks to Hervé Sibert).\n* ~MD2 added for Verisign root cert verification (thanks to Byron Rakitzis).\n* The ~MD5/~SHA1 digests are calculated incrementally to reduce memory (thanks to Byron Rakitzis).\n* The bigint cache is now cleared regularly to reduce memory.\n\n!!__axhttpd__\n\n* Improved the POST handling (thanks to Christian Melki).\n* CSS files now work properly.\n* Lua's CGI launcher location is configurable.\n* vfork() is now used for CGI for performance reasons.\n\n!@@bgcolor(#ff0000):color(#ffffff):Changes for 1.1.6@@\n\n!!__SSL Library__\n\n* ~RC4 speed improvements\n* Lua samples/bindings now work properly\n\n!@@bgcolor(#ff0000):color(#ffffff):Changes for 1.1.5@@\n\n!!__SSL Library__\n\n* Session id's can now be variable lengths in server hello messages.\n* 0 length client certificates are now supported.\n* ssl_version() now returns just the version and not the date.\n* ssl_write() was not sending complete packets under load.\n\n!!__axhttpd__\n\n* Completely updated the CGI code.\n* Lua now integrated - Lua scripts and Lua Pages now run.\n\n!@@bgcolor(#ff0000):color(#ffffff):Changes for 1.1.4@@\n\n!!__SSL Library__\n\n* Fixed a Win32 crypto library issue with non-Administrator users\n* Removed compiler warnings that showed up in ~FC6.\n* GNU TLS certificates are now accepted.\n* Separated the send/receive headers for HMAC calculations.\n* Fixed a compilation problem with swig/perl/~FC6.\n* Fixed an issue with loading PEM CA certificates.\n\n!!__axhttpd__\n\n* Made //setuid()/setgid()// call an mconf option.\n* Made //chroot()// an mconf option. Default to //chdir()// instead.\n* Removed optional permissions checking.\n\n!@@bgcolor(#ff0000):color(#ffffff):Changes for 1.1.1@@\n\n!!__SSL Library__\n\n* AES should now work on 16bit processors (there was an alignment problem).\n* Various freed objects are cleared before freeing.\n* Header files now installed in ///usr/local/include/axTLS//.\n* -DCYGWIN replaced with -~DCONFIG_PLATFORM_CYGWIN (and the same for Solaris).\n* removed &quot;-noextern&quot; option in Swig. Fixed some other warnings in Win32.\n* SSLCTX changed to ~SSL_CTX (to be consistent with openssl). SSLCTX still exists for backwards compatibility.\n* malloc() and friends call abort() on failure.\n* Fixed a memory leak in directory listings.\n* Added openssl() compatibility functions.\n* Fixed Cygwin 'make install' issue.\n\n!!__axhttpd__\n\n* main.c now becomes axhttpd.c.\n* Header file issue fixed (in mime_types.c).\n* //chroot()// now used for better security.\n* Basic authentication implemented (via .htpasswd).\n* SSL access/denial protection implemented (via .htaccess).\n* Directory access protection implemented (via .htaccess).\n* Can now have more than one CGI file extension in mconf.\n* &quot;~If-Modified-Since&quot; request now handled properly.\n* Performance tweaks to remove //ssl_find()//.</div> <div tiddler="Changelog" modifier="CameronRich" modified="200711271156" created="200702240022" tags="">!@@bgcolor(#ff0000):color(#ffffff):Changes for 1.1.8@@\n\n!!__SSL Library__\n* Now using a BSD style license.\n* Certificates can now be automatically generated (the keys still need to be provided).\n* Certificate/keys can be loaded automatically given a file location.\n* ~SSL_NO_DEFAULT_KEY has been removed (it is now largely redundant).\n\n!@@bgcolor(#ff0000):color(#ffffff):Changes for 1.1.7@@\n\n!!__SSL Library__\n\n* Variable sized session id's is now better handled for session caching. It has meant a new API call ssl_get_session_id_size() and a change to ssl_client_new() to define the session id size.\n* Muliple records with a single header are now better supported (thanks to Hervé Sibert).\n* ~MD2 added for Verisign root cert verification (thanks to Byron Rakitzis).\n* The ~MD5/~SHA1 digests are calculated incrementally to reduce memory (thanks to Byron Rakitzis).\n* The bigint cache is now cleared regularly to reduce memory.\n\n!!__axhttpd__\n\n* Improved the POST handling (thanks to Christian Melki).\n* CSS files now work properly.\n* Lua's CGI launcher location is configurable.\n* vfork() is now used for CGI for performance reasons.\n\n!@@bgcolor(#ff0000):color(#ffffff):Changes for 1.1.6@@\n\n!!__SSL Library__\n\n* ~RC4 speed improvements\n* Lua samples/bindings now work properly\n\n!@@bgcolor(#ff0000):color(#ffffff):Changes for 1.1.5@@\n\n!!__SSL Library__\n\n* Session id's can now be variable lengths in server hello messages.\n* 0 length client certificates are now supported.\n* ssl_version() now returns just the version and not the date.\n* ssl_write() was not sending complete packets under load.\n\n!!__axhttpd__\n\n* Completely updated the CGI code.\n* Lua now integrated - Lua scripts and Lua Pages now run.\n\n!@@bgcolor(#ff0000):color(#ffffff):Changes for 1.1.4@@\n\n!!__SSL Library__\n\n* Fixed a Win32 crypto library issue with non-Administrator users\n* Removed compiler warnings that showed up in ~FC6.\n* GNU TLS certificates are now accepted.\n* Separated the send/receive headers for HMAC calculations.\n* Fixed a compilation problem with swig/perl/~FC6.\n* Fixed an issue with loading PEM CA certificates.\n\n!!__axhttpd__\n\n* Made //setuid()/setgid()// call an mconf option.\n* Made //chroot()// an mconf option. Default to //chdir()// instead.\n* Removed optional permissions checking.\n\n!@@bgcolor(#ff0000):color(#ffffff):Changes for 1.1.1@@\n\n!!__SSL Library__\n\n* AES should now work on 16bit processors (there was an alignment problem).\n* Various freed objects are cleared before freeing.\n* Header files now installed in ///usr/local/include/axTLS//.\n* -DCYGWIN replaced with -~DCONFIG_PLATFORM_CYGWIN (and the same for Solaris).\n* removed &quot;-noextern&quot; option in Swig. Fixed some other warnings in Win32.\n* SSLCTX changed to ~SSL_CTX (to be consistent with openssl). SSLCTX still exists for backwards compatibility.\n* malloc() and friends call abort() on failure.\n* Fixed a memory leak in directory listings.\n* Added openssl() compatibility functions.\n* Fixed Cygwin 'make install' issue.\n\n!!__axhttpd__\n\n* main.c now becomes axhttpd.c.\n* Header file issue fixed (in mime_types.c).\n* //chroot()// now used for better security.\n* Basic authentication implemented (via .htpasswd).\n* SSL access/denial protection implemented (via .htaccess).\n* Directory access protection implemented (via .htaccess).\n* Can now have more than one CGI file extension in mconf.\n* &quot;~If-Modified-Since&quot; request now handled properly.\n* Performance tweaks to remove //ssl_find()//.</div>
<div tiddler="DefaultTiddlers" modifier="CameronRich" modified="200702240019" created="200702240019" tags="">[[Read Me]]</div> <div tiddler="DefaultTiddlers" modifier="CameronRich" modified="200702240019" created="200702240019" tags="">[[Read Me]]</div>
<div tiddler="License" modifier="YourName" modified="200711050226" created="200702240022" tags="">axTLS uses a BSD style license:\n\nCopyright (c) 2007, Cameron Rich All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\nRedistributions of source code must retain the above copyright notice, this\nlist of conditions and the following disclaimer. Redistributions in binary\nform must reproduce the above copyright notice, this list of conditions and\nthe following disclaimer in the documentation and/or other materials\nprovided with the distribution. Neither the name of the axTLS Project nor\nthe names of its contributors may be used to endorse or promote products\nderived from this software without specific prior written permission. \n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS &quot;AS IS&quot;\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR\nANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\nLIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\nOUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\nDAMAGE.</div> <div tiddler="License" modifier="YourName" modified="200711050226" created="200702240022" tags="">axTLS uses a BSD style license:\n\nCopyright (c) 2007, Cameron Rich All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\nRedistributions of source code must retain the above copyright notice, this\nlist of conditions and the following disclaimer. Redistributions in binary\nform must reproduce the above copyright notice, this list of conditions and\nthe following disclaimer in the documentation and/or other materials\nprovided with the distribution. Neither the name of the axTLS Project nor\nthe names of its contributors may be used to endorse or promote products\nderived from this software without specific prior written permission. \n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS &quot;AS IS&quot;\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR\nANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\nLIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\nOUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\nDAMAGE.</div>
<div tiddler="MainMenu" modifier="CameronRich" modified="200702250353" created="200702240021" tags="">[[Read Me]] \n[[Changelog]]\n[[axhttpd]]\n[[License]]</div> <div tiddler="MainMenu" modifier="CameronRich" modified="200702250353" created="200702240021" tags="">[[Read Me]] \n[[Changelog]]\n[[axhttpd]]\n[[License]]</div>