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:
@@ -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
|
||||
|
14
ssl/Makefile
14
ssl/Makefile
@@ -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)
|
||||
|
||||
|
16
ssl/asn1.c
16
ssl/asn1.c
@@ -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 */
|
||||
|
@@ -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
|
||||
|
||||
/**************************************************************************
|
||||
|
151
ssl/gen_cert.c
151
ssl/gen_cert.c
@@ -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
|
||||
|
86
ssl/loader.c
86
ssl/loader.c
@@ -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;
|
||||
|
||||
}
|
||||
|
29
ssl/ssl.h
29
ssl/ssl.h
@@ -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);
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
|
57
ssl/tls1.c
57
ssl/tls1.c
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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)
|
||||
|
85
ssl/x509.c
85
ssl/x509.c
@@ -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;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user