1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-08-09 22:24:14 +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

@@ -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
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
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
code update).
@@ -125,6 +129,62 @@ config CONFIG_SSL_USE_DEFAULT_KEY
This mode is enabled by default. Disable this mode if the
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
bool "Enable v23 Handshake"
default y
@@ -251,13 +311,6 @@ config CONFIG_OPENSSL_COMPATIBLE
Note: not all the API is implemented, so parts may still break. And
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
bool "Build the bigint performance test tool"
default n

View File

@@ -48,10 +48,8 @@ BASETARGET=libaxtls.so
CRYPTO_PATH=$(AXTLS_HOME)/crypto/
ifdef CONFIG_PLATFORM_CYGWIN
TARGET2=$(AXTLS_HOME)/$(STAGE)/libaxtls.dll.a
TARGET3=$(AXTLS_HOME)/$(STAGE)/gen_cert.exe
else
TARGET2=$(AXTLS_HOME)/$(STAGE)/$(LIBMINOR)
TARGET3=$(AXTLS_HOME)/$(STAGE)/gen_cert
endif
# shared library major/minor numbers
@@ -64,7 +62,7 @@ STATIC_LIB=$(AXTLS_HOME)/$(STAGE)/axtls.static.lib
CRYPTO_PATH=$(AXTLS_HOME)\\crypto\\
endif
libs: $(TARGET1) $(TARGET2) $(TARGET3)
libs: $(TARGET1) $(TARGET2)
CRYPTO_OBJ=\
$(CRYPTO_PATH)aes.o \
@@ -79,14 +77,15 @@ CRYPTO_OBJ=\
OBJ=\
asn1.o \
x509.o \
os_port.o \
gen_cert.o \
loader.o \
openssl.o \
os_port.o \
p12.o \
tls1.o \
tls1_svr.o \
tls1_clnt.o
tls1_clnt.o \
x509.o
include $(AXTLS_HOME)/config/makefile.post
@@ -106,9 +105,6 @@ else
-Wl,--enable-auto-import $(CRYPTO_OBJ) $(OBJ)
endif
$(TARGET3): gen_cert.o
$(LD) $(LDFLAGS) -o $@ $< -L$(AXTLS_HOME)/$(STAGE) -laxtls
else # Win32
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)
goto end_int_array;
*object = (uint8_t *)malloc(len);
/* TODO */
#if 0
if (*object == 0x00) /* ignore the negative byte */
if (buf[*offset] == 0x00) /* ignore the negative byte */
{
len--;
(*object)++;
(*offset)++;
}
#endif
*object = (uint8_t *)malloc(len);
memcpy(*object, &buf[*offset], len);
*offset += len;
@@ -421,10 +418,13 @@ void remove_ca_certs(CA_CERT_CTX *ca_cert_ctx)
{
int i = 0;
if (ca_cert_ctx == NULL)
return;
while (i < CONFIG_X509_MAX_CA_CERTS && 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);
@@ -441,9 +441,7 @@ int asn1_compare_dn(char * const dn1[], char * const dn2[])
for (i = 0; i < X509_NUM_DN_TYPES; i++)
{
if (asn1_compare_dn_comp(dn1[i], dn2[i]))
{
return 1;
}
}
return 0; /* all good */

View File

@@ -68,13 +68,8 @@ struct _x509_ctx
{
char *ca_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_after;
#endif
uint8_t *signature;
uint16_t sig_len;
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);
#endif
#ifdef CONFIG_SSL_FULL_MODE
void x509_print(CA_CERT_CTX *ca_cert_ctx, const X509_CTX *cert);
void x509_display_error(int error);
void x509_print(const X509_CTX *cert, CA_CERT_CTX *ca_cert_ctx);
const char * x509_display_error(int error);
#endif
/**************************************************************************

View File

@@ -30,13 +30,13 @@
#include "config.h"
#ifdef CONFIG_GEN_CERTIFICATES
#ifdef CONFIG_SSL_GENERATE_X509_CERT
#include <string.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) */
@@ -176,33 +176,35 @@ error:
return ret;
}
static int gen_issuer(const char *cn, const char *o, const char *ou,
uint8_t *buf, int *offset)
static int gen_issuer(const char * dn[], uint8_t *buf, int *offset)
{
int ret = X509_OK;
int seq_offset;
int seq_size = pre_adjust_with_size(
ASN1_SEQUENCE, &seq_offset, buf, offset);
char hostname[128];
/* we need the common name at a minimum */
if (cn == NULL)
/* we need the common name, so if not configured, use the hostname */
if (dn[X509_COMMON_NAME] == NULL || strlen(dn[X509_COMMON_NAME]) == 0)
{
ret = X509_NOT_OK;
gethostname(hostname, sizeof(hostname));
dn[X509_COMMON_NAME] = hostname;
}
if ((ret = gen_dn(dn[X509_COMMON_NAME], 3, buf, offset)))
goto error;
}
if ((ret = gen_dn(cn, 3, buf, offset)))
goto error;
if (dn[X509_ORGANIZATION] == NULL || strlen(dn[X509_ORGANIZATION]) == 0)
dn[X509_ORGANIZATION] = getenv("USERNAME");
if (o != 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, 10, buf, offset)))
goto error;
}
if (ou != NULL)
{
if ((ret = gen_dn(o, 11, buf, offset)))
if ((ret = gen_dn(dn[X509_ORGANIZATIONAL_TYPE], 11, buf, offset)))
goto error;
}
@@ -212,32 +214,20 @@ error:
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)
{
time_t curr_time = time(NULL);
struct tm *now_tm = gmtime(&curr_time);
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;
/* fixed time */
memcpy(&buf[*offset], time_seq, sizeof(time_seq));
*offset += sizeof(time_seq);
}
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);
buf[(*offset)++] = ASN1_INTEGER;
bi_export(rsa_ctx->bi_ctx, rsa_ctx->m, block, pub_key_size);
if (*block & 0x80) /* make integer positive */
{
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);
*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);
}
@@ -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)++] = 0;
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);
}
@@ -313,86 +304,64 @@ static void gen_signature(const RSA_CTX *rsa_ctx, const uint8_t *sha_dgst,
*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,
uint8_t *sha_dgst)
{
int ret = X509_OK;
SHA1_CTX sha_ctx;
int seq_offset;
int begin_tbs = *offset;
int seq_size = pre_adjust_with_size(
ASN1_SEQUENCE, &seq_offset, buf, offset);
int begin_tbs = *offset;
gen_serial_number(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;
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;
gen_pub_key(rsa_ctx, buf, offset);
adjust_with_size(seq_size, seq_offset, buf, offset);
SHA1_Init(&sha_ctx);
SHA1_Update(&sha_ctx, &buf[begin_tbs], *offset-begin_tbs);
SHA1_Final(sha_dgst, &sha_ctx);
adjust_with_size(seq_size, seq_offset, buf, offset);
error:
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 offset = 0;
int seq_offset;
int ret = X509_OK, offset = 0, seq_offset;
/* allocate enough space to load a new certificate */
uint8_t *buf = (uint8_t *)alloca(ssl_ctx->rsa_ctx->num_octets*2 + 512);
uint8_t sha_dgst[SHA1_SIZE];
int seq_size = pre_adjust_with_size(
ASN1_SEQUENCE, &seq_offset, buf, &offset);
int seq_size = pre_adjust_with_size(ASN1_SEQUENCE,
&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;
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);
*cert_size = offset;
*cert_data = (uint8_t *)malloc(offset); /* create the exact memory for it */
memcpy(*cert_data, buf, offset);
error:
return ret;
}
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;
return ret < 0 ? ret : offset;
}
#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->len = get_file(filename, &ssl_obj->buf);
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)
{
int ret;
SSLObjLoader *ssl_obj;
ssl_obj = (SSLObjLoader *)calloc(1, sizeof(SSLObjLoader));
ssl_obj->buf = (uint8_t *)malloc(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;
uint8_t key[32]; /* AES256 size */
if (password == NULL)
if (password == NULL || strlen(password) == 0)
{
#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
goto error;
}
@@ -239,7 +238,7 @@ static int pem_decrypt(const char *where, const char *end,
else
{
#ifdef CONFIG_SSL_FULL_MODE
printf("Error: Unsupported password cipher\n");
printf("Error: Unsupported password cipher\n"); TTY_FLUSH();
#endif
goto error;
}
@@ -387,3 +386,80 @@ static int ssl_obj_PEM_load(SSL_CTX *ssl_ctx, int obj_type,
start, ssl_obj->len, password);
}
#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
* i.e. each handshake will include a "certificate request" message from the
* 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
* during the handshake.
* - 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);
#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.
* @note New API function for v1.1
*/
EXP_FUNC const char * STDCALL ssl_version(void);

View File

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

View File

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

View File

@@ -38,14 +38,6 @@
#include <stdarg.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 */
#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->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
ssl_ctx->num_sessions = num_sessions;
#endif
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
if (num_sessions)
{
@@ -197,10 +186,6 @@ EXP_FUNC SSL_CTX *STDCALL ssl_ctx_new(uint32_t options, int num_sessions)
}
#endif
#ifdef CONFIG_SSL_CERT_VERIFICATION
ssl_ctx->ca_cert_ctx = (CA_CERT_CTX *)calloc(1, sizeof(CA_CERT_CTX));
#endif
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 offset;
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])
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];
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);
x509_free(cert); /* get rid of it */
ca_cert_ctx->cert[i] = NULL;
#ifdef CONFIG_SSL_FULL_MODE
printf("Error: %s\n", x509_display_error(ret));
#endif
goto error;
}
@@ -1484,6 +1477,7 @@ int send_certificate(SSL *ssl)
while (i < ssl->ssl_ctx->chain_length)
{
X509_CTX *cert_ctx;
SSL_CERT *cert = &ssl->ssl_ctx->certs[i];
buf[offset++] = 0;
buf[offset++] = cert->size >> 8; /* cert 1 length */
@@ -1491,6 +1485,10 @@ int send_certificate(SSL *ssl)
memcpy(&buf[offset], cert->buf, cert->size);
offset += cert->size;
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;
@@ -1765,7 +1763,7 @@ int process_certificate(SSL *ssl, X509_CTX **x509_ctx)
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->dc->bm_proc_index += offset;
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.
*/
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))
return;
x509_print(ssl->ssl_ctx->ca_cert_ctx, x509_ctx);
x509_print(x509_ctx, ssl->ssl_ctx->ca_cert_ctx);
TTY_FLUSH();
}
/**
* 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))
return;
@@ -1897,8 +1895,7 @@ EXP_FUNC void STDCALL ssl_display_error(int error_code)
/* X509 error? */
if (error_code < SSL_X509_OFFSET)
{
x509_display_error(error_code - SSL_X509_OFFSET);
printf("\n");
printf("%s\n", x509_display_error(error_code - SSL_X509_OFFSET));
return;
}

View File

@@ -172,7 +172,7 @@ struct _SSL
uint16_t bm_read_index;
struct _SSL *next; /* doubly linked list */
struct _SSL *prev;
struct _SSL_CTX *ssl_ctx; /* back reference to a clnt/svr ctx */
struct _SSL_CTX *ssl_ctx; /* back reference to a clnt/svr ctx */
#ifndef CONFIG_SSL_SKELETON_MODE
uint16_t session_index;
SSL_SESS *session;
@@ -243,6 +243,7 @@ int add_private_key(SSL_CTX *ssl_ctx, SSLObjLoader *ssl_obj);
void ssl_obj_free(SSLObjLoader *ssl_obj);
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 load_key_certs(SSL_CTX *ssl_ctx);
#ifdef CONFIG_SSL_CERT_VERIFICATION
int add_cert_auth(SSL_CTX *ssl_ctx, const uint8_t *buf, int len);
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_BYTES(SSL *ssl, const char *format,
const uint8_t *data, int size, ...);
void DISPLAY_CERT(SSL *ssl, const char *label, const X509_CTX *x509_ctx);
void DISPLAY_RSA(SSL *ssl, const char *label, const RSA_CTX *rsa_ctx);
void DISPLAY_CERT(SSL *ssl, const X509_CTX *x509_ctx);
void DISPLAY_RSA(SSL *ssl, const RSA_CTX *rsa_ctx);
void DISPLAY_ALERT(SSL *ssl, int alert);
#else
#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;
#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)
{
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);
bi_export(ctx, decrypted_bi, block, sig_len);
print_blob("SIGNATURE", block, sig_len);
ctx->mod_offset = BIGINT_M_OFFSET;
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 */
if (size > 0)
{
FILE *f = fopen("blah.dat", "w");
fwrite(&block[i], sig_len-i, 1, f);
fclose(f);
int 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;
struct timeval tv;
int match_ca_cert = 0;
uint8_t is_self_signed = 0;
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 */
if (cert->next == NULL)
if (cert->next == NULL && ca_cert_ctx)
{
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)
{
match_ca_cert = 1;
next_cert = ca_cert_ctx->cert[i];
break;
}
i++;
}
if (i < CONFIG_X509_MAX_CA_CERTS && ca_cert_ctx->cert[i])
{
next_cert = ca_cert_ctx->cert[i];
}
else /* trusted cert not found */
/* trusted cert not found */
if (i >= CONFIG_X509_MAX_CA_CERTS)
{
ret = X509_VFY_ERROR_NO_TRUSTED_CERT;
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 */
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;
goto end_verify;
}
ctx = cert->rsa_ctx->bi_ctx;
/* 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;
goto end_verify;
is_self_signed = 1;
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 */
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,
bi_clone(ctx, mod), bi_clone(ctx, expn));
if (cert_sig)
if (cert_sig && cert->digest)
{
ret = cert->digest ? /* check the signature */
bi_compare(cert_sig, cert->digest) :
X509_VFY_ERROR_UNSUPPORTED_DIGEST;
if (bi_compare(cert_sig, cert->digest))
ret = X509_VFY_ERROR_BAD_SIGNATURE;
bi_free(ctx, cert_sig);
if (ret)
@@ -361,6 +362,12 @@ int x509_verify(const CA_CERT_CTX *ca_cert_ctx, const X509_CTX *cert)
goto end_verify;
}
if (is_self_signed)
{
ret = X509_VFY_ERROR_SELF_SIGNED;
goto end_verify;
}
/* go down the certificate chain using recursion. */
if (ret == 0 && cert->next)
{
@@ -376,7 +383,7 @@ end_verify:
/**
* 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)
return;
@@ -436,14 +443,12 @@ void x509_print(CA_CERT_CTX *ca_cert_ctx, const X509_CTX *cert)
break;
}
printf("Verify:\t\t\t");
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
print_blob("Signature", cert->signature, cert->sig_len);
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)
{
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)
{
case X509_NOT_OK:
printf("X509 not ok");
return "X509 not ok";
break;
case X509_VFY_ERROR_NO_TRUSTED_CERT:
printf("No trusted cert is available");
return "No trusted cert is available";
break;
case X509_VFY_ERROR_BAD_SIGNATURE:
printf("Bad signature");
return "Bad signature";
break;
case X509_VFY_ERROR_NOT_YET_VALID:
printf("Cert is not yet valid");
return "Cert is not yet valid";
break;
case X509_VFY_ERROR_EXPIRED:
printf("Cert has expired");
return "Cert has expired";
break;
case X509_VFY_ERROR_SELF_SIGNED:
printf("Cert is self-signed");
return "Cert is self-signed";
break;
case X509_VFY_ERROR_INVALID_CHAIN:
printf("Chain is invalid (check order of certs)");
return "Chain is invalid (check order of certs)";
break;
case X509_VFY_ERROR_UNSUPPORTED_DIGEST:
printf("Unsupported digest");
return "Unsupported digest";
break;
case X509_INVALID_PRIV_KEY:
printf("Invalid private key");
return "Invalid private key";
break;
default:
return "Unknown";
break;
}
}