summaryrefslogtreecommitdiff
path: root/axTLS/src/ssl
diff options
context:
space:
mode:
Diffstat (limited to 'axTLS/src/ssl')
-rw-r--r--axTLS/src/ssl/asn1.c565
-rw-r--r--axTLS/src/ssl/cert.h43
-rw-r--r--axTLS/src/ssl/crypto_misc.h173
-rw-r--r--axTLS/src/ssl/gen_cert.c364
-rw-r--r--axTLS/src/ssl/loader.c478
-rw-r--r--axTLS/src/ssl/openssl.c323
-rw-r--r--axTLS/src/ssl/os_port.c158
-rw-r--r--axTLS/src/ssl/os_port.h208
-rw-r--r--axTLS/src/ssl/p12.c483
-rw-r--r--axTLS/src/ssl/private_key.h54
-rw-r--r--axTLS/src/ssl/ssl.h499
-rw-r--r--axTLS/src/ssl/tls1.c2195
-rw-r--r--axTLS/src/ssl/tls1.h295
-rw-r--r--axTLS/src/ssl/tls1_clnt.c395
-rw-r--r--axTLS/src/ssl/tls1_svr.c478
-rw-r--r--axTLS/src/ssl/version.h1
-rw-r--r--axTLS/src/ssl/x509.c564
17 files changed, 0 insertions, 7276 deletions
diff --git a/axTLS/src/ssl/asn1.c b/axTLS/src/ssl/asn1.c
deleted file mode 100644
index cf8d5be..0000000
--- a/axTLS/src/ssl/asn1.c
+++ /dev/null
@@ -1,565 +0,0 @@
-/*
- * Copyright (c) 2007, Cameron Rich
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * * Neither the name of the axTLS project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * Some primitive asn methods for extraction ASN.1 data.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include "os_port.h"
-#include "crypto.h"
-#include "crypto_misc.h"
-
-#define SIG_OID_PREFIX_SIZE 8
-#define SIG_IIS6_OID_SIZE 5
-#define SIG_SUBJECT_ALT_NAME_SIZE 3
-
-/* Must be an RSA algorithm with either SHA1 or MD5 for verifying to work */
-static const uint8_t sig_oid_prefix[SIG_OID_PREFIX_SIZE] =
-{
- 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01
-};
-
-static const uint8_t sig_sha1WithRSAEncrypt[SIG_IIS6_OID_SIZE] =
-{
- 0x2b, 0x0e, 0x03, 0x02, 0x1d
-};
-
-static const uint8_t sig_subject_alt_name[SIG_SUBJECT_ALT_NAME_SIZE] =
-{
- 0x55, 0x1d, 0x11
-};
-
-/* CN, O, OU */
-static const uint8_t g_dn_types[] = { 3, 10, 11 };
-
-int get_asn1_length(const uint8_t *buf, int *offset)
-{
- int len, i;
-
- if (!(buf[*offset] & 0x80)) /* short form */
- {
- len = buf[(*offset)++];
- }
- else /* long form */
- {
- int length_bytes = buf[(*offset)++]&0x7f;
- len = 0;
- for (i = 0; i < length_bytes; i++)
- {
- len <<= 8;
- len += buf[(*offset)++];
- }
- }
-
- return len;
-}
-
-/**
- * Skip the ASN1.1 object type and its length. Get ready to read the object's
- * data.
- */
-int asn1_next_obj(const uint8_t *buf, int *offset, int obj_type)
-{
- if (buf[*offset] != obj_type)
- return X509_NOT_OK;
- (*offset)++;
- return get_asn1_length(buf, offset);
-}
-
-/**
- * Skip over an ASN.1 object type completely. Get ready to read the next
- * object.
- */
-int asn1_skip_obj(const uint8_t *buf, int *offset, int obj_type)
-{
- int len;
-
- if (buf[*offset] != obj_type)
- return X509_NOT_OK;
- (*offset)++;
- len = get_asn1_length(buf, offset);
- *offset += len;
- return 0;
-}
-
-/**
- * Read an integer value for ASN.1 data
- * Note: This function allocates memory which must be freed by the user.
- */
-int asn1_get_int(const uint8_t *buf, int *offset, uint8_t **object)
-{
- int len;
-
- if ((len = asn1_next_obj(buf, offset, ASN1_INTEGER)) < 0)
- goto end_int_array;
-
- if (len > 1 && buf[*offset] == 0x00) /* ignore the negative byte */
- {
- len--;
- (*offset)++;
- }
-
- *object = (uint8_t *)malloc(len);
- memcpy(*object, &buf[*offset], len);
- *offset += len;
-
-end_int_array:
- return len;
-}
-
-/**
- * Get all the RSA private key specifics from an ASN.1 encoded file
- */
-int asn1_get_private_key(const uint8_t *buf, int len, RSA_CTX **rsa_ctx)
-{
- int offset = 7;
- uint8_t *modulus = NULL, *priv_exp = NULL, *pub_exp = NULL;
- int mod_len, priv_len, pub_len;
-#ifdef CONFIG_BIGINT_CRT
- uint8_t *p = NULL, *q = NULL, *dP = NULL, *dQ = NULL, *qInv = NULL;
- int p_len, q_len, dP_len, dQ_len, qInv_len;
-#endif
-
- /* not in der format */
- if (buf[0] != ASN1_SEQUENCE) /* basic sanity check */
- {
-#ifdef CONFIG_SSL_FULL_MODE
- printf("Error: This is not a valid ASN.1 file\n");
-#endif
- return X509_INVALID_PRIV_KEY;
- }
-
- /* initialise the RNG */
- RNG_initialize(buf, len);
-
- mod_len = asn1_get_int(buf, &offset, &modulus);
- pub_len = asn1_get_int(buf, &offset, &pub_exp);
- priv_len = asn1_get_int(buf, &offset, &priv_exp);
-
- if (mod_len <= 0 || pub_len <= 0 || priv_len <= 0)
- return X509_INVALID_PRIV_KEY;
-
-#ifdef CONFIG_BIGINT_CRT
- p_len = asn1_get_int(buf, &offset, &p);
- q_len = asn1_get_int(buf, &offset, &q);
- dP_len = asn1_get_int(buf, &offset, &dP);
- dQ_len = asn1_get_int(buf, &offset, &dQ);
- qInv_len = asn1_get_int(buf, &offset, &qInv);
-
- if (p_len <= 0 || q_len <= 0 || dP_len <= 0 || dQ_len <= 0 || qInv_len <= 0)
- return X509_INVALID_PRIV_KEY;
-
- RSA_priv_key_new(rsa_ctx,
- modulus, mod_len, pub_exp, pub_len, priv_exp, priv_len,
- p, p_len, q, p_len, dP, dP_len, dQ, dQ_len, qInv, qInv_len);
-
- free(p);
- free(q);
- free(dP);
- free(dQ);
- free(qInv);
-#else
- RSA_priv_key_new(rsa_ctx,
- modulus, mod_len, pub_exp, pub_len, priv_exp, priv_len);
-#endif
-
- free(modulus);
- free(priv_exp);
- free(pub_exp);
- return X509_OK;
-}
-
-/**
- * Get the time of a certificate. Ignore hours/minutes/seconds.
- */
-static int asn1_get_utc_time(const uint8_t *buf, int *offset, time_t *t)
-{
- int ret = X509_NOT_OK, len, t_offset;
- struct tm tm;
-
- if (buf[(*offset)++] != ASN1_UTC_TIME)
- goto end_utc_time;
-
- len = get_asn1_length(buf, offset);
- t_offset = *offset;
-
- memset(&tm, 0, sizeof(struct tm));
- tm.tm_year = (buf[t_offset] - '0')*10 + (buf[t_offset+1] - '0');
-
- if (tm.tm_year <= 50) /* 1951-2050 thing */
- {
- tm.tm_year += 100;
- }
-
- tm.tm_mon = (buf[t_offset+2] - '0')*10 + (buf[t_offset+3] - '0') - 1;
- tm.tm_mday = (buf[t_offset+4] - '0')*10 + (buf[t_offset+5] - '0');
- *t = mktime(&tm);
- *offset += len;
- ret = X509_OK;
-
-end_utc_time:
- return ret;
-}
-
-/**
- * Get the version type of a certificate (which we don't actually care about)
- */
-int asn1_version(const uint8_t *cert, int *offset, X509_CTX *x509_ctx)
-{
- int ret = X509_NOT_OK;
-
- (*offset) += 2; /* get past explicit tag */
- if (asn1_skip_obj(cert, offset, ASN1_INTEGER))
- goto end_version;
-
- ret = X509_OK;
-end_version:
- return ret;
-}
-
-/**
- * Retrieve the notbefore and notafter certificate times.
- */
-int asn1_validity(const uint8_t *cert, int *offset, X509_CTX *x509_ctx)
-{
- return (asn1_next_obj(cert, offset, ASN1_SEQUENCE) < 0 ||
- asn1_get_utc_time(cert, offset, &x509_ctx->not_before) ||
- asn1_get_utc_time(cert, offset, &x509_ctx->not_after));
-}
-
-/**
- * Get the components of a distinguished name
- */
-static int asn1_get_oid_x520(const uint8_t *buf, int *offset)
-{
- int dn_type = 0;
- int len;
-
- if ((len = asn1_next_obj(buf, offset, ASN1_OID)) < 0)
- goto end_oid;
-
- /* expect a sequence of 2.5.4.[x] where x is a one of distinguished name
- components we are interested in. */
- if (len == 3 && buf[(*offset)++] == 0x55 && buf[(*offset)++] == 0x04)
- dn_type = buf[(*offset)++];
- else
- {
- *offset += len; /* skip over it */
- }
-
-end_oid:
- return dn_type;
-}
-
-/**
- * Obtain an ASN.1 printable string type.
- */
-static int asn1_get_printable_str(const uint8_t *buf, int *offset, char **str)
-{
- int len = X509_NOT_OK;
-
- /* some certs have this awful crud in them for some reason */
- if (buf[*offset] != ASN1_PRINTABLE_STR &&
- buf[*offset] != ASN1_PRINTABLE_STR2 &&
- buf[*offset] != ASN1_TELETEX_STR &&
- buf[*offset] != ASN1_IA5_STR &&
- buf[*offset] != ASN1_UNICODE_STR)
- goto end_pnt_str;
-
- (*offset)++;
- len = get_asn1_length(buf, offset);
-
- if (buf[*offset - 1] == ASN1_UNICODE_STR)
- {
- int i;
- *str = (char *)malloc(len/2+1); /* allow for null */
-
- for (i = 0; i < len; i += 2)
- (*str)[i/2] = buf[*offset + i + 1];
-
- (*str)[len/2] = 0; /* null terminate */
- }
- else
- {
- *str = (char *)malloc(len+1); /* allow for null */
- memcpy(*str, &buf[*offset], len);
- (*str)[len] = 0; /* null terminate */
- }
-
- *offset += len;
-
-end_pnt_str:
- return len;
-}
-
-/**
- * Get the subject name (or the issuer) of a certificate.
- */
-int asn1_name(const uint8_t *cert, int *offset, char *dn[])
-{
- int ret = X509_NOT_OK;
- int dn_type;
- char *tmp;
-
- if (asn1_next_obj(cert, offset, ASN1_SEQUENCE) < 0)
- goto end_name;
-
- while (asn1_next_obj(cert, offset, ASN1_SET) >= 0)
- {
- int i, found = 0;
-
- if (asn1_next_obj(cert, offset, ASN1_SEQUENCE) < 0 ||
- (dn_type = asn1_get_oid_x520(cert, offset)) < 0)
- goto end_name;
-
- tmp = NULL;
-
- if (asn1_get_printable_str(cert, offset, &tmp) < 0)
- {
- free(tmp);
- goto end_name;
- }
-
- /* find the distinguished named type */
- for (i = 0; i < X509_NUM_DN_TYPES; i++)
- {
- if (dn_type == g_dn_types[i])
- {
- if (dn[i] == NULL)
- {
- dn[i] = tmp;
- found = 1;
- break;
- }
- }
- }
-
- if (found == 0) /* not found so get rid of it */
- {
- free(tmp);
- }
- }
-
- ret = X509_OK;
-end_name:
- return ret;
-}
-
-/**
- * Read the modulus and public exponent of a certificate.
- */
-int asn1_public_key(const uint8_t *cert, int *offset, X509_CTX *x509_ctx)
-{
- int ret = X509_NOT_OK, mod_len, pub_len;
- uint8_t *modulus = NULL, *pub_exp = NULL;
-
- if (asn1_next_obj(cert, offset, ASN1_SEQUENCE) < 0 ||
- asn1_skip_obj(cert, offset, ASN1_SEQUENCE) ||
- asn1_next_obj(cert, offset, ASN1_BIT_STRING) < 0)
- goto end_pub_key;
-
- (*offset)++; /* ignore the padding bit field */
-
- if (asn1_next_obj(cert, offset, ASN1_SEQUENCE) < 0)
- goto end_pub_key;
-
- mod_len = asn1_get_int(cert, offset, &modulus);
- pub_len = asn1_get_int(cert, offset, &pub_exp);
-
- RSA_pub_key_new(&x509_ctx->rsa_ctx, modulus, mod_len, pub_exp, pub_len);
-
- free(modulus);
- free(pub_exp);
- ret = X509_OK;
-
-end_pub_key:
- return ret;
-}
-
-#ifdef CONFIG_SSL_CERT_VERIFICATION
-/**
- * Read the signature of the certificate.
- */
-int asn1_signature(const uint8_t *cert, int *offset, X509_CTX *x509_ctx)
-{
- int ret = X509_NOT_OK;
-
- if (cert[(*offset)++] != ASN1_BIT_STRING)
- goto end_sig;
-
- x509_ctx->sig_len = get_asn1_length(cert, offset)-1;
- (*offset)++; /* ignore bit string padding bits */
- x509_ctx->signature = (uint8_t *)malloc(x509_ctx->sig_len);
- memcpy(x509_ctx->signature, &cert[*offset], x509_ctx->sig_len);
- *offset += x509_ctx->sig_len;
- ret = X509_OK;
-
-end_sig:
- return ret;
-}
-
-/*
- * Compare 2 distinguished name components for equality
- * @return 0 if a match
- */
-static int asn1_compare_dn_comp(const char *dn1, const char *dn2)
-{
- int ret;
-
- if (dn1 == NULL && dn2 == NULL)
- ret = 0;
- else
- ret = (dn1 && dn2) ? strcmp(dn1, dn2) : 1;
-
- return ret;
-}
-
-/**
- * Clean up all of the CA certificates.
- */
-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;
- }
-
- free(ca_cert_ctx);
-}
-
-/*
- * Compare 2 distinguished names for equality
- * @return 0 if a match
- */
-int asn1_compare_dn(char * const dn1[], char * const dn2[])
-{
- int i;
-
- for (i = 0; i < X509_NUM_DN_TYPES; i++)
- {
- if (asn1_compare_dn_comp(dn1[i], dn2[i]))
- return 1;
- }
-
- return 0; /* all good */
-}
-
-int asn1_find_oid(const uint8_t* cert, int* offset,
- const uint8_t* oid, int oid_length)
-{
- int seqlen;
- if ((seqlen = asn1_next_obj(cert, offset, ASN1_SEQUENCE))> 0)
- {
- int end = *offset + seqlen;
-
- while (*offset < end)
- {
- int type = cert[(*offset)++];
- int length = get_asn1_length(cert, offset);
- int noffset = *offset + length;
-
- if (type == ASN1_SEQUENCE)
- {
- type = cert[(*offset)++];
- length = get_asn1_length(cert, offset);
-
- if (type == ASN1_OID && length == oid_length &&
- memcmp(cert + *offset, oid, oid_length) == 0)
- {
- *offset += oid_length;
- return 1;
- }
- }
-
- *offset = noffset;
- }
- }
-
- return 0;
-}
-
-int asn1_find_subjectaltname(const uint8_t* cert, int offset)
-{
- if (asn1_find_oid(cert, &offset, sig_subject_alt_name,
- SIG_SUBJECT_ALT_NAME_SIZE))
- {
- return offset;
- }
-
- return 0;
-}
-
-#endif /* CONFIG_SSL_CERT_VERIFICATION */
-
-/**
- * Read the signature type of the certificate. We only support RSA-MD5 and
- * RSA-SHA1 signature types.
- */
-int asn1_signature_type(const uint8_t *cert,
- int *offset, X509_CTX *x509_ctx)
-{
- int ret = X509_NOT_OK, len;
-
- if (cert[(*offset)++] != ASN1_OID)
- goto end_check_sig;
-
- len = get_asn1_length(cert, offset);
-
- if (len == 5 && memcmp(sig_sha1WithRSAEncrypt, &cert[*offset],
- SIG_IIS6_OID_SIZE) == 0)
- {
- x509_ctx->sig_type = SIG_TYPE_SHA1;
- }
- else
- {
- if (memcmp(sig_oid_prefix, &cert[*offset], SIG_OID_PREFIX_SIZE))
- goto end_check_sig; /* unrecognised cert type */
-
- x509_ctx->sig_type = cert[*offset + SIG_OID_PREFIX_SIZE];
- }
-
- *offset += len;
- asn1_skip_obj(cert, offset, ASN1_NULL); /* if it's there */
- ret = X509_OK;
-
-end_check_sig:
- return ret;
-}
-
diff --git a/axTLS/src/ssl/cert.h b/axTLS/src/ssl/cert.h
deleted file mode 100644
index 30c7b65..0000000
--- a/axTLS/src/ssl/cert.h
+++ /dev/null
@@ -1,43 +0,0 @@
-unsigned char default_certificate[] = {
- 0x30, 0x82, 0x01, 0xd7, 0x30, 0x82, 0x01, 0x40, 0x02, 0x09, 0x00, 0xab,
- 0x08, 0x18, 0xa7, 0x03, 0x07, 0x27, 0xfd, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x34,
- 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x29, 0x61,
- 0x78, 0x54, 0x4c, 0x53, 0x20, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74,
- 0x20, 0x44, 0x6f, 0x64, 0x67, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
- 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f,
- 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, 0x31, 0x32,
- 0x32, 0x36, 0x32, 0x32, 0x33, 0x33, 0x33, 0x39, 0x5a, 0x17, 0x0d, 0x32,
- 0x34, 0x30, 0x39, 0x30, 0x33, 0x32, 0x32, 0x33, 0x33, 0x33, 0x39, 0x5a,
- 0x30, 0x2c, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
- 0x0d, 0x61, 0x78, 0x54, 0x4c, 0x53, 0x20, 0x50, 0x72, 0x6f, 0x6a, 0x65,
- 0x63, 0x74, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
- 0x09, 0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x30, 0x81,
- 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
- 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02,
- 0x81, 0x81, 0x00, 0xcd, 0xfd, 0x89, 0x48, 0xbe, 0x36, 0xb9, 0x95, 0x76,
- 0xd4, 0x13, 0x30, 0x0e, 0xbf, 0xb2, 0xed, 0x67, 0x0a, 0xc0, 0x16, 0x3f,
- 0x51, 0x09, 0x9d, 0x29, 0x2f, 0xb2, 0x6d, 0x3f, 0x3e, 0x6c, 0x2f, 0x90,
- 0x80, 0xa1, 0x71, 0xdf, 0xbe, 0x38, 0xc5, 0xcb, 0xa9, 0x9a, 0x40, 0x14,
- 0x90, 0x0a, 0xf9, 0xb7, 0x07, 0x0b, 0xe1, 0xda, 0xe7, 0x09, 0xbf, 0x0d,
- 0x57, 0x41, 0x86, 0x60, 0xa1, 0xc1, 0x27, 0x91, 0x5b, 0x0a, 0x98, 0x46,
- 0x1b, 0xf6, 0xa2, 0x84, 0xf8, 0x65, 0xc7, 0xce, 0x2d, 0x96, 0x17, 0xaa,
- 0x91, 0xf8, 0x61, 0x04, 0x50, 0x70, 0xeb, 0xb4, 0x43, 0xb7, 0xdc, 0x9a,
- 0xcc, 0x31, 0x01, 0x14, 0xd4, 0xcd, 0xcc, 0xc2, 0x37, 0x6d, 0x69, 0x82,
- 0xd6, 0xc6, 0xc4, 0xbe, 0xf2, 0x34, 0xa5, 0xc9, 0xa6, 0x19, 0x53, 0x32,
- 0x7a, 0x86, 0x0e, 0x91, 0x82, 0x0f, 0xa1, 0x42, 0x54, 0xaa, 0x01, 0x02,
- 0x03, 0x01, 0x00, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
- 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x40,
- 0xb4, 0x94, 0x9a, 0xa8, 0x89, 0x72, 0x1d, 0x07, 0xe5, 0xb3, 0x6b, 0x88,
- 0x21, 0xc2, 0x38, 0x36, 0x9e, 0x7a, 0x8c, 0x49, 0x48, 0x68, 0x0c, 0x06,
- 0xe8, 0xdb, 0x1f, 0x4e, 0x05, 0xe6, 0x31, 0xe3, 0xfd, 0xe6, 0x0d, 0x6b,
- 0xd8, 0x13, 0x17, 0xe0, 0x2d, 0x0d, 0xb8, 0x7e, 0xcb, 0x20, 0x6c, 0xa8,
- 0x73, 0xa7, 0xfd, 0xe3, 0xa7, 0xfa, 0xf3, 0x02, 0x60, 0x78, 0x1f, 0x13,
- 0x40, 0x45, 0xee, 0x75, 0xf5, 0x10, 0xfd, 0x8f, 0x68, 0x74, 0xd4, 0xac,
- 0xae, 0x04, 0x09, 0x55, 0x2c, 0xdb, 0xd8, 0x07, 0x07, 0x65, 0x69, 0x27,
- 0x6e, 0xbf, 0x5e, 0x61, 0x40, 0x56, 0x8b, 0xd7, 0x33, 0x3b, 0xff, 0x6e,
- 0x53, 0x7e, 0x9d, 0x3f, 0xc0, 0x40, 0x3a, 0xab, 0xa0, 0x50, 0x4e, 0x80,
- 0x47, 0x46, 0x0d, 0x1e, 0xdb, 0x4c, 0xf1, 0x1b, 0x5d, 0x3c, 0x2a, 0x54,
- 0xa7, 0x4d, 0xfa, 0x7b, 0x72, 0x66, 0xc5
-};
-unsigned int default_certificate_len = 475;
diff --git a/axTLS/src/ssl/crypto_misc.h b/axTLS/src/ssl/crypto_misc.h
deleted file mode 100644
index 9c9e2aa..0000000
--- a/axTLS/src/ssl/crypto_misc.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright (c) 2007, Cameron Rich
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * * Neither the name of the axTLS project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/**
- * @file crypto_misc.h
- */
-
-#ifndef HEADER_CRYPTO_MISC_H
-#define HEADER_CRYPTO_MISC_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "crypto.h"
-#include "bigint.h"
-
-/**************************************************************************
- * X509 declarations
- **************************************************************************/
-#define X509_OK 0
-#define X509_NOT_OK -1
-#define X509_VFY_ERROR_NO_TRUSTED_CERT -2
-#define X509_VFY_ERROR_BAD_SIGNATURE -3
-#define X509_VFY_ERROR_NOT_YET_VALID -4
-#define X509_VFY_ERROR_EXPIRED -5
-#define X509_VFY_ERROR_SELF_SIGNED -6
-#define X509_VFY_ERROR_INVALID_CHAIN -7
-#define X509_VFY_ERROR_UNSUPPORTED_DIGEST -8
-#define X509_INVALID_PRIV_KEY -9
-
-/*
- * The Distinguished Name
- */
-#define X509_NUM_DN_TYPES 3
-#define X509_COMMON_NAME 0
-#define X509_ORGANIZATION 1
-#define X509_ORGANIZATIONAL_UNIT 2
-
-struct _x509_ctx
-{
- char *ca_cert_dn[X509_NUM_DN_TYPES];
- char *cert_dn[X509_NUM_DN_TYPES];
- char **subject_alt_dnsnames;
- time_t not_before;
- time_t not_after;
- uint8_t *signature;
- uint16_t sig_len;
- uint8_t sig_type;
- RSA_CTX *rsa_ctx;
- bigint *digest;
- uint8_t sha1_fingerprint[SHA1_SIZE];
- struct _x509_ctx *next;
-};
-
-typedef struct _x509_ctx X509_CTX;
-
-#ifdef CONFIG_SSL_CERT_VERIFICATION
-typedef struct
-{
- X509_CTX *cert[CONFIG_X509_MAX_CA_CERTS];
-} CA_CERT_CTX;
-#endif
-
-int x509_new(const uint8_t *cert, int *len, X509_CTX **ctx);
-void x509_free(X509_CTX *x509_ctx);
-#ifdef CONFIG_SSL_CERT_VERIFICATION
-int x509_verify(const CA_CERT_CTX *ca_cert_ctx, const X509_CTX *cert);
-#endif
-#ifdef CONFIG_SSL_FULL_MODE
-void x509_print(const X509_CTX *cert, CA_CERT_CTX *ca_cert_ctx);
-const char * x509_display_error(int error);
-#endif
-
-/**************************************************************************
- * ASN1 declarations
- **************************************************************************/
-#define ASN1_INTEGER 0x02
-#define ASN1_BIT_STRING 0x03
-#define ASN1_OCTET_STRING 0x04
-#define ASN1_NULL 0x05
-#define ASN1_PRINTABLE_STR2 0x0C
-#define ASN1_OID 0x06
-#define ASN1_PRINTABLE_STR2 0x0C
-#define ASN1_PRINTABLE_STR 0x13
-#define ASN1_TELETEX_STR 0x14
-#define ASN1_IA5_STR 0x16
-#define ASN1_UTC_TIME 0x17
-#define ASN1_UNICODE_STR 0x1e
-#define ASN1_SEQUENCE 0x30
-#define ASN1_CONTEXT_DNSNAME 0x82
-#define ASN1_SET 0x31
-#define ASN1_V3_DATA 0xa3
-#define ASN1_IMPLICIT_TAG 0x80
-#define ASN1_CONTEXT_DNSNAME 0x82
-#define ASN1_EXPLICIT_TAG 0xa0
-#define ASN1_V3_DATA 0xa3
-
-#define SIG_TYPE_MD2 0x02
-#define SIG_TYPE_MD5 0x04
-#define SIG_TYPE_SHA1 0x05
-
-int get_asn1_length(const uint8_t *buf, int *offset);
-int asn1_get_private_key(const uint8_t *buf, int len, RSA_CTX **rsa_ctx);
-int asn1_next_obj(const uint8_t *buf, int *offset, int obj_type);
-int asn1_skip_obj(const uint8_t *buf, int *offset, int obj_type);
-int asn1_get_int(const uint8_t *buf, int *offset, uint8_t **object);
-int asn1_version(const uint8_t *cert, int *offset, X509_CTX *x509_ctx);
-int asn1_validity(const uint8_t *cert, int *offset, X509_CTX *x509_ctx);
-int asn1_name(const uint8_t *cert, int *offset, char *dn[]);
-int asn1_public_key(const uint8_t *cert, int *offset, X509_CTX *x509_ctx);
-#ifdef CONFIG_SSL_CERT_VERIFICATION
-int asn1_signature(const uint8_t *cert, int *offset, X509_CTX *x509_ctx);
-int asn1_find_subjectaltname(const uint8_t* cert, int offset);
-int asn1_compare_dn(char * const dn1[], char * const dn2[]);
-#endif /* CONFIG_SSL_CERT_VERIFICATION */
-int asn1_signature_type(const uint8_t *cert,
- int *offset, X509_CTX *x509_ctx);
-
-/**************************************************************************
- * MISC declarations
- **************************************************************************/
-#define SALT_SIZE 8
-
-extern const char * const unsupported_str;
-
-typedef void (*crypt_func)(void *, const uint8_t *, uint8_t *, int);
-typedef void (*hmac_func)(const uint8_t *msg, int length, const uint8_t *key,
- int key_len, uint8_t *digest);
-
-int get_file(const char *filename, uint8_t **buf);
-
-#if defined(CONFIG_SSL_FULL_MODE) || defined(WIN32) || defined(CONFIG_DEBUG)
-EXP_FUNC void STDCALL print_blob(const char *format, const uint8_t *data, int size, ...);
-#else
- #define print_blob(...)
-#endif
-
-EXP_FUNC int STDCALL base64_decode(const char *in, int len,
- uint8_t *out, int *outlen);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/axTLS/src/ssl/gen_cert.c b/axTLS/src/ssl/gen_cert.c
deleted file mode 100644
index c2fe381..0000000
--- a/axTLS/src/ssl/gen_cert.c
+++ /dev/null
@@ -1,364 +0,0 @@
-/*
- * Copyright (c) 2007, Cameron Rich
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * * Neither the name of the axTLS project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#ifdef CONFIG_SSL_GENERATE_X509_CERT
-#include <string.h>
-#include <stdlib.h>
-#include "os_port.h"
-#include "ssl.h"
-
-/**
- * Generate a basic X.509 certificate
- */
-
-static uint8_t set_gen_length(int len, uint8_t *buf, int *offset)
-{
- if (len < 0x80) /* short form */
- {
- buf[(*offset)++] = len;
- return 1;
- }
- else /* long form */
- {
- int i, length_bytes = 0;
-
- if (len & 0x00FF0000)
- length_bytes = 3;
- else if (len & 0x0000FF00)
- length_bytes = 2;
- else if (len & 0x000000FF)
- length_bytes = 1;
-
- buf[(*offset)++] = 0x80 + length_bytes;
-
- for (i = length_bytes-1; i >= 0; i--)
- {
- buf[*offset+i] = len & 0xFF;
- len >>= 8;
- }
-
- *offset += length_bytes;
- return length_bytes+1;
- }
-}
-
-static int pre_adjust_with_size(uint8_t type,
- int *seq_offset, uint8_t *buf, int *offset)
-{
- buf[(*offset)++] = type;
- *seq_offset = *offset;
- *offset += 4; /* fill in later */
- return *offset;
-}
-
-static void adjust_with_size(int seq_size, int seq_start,
- uint8_t *buf, int *offset)
-{
- uint8_t seq_byte_size;
- int orig_seq_size = seq_size;
- int orig_seq_start = seq_start;
-
- seq_size = *offset-seq_size;
- seq_byte_size = set_gen_length(seq_size, buf, &seq_start);
-
- if (seq_byte_size != 4)
- {
- memmove(&buf[orig_seq_start+seq_byte_size],
- &buf[orig_seq_size], seq_size);
- *offset -= 4-seq_byte_size;
- }
-}
-
-static void gen_serial_number(uint8_t *buf, int *offset)
-{
- static const uint8_t ser_oid[] = { ASN1_INTEGER, 1, 0x7F };
- memcpy(&buf[*offset], ser_oid , sizeof(ser_oid));
- *offset += sizeof(ser_oid);
-}
-
-static void gen_signature_alg(uint8_t *buf, int *offset)
-{
- /* OBJECT IDENTIFIER sha1withRSAEncryption (1 2 840 113549 1 1 5) */
- static const uint8_t sig_oid[] =
- {
- ASN1_SEQUENCE, 0x0d, ASN1_OID, 0x09,
- 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
- ASN1_NULL, 0x00
- };
-
- memcpy(&buf[*offset], sig_oid, sizeof(sig_oid));
- *offset += sizeof(sig_oid);
-}
-
-static int gen_dn(const char *name, uint8_t dn_type,
- uint8_t *buf, int *offset)
-{
- int ret = X509_OK;
- int name_size = strlen(name);
-
- if (name_size > 0x70) /* just too big */
- {
- ret = X509_NOT_OK;
- goto error;
- }
-
- buf[(*offset)++] = ASN1_SET;
- set_gen_length(9+name_size, buf, offset);
- buf[(*offset)++] = ASN1_SEQUENCE;
- set_gen_length(7+name_size, buf, offset);
- buf[(*offset)++] = ASN1_OID;
- buf[(*offset)++] = 3;
- buf[(*offset)++] = 0x55;
- buf[(*offset)++] = 0x04;
- buf[(*offset)++] = dn_type;
- buf[(*offset)++] = ASN1_PRINTABLE_STR;
- buf[(*offset)++] = name_size;
- strcpy(&buf[*offset], name);
- *offset += name_size;
-
-error:
- return ret;
-}
-
-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 fqdn[128];
-
- /* we need the common name, so if not configured, work out the fully
- * qualified domain name */
- if (dn[X509_COMMON_NAME] == NULL || strlen(dn[X509_COMMON_NAME]) == 0)
- {
- int fqdn_len;
- gethostname(fqdn, sizeof(fqdn));
- fqdn_len = strlen(fqdn);
- fqdn[fqdn_len++] = '.';
- getdomainname(&fqdn[fqdn_len], sizeof(fqdn)-fqdn_len);
- fqdn_len = strlen(fqdn);
-
- if (fqdn[fqdn_len-1] == '.') /* ensure '.' is not last char */
- fqdn[fqdn_len-1] = 0;
-
- dn[X509_COMMON_NAME] = fqdn;
- }
-
- if ((ret = gen_dn(dn[X509_COMMON_NAME], 3, buf, offset)))
- goto error;
-
- if (dn[X509_ORGANIZATION] != NULL && strlen(dn[X509_ORGANIZATION]) > 0)
- {
- if ((ret = gen_dn(dn[X509_ORGANIZATION], 10, buf, offset)))
- goto error;
- }
-
- if (dn[X509_ORGANIZATIONAL_UNIT] != NULL &&
- strlen(dn[X509_ORGANIZATIONAL_UNIT]) > 0)
- {
- if ((ret = gen_dn(dn[X509_ORGANIZATIONAL_UNIT], 11, buf, offset)))
- goto error;
- }
-
- adjust_with_size(seq_size, seq_offset, buf, offset);
-
-error:
- return ret;
-}
-
-static void gen_utc_time(uint8_t *buf, int *offset)
-{
- 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 30 or so years */
- '3', '8', '0', '1', '0', '1', '0', '0', '0', '0', '0', '0', 'Z'
- };
-
- /* 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)
-{
- static const uint8_t pub_key_seq[] =
- {
- ASN1_INTEGER, 0x03, 0x01, 0x00, 0x01 /* INTEGER 65537 */
- };
-
- int seq_offset;
- int pub_key_size = rsa_ctx->num_octets;
- uint8_t *block = (uint8_t *)alloca(pub_key_size);
- int seq_size = pre_adjust_with_size(
- 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);
- buf[(*offset)++] = 0;
- }
- else
- set_gen_length(pub_key_size, buf, 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);
-}
-
-static void gen_pub_key1(const RSA_CTX *rsa_ctx, uint8_t *buf, int *offset)
-{
- int seq_offset;
- int seq_size = pre_adjust_with_size(
- ASN1_BIT_STRING, &seq_offset, buf, offset);
- buf[(*offset)++] = 0; /* bit string is multiple of 8 */
- gen_pub_key2(rsa_ctx, buf, offset);
- adjust_with_size(seq_size, seq_offset, buf, offset);
-}
-
-static void gen_pub_key(const RSA_CTX *rsa_ctx, uint8_t *buf, int *offset)
-{
- /* OBJECT IDENTIFIER rsaEncryption (1 2 840 113549 1 1 1) */
- static const uint8_t rsa_enc_oid[] =
- {
- ASN1_SEQUENCE, 0x0d, ASN1_OID, 0x09,
- 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
- ASN1_NULL, 0x00
- };
-
- int seq_offset;
- int seq_size = pre_adjust_with_size(
- ASN1_SEQUENCE, &seq_offset, buf, offset);
-
- memcpy(&buf[*offset], rsa_enc_oid, sizeof(rsa_enc_oid));
- *offset += sizeof(rsa_enc_oid);
- gen_pub_key1(rsa_ctx, buf, offset);
- adjust_with_size(seq_size, seq_offset, buf, offset);
-}
-
-static void gen_signature(const RSA_CTX *rsa_ctx, const uint8_t *sha_dgst,
- uint8_t *buf, int *offset)
-{
- static const uint8_t asn1_sig[] =
- {
- ASN1_SEQUENCE, 0x21, ASN1_SEQUENCE, 0x09, ASN1_OID, 0x05,
- 0x2b, 0x0e, 0x03, 0x02, 0x1a, /* sha1 (1 3 14 3 2 26) */
- ASN1_NULL, 0x00, ASN1_OCTET_STRING, 0x14
- };
-
- uint8_t *enc_block = (uint8_t *)alloca(rsa_ctx->num_octets);
- uint8_t *block = (uint8_t *)alloca(sizeof(asn1_sig) + SHA1_SIZE);
- int sig_size;
-
- /* add the digest as an embedded asn.1 sequence */
- memcpy(block, asn1_sig, sizeof(asn1_sig));
- memcpy(&block[sizeof(asn1_sig)], sha_dgst, SHA1_SIZE);
-
- sig_size = RSA_encrypt(rsa_ctx, block,
- sizeof(asn1_sig) + SHA1_SIZE, enc_block, 1);
-
- buf[(*offset)++] = ASN1_BIT_STRING;
- set_gen_length(sig_size+1, buf, offset);
- buf[(*offset)++] = 0; /* bit string is multiple of 8 */
- memcpy(&buf[*offset], enc_block, sig_size);
- *offset += sig_size;
-}
-
-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);
-
- gen_serial_number(buf, offset);
- gen_signature_alg(buf, offset);
-
- /* CA certicate issuer */
- if ((ret = gen_issuer(dn, buf, offset)))
- goto error;
-
- gen_utc_time(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);
-
-error:
- return ret;
-}
-
-/**
- * Create a new certificate.
- */
-EXP_FUNC int STDCALL ssl_x509_create(SSL_CTX *ssl_ctx, uint32_t options, const char * dn[], uint8_t **cert_data)
-{
- 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);
-
- if ((ret = gen_tbs_cert(dn, ssl_ctx->rsa_ctx, buf, &offset, sha_dgst)) < 0)
- goto error;
-
- gen_signature_alg(buf, &offset);
- gen_signature(ssl_ctx->rsa_ctx, sha_dgst, buf, &offset);
- adjust_with_size(seq_size, seq_offset, buf, &offset);
- *cert_data = (uint8_t *)malloc(offset); /* create the exact memory for it */
- memcpy(*cert_data, buf, offset);
-
-error:
- return ret < 0 ? ret : offset;
-}
-
-#endif
-
diff --git a/axTLS/src/ssl/loader.c b/axTLS/src/ssl/loader.c
deleted file mode 100644
index 90231f3..0000000
--- a/axTLS/src/ssl/loader.c
+++ /dev/null
@@ -1,478 +0,0 @@
-/*
- * Copyright (c) 2007, Cameron Rich
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * * Neither the name of the axTLS project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * Load certificates/keys into memory. These can be in many different formats.
- * PEM support and other formats can be processed here.
- *
- * The PEM private keys may be optionally encrypted with AES128 or AES256.
- * The encrypted PEM keys were generated with something like:
- *
- * openssl genrsa -aes128 -passout pass:abcd -out axTLS.key_aes128.pem 512
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include "os_port.h"
-#include "ssl.h"
-
-static int do_obj(SSL_CTX *ssl_ctx, int obj_type,
- SSLObjLoader *ssl_obj, const char *password);
-#ifdef CONFIG_SSL_HAS_PEM
-static int ssl_obj_PEM_load(SSL_CTX *ssl_ctx, int obj_type,
- SSLObjLoader *ssl_obj, const char *password);
-#endif
-
-/*
- * Load a file into memory that is in binary DER (or ascii PEM) format.
- */
-EXP_FUNC int STDCALL ssl_obj_load(SSL_CTX *ssl_ctx, int obj_type,
- const char *filename, const char *password)
-{
-#ifndef CONFIG_SSL_SKELETON_MODE
- static const char * const begin = "-----BEGIN";
- int ret = SSL_OK;
- SSLObjLoader *ssl_obj = NULL;
-
- if (filename == NULL)
- {
- ret = SSL_ERROR_INVALID_KEY;
- goto error;
- }
-
- ssl_obj = (SSLObjLoader *)calloc(1, sizeof(SSLObjLoader));
- ssl_obj->len = get_file(filename, &ssl_obj->buf);
- if (ssl_obj->len <= 0)
- {
- ret = SSL_ERROR_INVALID_KEY;
- goto error;
- }
-
- /* is the file a PEM file? */
- if (strstr((char *)ssl_obj->buf, begin) != NULL)
- {
-#ifdef CONFIG_SSL_HAS_PEM
- ret = ssl_obj_PEM_load(ssl_ctx, obj_type, ssl_obj, password);
-#else
- printf(unsupported_str);
- ret = SSL_ERROR_NOT_SUPPORTED;
-#endif
- }
- else
- ret = do_obj(ssl_ctx, obj_type, ssl_obj, password);
-
-error:
- ssl_obj_free(ssl_obj);
- return ret;
-#else
- printf(unsupported_str);
- return SSL_ERROR_NOT_SUPPORTED;
-#endif /* CONFIG_SSL_SKELETON_MODE */
-}
-
-/*
- * Transfer binary data into the object loader.
- */
-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);
- ssl_obj->len = len;
- ret = do_obj(ssl_ctx, mem_type, ssl_obj, password);
- ssl_obj_free(ssl_obj);
- return ret;
-}
-
-/*
- * Actually work out what we are doing
- */
-static int do_obj(SSL_CTX *ssl_ctx, int obj_type,
- SSLObjLoader *ssl_obj, const char *password)
-{
- int ret = SSL_OK;
-
- switch (obj_type)
- {
- case SSL_OBJ_RSA_KEY:
- ret = add_private_key(ssl_ctx, ssl_obj);
- break;
-
- case SSL_OBJ_X509_CERT:
- ret = add_cert(ssl_ctx, ssl_obj->buf, ssl_obj->len);
- break;
-
-#ifdef CONFIG_SSL_CERT_VERIFICATION
- case SSL_OBJ_X509_CACERT:
- add_cert_auth(ssl_ctx, ssl_obj->buf, ssl_obj->len);
- break;
-#endif
-
-#ifdef CONFIG_SSL_USE_PKCS12
- case SSL_OBJ_PKCS8:
- ret = pkcs8_decode(ssl_ctx, ssl_obj, password);
- break;
-
- case SSL_OBJ_PKCS12:
- ret = pkcs12_decode(ssl_ctx, ssl_obj, password);
- break;
-#endif
- default:
- printf(unsupported_str);
- ret = SSL_ERROR_NOT_SUPPORTED;
- break;
- }
-
- return ret;
-}
-
-/*
- * Clean up our mess.
- */
-void ssl_obj_free(SSLObjLoader *ssl_obj)
-{
- if (ssl_obj)
- {
- free(ssl_obj->buf);
- free(ssl_obj);
- }
-}
-
-/*
- * Support for PEM encoded keys/certificates.
- */
-#ifdef CONFIG_SSL_HAS_PEM
-
-#define NUM_PEM_TYPES 4
-#define IV_SIZE 16
-#define IS_RSA_PRIVATE_KEY 0
-#define IS_ENCRYPTED_PRIVATE_KEY 1
-#define IS_PRIVATE_KEY 2
-#define IS_CERTIFICATE 3
-
-static const char * const begins[NUM_PEM_TYPES] =
-{
- "-----BEGIN RSA PRIVATE KEY-----",
- "-----BEGIN ENCRYPTED PRIVATE KEY-----",
- "-----BEGIN PRIVATE KEY-----",
- "-----BEGIN CERTIFICATE-----",
-};
-
-static const char * const ends[NUM_PEM_TYPES] =
-{
- "-----END RSA PRIVATE KEY-----",
- "-----END ENCRYPTED PRIVATE KEY-----",
- "-----END PRIVATE KEY-----",
- "-----END CERTIFICATE-----",
-};
-
-static const char * const aes_str[2] =
-{
- "DEK-Info: AES-128-CBC,",
- "DEK-Info: AES-256-CBC,"
-};
-
-/**
- * Take a base64 blob of data and decrypt it (using AES) into its
- * proper ASN.1 form.
- */
-static int pem_decrypt(const char *where, const char *end,
- const char *password, SSLObjLoader *ssl_obj)
-{
- int ret = -1;
- int is_aes_256 = 0;
- char *start = NULL;
- uint8_t iv[IV_SIZE];
- int i, pem_size;
- MD5_CTX md5_ctx;
- AES_CTX aes_ctx;
- uint8_t key[32]; /* AES256 size */
-
- if (password == NULL || strlen(password) == 0)
- {
-#ifdef CONFIG_SSL_FULL_MODE
- printf("Error: Need a password for this PEM file\n"); TTY_FLUSH();
-#endif
- goto error;
- }
-
- if ((start = strstr((const char *)where, aes_str[0]))) /* AES128? */
- {
- start += strlen(aes_str[0]);
- }
- else if ((start = strstr((const char *)where, aes_str[1]))) /* AES256? */
- {
- is_aes_256 = 1;
- start += strlen(aes_str[1]);
- }
- else
- {
-#ifdef CONFIG_SSL_FULL_MODE
- printf("Error: Unsupported password cipher\n"); TTY_FLUSH();
-#endif
- goto error;
- }
-
- /* convert from hex to binary - assumes uppercase hex */
- for (i = 0; i < IV_SIZE; i++)
- {
- char c = *start++ - '0';
- iv[i] = (c > 9 ? c + '0' - 'A' + 10 : c) << 4;
- c = *start++ - '0';
- iv[i] += (c > 9 ? c + '0' - 'A' + 10 : c);
- }
-
- while (*start == '\r' || *start == '\n')
- start++;
-
- /* turn base64 into binary */
- pem_size = (int)(end-start);
- if (base64_decode(start, pem_size, ssl_obj->buf, &ssl_obj->len) != 0)
- goto error;
-
- /* work out the key */
- MD5_Init(&md5_ctx);
- MD5_Update(&md5_ctx, (const uint8_t *)password, strlen(password));
- MD5_Update(&md5_ctx, iv, SALT_SIZE);
- MD5_Final(key, &md5_ctx);
-
- if (is_aes_256)
- {
- MD5_Init(&md5_ctx);
- MD5_Update(&md5_ctx, key, MD5_SIZE);
- MD5_Update(&md5_ctx, (const uint8_t *)password, strlen(password));
- MD5_Update(&md5_ctx, iv, SALT_SIZE);
- MD5_Final(&key[MD5_SIZE], &md5_ctx);
- }
-
- /* decrypt using the key/iv */
- AES_set_key(&aes_ctx, key, iv, is_aes_256 ? AES_MODE_256 : AES_MODE_128);
- AES_convert_key(&aes_ctx);
- AES_cbc_decrypt(&aes_ctx, ssl_obj->buf, ssl_obj->buf, ssl_obj->len);
- ret = 0;
-
-error:
- return ret;
-}
-
-/**
- * Take a base64 blob of data and turn it into its proper ASN.1 form.
- */
-static int new_pem_obj(SSL_CTX *ssl_ctx, int is_cacert, char *where,
- int remain, const char *password)
-{
- int ret = SSL_ERROR_BAD_CERTIFICATE;
- SSLObjLoader *ssl_obj = NULL;
-
- while (remain > 0)
- {
- int i, pem_size, obj_type;
- char *start = NULL, *end = NULL;
-
- for (i = 0; i < NUM_PEM_TYPES; i++)
- {
- if ((start = strstr(where, begins[i])) &&
- (end = strstr(where, ends[i])))
- {
- remain -= (int)(end-where);
- start += strlen(begins[i]);
- pem_size = (int)(end-start);
-
- ssl_obj = (SSLObjLoader *)calloc(1, sizeof(SSLObjLoader));
-
- /* 4/3 bigger than what we need but so what */
- ssl_obj->buf = (uint8_t *)calloc(1, pem_size);
-
- if (i == IS_RSA_PRIVATE_KEY &&
- strstr(start, "Proc-Type:") &&
- strstr(start, "4,ENCRYPTED"))
- {
- /* check for encrypted PEM file */
- if (pem_decrypt(start, end, password, ssl_obj) < 0)
- {
- ret = SSL_ERROR_BAD_CERTIFICATE;
- goto error;
- }
- }
- else if (base64_decode(start, pem_size,
- ssl_obj->buf, &ssl_obj->len) != 0)
- {
- ret = SSL_ERROR_BAD_CERTIFICATE;
- goto error;
- }
-
- switch (i)
- {
- case IS_RSA_PRIVATE_KEY:
- obj_type = SSL_OBJ_RSA_KEY;
- break;
-
- case IS_ENCRYPTED_PRIVATE_KEY:
- case IS_PRIVATE_KEY:
- obj_type = SSL_OBJ_PKCS8;
- break;
-
- case IS_CERTIFICATE:
- obj_type = is_cacert ?
- SSL_OBJ_X509_CACERT : SSL_OBJ_X509_CERT;
- break;
-
- default:
- ret = SSL_ERROR_BAD_CERTIFICATE;
- goto error;
- }
-
- /* In a format we can now understand - so process it */
- if ((ret = do_obj(ssl_ctx, obj_type, ssl_obj, password)))
- goto error;
-
- end += strlen(ends[i]);
- remain -= strlen(ends[i]);
- while (remain > 0 && (*end == '\r' || *end == '\n'))
- {
- end++;
- remain--;
- }
-
- where = end;
- break;
- }
- }
-
- ssl_obj_free(ssl_obj);
- ssl_obj = NULL;
- if (start == NULL)
- break;
- }
-error:
- ssl_obj_free(ssl_obj);
- return ret;
-}
-
-/*
- * Load a file into memory that is in ASCII PEM format.
- */
-static int ssl_obj_PEM_load(SSL_CTX *ssl_ctx, int obj_type,
- SSLObjLoader *ssl_obj, const char *password)
-{
- char *start;
-
- /* add a null terminator */
- ssl_obj->len++;
- ssl_obj->buf = (uint8_t *)realloc(ssl_obj->buf, ssl_obj->len);
- ssl_obj->buf[ssl_obj->len-1] = 0;
- start = (char *)ssl_obj->buf;
- return new_pem_obj(ssl_ctx, obj_type == SSL_OBJ_X509_CACERT,
- 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;
-#ifdef CONFIG_SSL_GENERATE_X509_CERT
- uint8_t *cert_data = NULL;
- int cert_size;
- static const char *dn[] =
- {
- CONFIG_SSL_X509_COMMON_NAME,
- CONFIG_SSL_X509_ORGANIZATION_NAME,
- CONFIG_SSL_X509_ORGANIZATION_UNIT_NAME
- };
-#endif
-
- /* 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
- if ((cert_size = ssl_x509_create(ssl_ctx, 0, 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;
-
-}
diff --git a/axTLS/src/ssl/openssl.c b/axTLS/src/ssl/openssl.c
deleted file mode 100644
index 6b5c4d8..0000000
--- a/axTLS/src/ssl/openssl.c
+++ /dev/null
@@ -1,323 +0,0 @@
-/*
- * Copyright (c) 2007, Cameron Rich
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * * Neither the name of the axTLS project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Enable a subset of openssl compatible functions. We don't aim to be 100%
- * compatible - just to be able to do basic ports etc.
- *
- * Only really tested on mini_httpd, so I'm not too sure how extensive this
- * port is.
- */
-
-#include "config.h"
-
-#ifdef CONFIG_OPENSSL_COMPATIBLE
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include "os_port.h"
-#include "ssl.h"
-
-#define OPENSSL_CTX_ATTR ((OPENSSL_CTX *)ssl_ctx->bonus_attr)
-
-static char *key_password = NULL;
-
-void *SSLv23_server_method(void) { return NULL; }
-void *SSLv3_server_method(void) { return NULL; }
-void *TLSv1_server_method(void) { return NULL; }
-void *SSLv23_client_method(void) { return NULL; }
-void *SSLv3_client_method(void) { return NULL; }
-void *TLSv1_client_method(void) { return NULL; }
-
-typedef void * (*ssl_func_type_t)(void);
-typedef void * (*bio_func_type_t)(void);
-
-typedef struct
-{
- ssl_func_type_t ssl_func_type;
-} OPENSSL_CTX;
-
-SSL_CTX * SSL_CTX_new(ssl_func_type_t meth)
-{
- SSL_CTX *ssl_ctx = ssl_ctx_new(0, 5);
- ssl_ctx->bonus_attr = malloc(sizeof(OPENSSL_CTX));
- OPENSSL_CTX_ATTR->ssl_func_type = meth;
- return ssl_ctx;
-}
-
-void SSL_CTX_free(SSL_CTX * ssl_ctx)
-{
- free(ssl_ctx->bonus_attr);
- ssl_ctx_free(ssl_ctx);
-}
-
-SSL * SSL_new(SSL_CTX *ssl_ctx)
-{
- SSL *ssl;
- ssl_func_type_t ssl_func_type;
-
- ssl = ssl_new(ssl_ctx, -1); /* fd is set later */
- ssl_func_type = OPENSSL_CTX_ATTR->ssl_func_type;
-
-#ifdef CONFIG_SSL_ENABLE_CLIENT
- if (ssl_func_type == SSLv23_client_method ||
- ssl_func_type == SSLv3_client_method ||
- ssl_func_type == TLSv1_client_method)
- {
- SET_SSL_FLAG(SSL_IS_CLIENT);
- }
- else
-#endif
- {
- ssl->next_state = HS_CLIENT_HELLO;
- }
-
- return ssl;
-}
-
-int SSL_set_fd(SSL *s, int fd)
-{
- s->client_fd = fd;
- return 1; /* always succeeds */
-}
-
-int SSL_accept(SSL *ssl)
-{
- while (ssl_read(ssl, NULL) == SSL_OK)
- {
- if (ssl->next_state == HS_CLIENT_HELLO)
- return 1; /* we're done */
- }
-
- return -1;
-}
-
-#ifdef CONFIG_SSL_ENABLE_CLIENT
-int SSL_connect(SSL *ssl)
-{
- return do_client_connect(ssl) == SSL_OK ? 1 : -1;
-}
-#endif
-
-void SSL_free(SSL *ssl)
-{
- ssl_free(ssl);
-}
-
-int SSL_read(SSL *ssl, void *buf, int num)
-{
- uint8_t *read_buf;
- int ret;
-
- while ((ret = ssl_read(ssl, &read_buf)) == SSL_OK);
-
- if (ret > SSL_OK)
- {
- memcpy(buf, read_buf, ret > num ? num : ret);
- }
-
- return ret;
-}
-
-int SSL_write(SSL *ssl, const void *buf, int num)
-{
- return ssl_write(ssl, buf, num);
-}
-
-int SSL_CTX_use_certificate_file(SSL_CTX *ssl_ctx, const char *file, int type)
-{
- return (ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CERT, file, NULL) == SSL_OK);
-}
-
-int SSL_CTX_use_PrivateKey_file(SSL_CTX *ssl_ctx, const char *file, int type)
-{
- return (ssl_obj_load(ssl_ctx, SSL_OBJ_RSA_KEY, file, key_password) == SSL_OK);
-}
-
-int SSL_CTX_use_certificate_ASN1(SSL_CTX *ssl_ctx, int len, const uint8_t *d)
-{
- return (ssl_obj_memory_load(ssl_ctx,
- SSL_OBJ_X509_CERT, d, len, NULL) == SSL_OK);
-}
-
-int SSL_CTX_set_session_id_context(SSL_CTX *ctx, const unsigned char *sid_ctx,
- unsigned int sid_ctx_len)
-{
- return 1;
-}
-
-int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx)
-{
- return 1;
-}
-
-int SSL_CTX_use_certificate_chain_file(SSL_CTX *ssl_ctx, const char *file)
-{
- return (ssl_obj_load(ssl_ctx,
- SSL_OBJ_X509_CERT, file, NULL) == SSL_OK);
-}
-
-int SSL_shutdown(SSL *ssl)
-{
- return 1;
-}
-
-/*** get/set session ***/
-SSL_SESSION *SSL_get1_session(SSL *ssl)
-{
- return (SSL_SESSION *)ssl_get_session_id(ssl); /* note: wrong cast */
-}
-
-int SSL_set_session(SSL *ssl, SSL_SESSION *session)
-{
- memcpy(ssl->session_id, (uint8_t *)session, SSL_SESSION_ID_SIZE);
- return 1;
-}
-
-void SSL_SESSION_free(SSL_SESSION *session) { }
-/*** end get/set session ***/
-
-long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
-{
- return 0;
-}
-
-void SSL_CTX_set_verify(SSL_CTX *ctx, int mode,
- int (*verify_callback)(int, void *)) { }
-
-void SSL_CTX_set_verify_depth(SSL_CTX *ctx,int depth) { }
-
-int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile,
- const char *CApath)
-{
- return 1;
-}
-
-void *SSL_load_client_CA_file(const char *file)
-{
- return (void *)file;
-}
-
-void SSL_CTX_set_client_CA_list(SSL_CTX *ssl_ctx, void *file)
-{
-
- ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CERT, (const char *)file, NULL);
-}
-
-void SSLv23_method(void) { }
-
-void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, void *cb) { }
-
-void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u)
-{
- key_password = (char *)u;
-}
-
-int SSL_peek(SSL *ssl, void *buf, int num)
-{
- memcpy(buf, ssl->bm_data, num);
- return num;
-}
-
-void SSL_set_bio(SSL *ssl, void *rbio, void *wbio) { }
-
-long SSL_get_verify_result(const SSL *ssl)
-{
- return ssl_handshake_status(ssl);
-}
-
-int SSL_state(SSL *ssl)
-{
- return 0x03; // ok state
-}
-
-/** end of could do better list */
-
-void *SSL_get_peer_certificate(const SSL *ssl)
-{
- return &ssl->ssl_ctx->certs[0];
-}
-
-int SSL_clear(SSL *ssl)
-{
- return 1;
-}
-
-
-int SSL_CTX_check_private_key(const SSL_CTX *ctx)
-{
- return 1;
-}
-
-int SSL_CTX_set_cipher_list(SSL *s, const char *str)
-{
- return 1;
-}
-
-int SSL_get_error(const SSL *ssl, int ret)
-{
- ssl_display_error(ret);
- return 0; /* TODO: return proper return code */
-}
-
-void SSL_CTX_set_options(SSL_CTX *ssl_ctx, int option) {}
-int SSL_library_init(void ) { return 1; }
-void SSL_load_error_strings(void ) {}
-void ERR_print_errors_fp(FILE *fp) {}
-
-#ifndef CONFIG_SSL_SKELETON_MODE
-long SSL_CTX_get_timeout(const SSL_CTX *ssl_ctx) {
- return CONFIG_SSL_EXPIRY_TIME*3600; }
-long SSL_CTX_set_timeout(SSL_CTX *ssl_ctx, long t) {
- return SSL_CTX_get_timeout(ssl_ctx); }
-#endif
-void BIO_printf(FILE *f, const char *format, ...)
-{
- va_list(ap);
- va_start(ap, format);
- vfprintf(f, format, ap);
- va_end(ap);
-}
-
-void* BIO_s_null(void) { return NULL; }
-FILE *BIO_new(bio_func_type_t func)
-{
- if (func == BIO_s_null)
- return fopen("/dev/null", "r");
- else
- return NULL;
-}
-
-FILE *BIO_new_fp(FILE *stream, int close_flag) { return stream; }
-int BIO_free(FILE *a) { if (a != stdout && a != stderr) fclose(a); return 1; }
-
-
-
-#endif
diff --git a/axTLS/src/ssl/os_port.c b/axTLS/src/ssl/os_port.c
deleted file mode 100644
index 9859d08..0000000
--- a/axTLS/src/ssl/os_port.c
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (c) 2007, Cameron Rich
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * * Neither the name of the axTLS project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @file os_port.c
- *
- * OS specific functions.
- */
-#include <time.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <stdarg.h>
-#include "os_port.h"
-
-#ifdef _MSC_VER
-/**
- * gettimeofday() not in Win32
- */
-EXP_FUNC void STDCALL gettimeofday(struct timeval* t, void* timezone)
-{
-#if defined(_WIN32_WCE)
- t->tv_sec = time(NULL);
- t->tv_usec = 0; /* 1sec precision only */
-#else
- struct _timeb timebuffer;
- _ftime(&timebuffer);
- t->tv_sec = (long)timebuffer.time;
- t->tv_usec = 1000 * timebuffer.millitm; /* 1ms precision */
-#endif
-}
-
-/**
- * strcasecmp() not in Win32
- */
-EXP_FUNC int STDCALL strcasecmp(const char *s1, const char *s2)
-{
- while (tolower(*s1) == tolower(*s2++))
- {
- if (*s1++ == '\0')
- {
- return 0;
- }
- }
-
- return *(unsigned char *)s1 - *(unsigned char *)(s2 - 1);
-}
-
-
-EXP_FUNC int STDCALL getdomainname(char *buf, int buf_size)
-{
- HKEY hKey;
- unsigned long datatype;
- unsigned long bufferlength = buf_size;
-
- if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
- TEXT("SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters"),
- 0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS)
- return -1;
-
- RegQueryValueEx(hKey, "Domain", NULL, &datatype, buf, &bufferlength);
- RegCloseKey(hKey);
- return 0;
-}
-#endif
-
-#undef malloc
-#undef realloc
-#undef calloc
-
-static const char * out_of_mem_str = "out of memory";
-static const char * file_open_str = "Could not open file \"%s\"";
-
-/*
- * Some functions that call display some error trace and then call abort().
- * This just makes life much easier on embedded systems, since we're
- * suffering major trauma...
- */
-EXP_FUNC void * STDCALL ax_malloc(size_t s)
-{
- void *x;
-
- if ((x = malloc(s)) == NULL)
- exit_now(out_of_mem_str);
-
- return x;
-}
-
-EXP_FUNC void * STDCALL ax_realloc(void *y, size_t s)
-{
- void *x;
-
- if ((x = realloc(y, s)) == NULL)
- exit_now(out_of_mem_str);
-
- return x;
-}
-
-EXP_FUNC void * STDCALL ax_calloc(size_t n, size_t s)
-{
- void *x;
-
- if ((x = calloc(n, s)) == NULL)
- exit_now(out_of_mem_str);
-
- return x;
-}
-
-EXP_FUNC int STDCALL ax_open(const char *pathname, int flags)
-{
- int x;
-
- if ((x = open(pathname, flags)) < 0)
- exit_now(file_open_str, pathname);
-
- return x;
-}
-
-/**
- * This is a call which will deliberately exit an application, but will
- * display some information before dying.
- */
-void exit_now(const char *format, ...)
-{
- va_list argp;
-
- va_start(argp, format);
- vfprintf(stderr, format, argp);
- va_end(argp);
- abort();
-}
-
diff --git a/axTLS/src/ssl/os_port.h b/axTLS/src/ssl/os_port.h
deleted file mode 100644
index b2924b4..0000000
--- a/axTLS/src/ssl/os_port.h
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Copyright (c) 2007, Cameron Rich
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * * Neither the name of the axTLS project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @file os_port.h
- *
- * Some stuff to minimise the differences between windows and linux/unix
- */
-
-#ifndef HEADER_OS_PORT_H
-#define HEADER_OS_PORT_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stdio.h>
-
-//#if defined(WIN32)
-//#define STDCALL __stdcall
-//#define EXP_FUNC __declspec(dllexport)
-//#else
-#define STDCALL
-#define EXP_FUNC
-//#endif
-
-#if defined(_WIN32_WCE)
-#undef WIN32
-#define WIN32
-#endif
-
-#ifdef WIN32
-
-/* Windows CE stuff */
-#if defined(_WIN32_WCE)
-#include <basetsd.h>
-#define abort() exit(1)
-#else
-#include <io.h>
-#include <process.h>
-#include <sys/timeb.h>
-#include <fcntl.h>
-#endif /* _WIN32_WCE */
-
-#include <winsock.h>
-#include <direct.h>
-#undef getpid
-#undef open
-#undef close
-#undef sleep
-#undef gettimeofday
-#undef dup2
-#undef unlink
-
-#define SOCKET_READ(A,B,C) recv(A,B,C,0)
-#define SOCKET_WRITE(A,B,C) send(A,B,C,0)
-#define SOCKET_CLOSE(A) closesocket(A)
-#define srandom(A) srand(A)
-#define random() rand()
-#define getpid() _getpid()
-#define snprintf _snprintf
-#define open(A,B) _open(A,B)
-#define dup2(A,B) _dup2(A,B)
-#define unlink(A) _unlink(A)
-#define close(A) _close(A)
-#define read(A,B,C) _read(A,B,C)
-#define write(A,B,C) _write(A,B,C)
-#define sleep(A) Sleep(A*1000)
-#define usleep(A) Sleep(A/1000)
-#define strdup(A) _strdup(A)
-#define chroot(A) _chdir(A)
-#define chdir(A) _chdir(A)
-#define alloca(A) _alloca(A)
-#ifndef lseek
-#define lseek(A,B,C) _lseek(A,B,C)
-#endif
-
-/* This fix gets around a problem where a win32 application on a cygwin xterm
- doesn't display regular output (until a certain buffer limit) - but it works
- fine under a normal DOS window. This is a hack to get around the issue -
- see http://www.khngai.com/emacs/tty.php */
-#define TTY_FLUSH() if (!_isatty(_fileno(stdout))) fflush(stdout);
-
-/*
- * automatically build some library dependencies.
- */
-#ifdef _MSC_VER
-#pragma comment(lib, "WS2_32.lib")
-#pragma comment(lib, "AdvAPI32.lib")
-
-typedef UINT8 uint8_t;
-typedef INT8 int8_t;
-typedef UINT16 uint16_t;
-typedef INT16 int16_t;
-typedef UINT32 uint32_t;
-typedef INT32 int32_t;
-typedef UINT64 uint64_t;
-typedef INT64 int64_t;
-typedef int socklen_t;
-
-EXP_FUNC void STDCALL gettimeofday(struct timeval* t,void* timezone);
-EXP_FUNC int STDCALL strcasecmp(const char *s1, const char *s2);
-EXP_FUNC int STDCALL getdomainname(char *buf, int buf_size);
-#else
-#include <stdint.h>
-#endif
-
-#else /* Not Win32 */
-
-#ifdef CONFIG_PLATFORM_SOLARIS
-#include <inttypes.h>
-#else
-#include <stdint.h>
-#endif /* Not Solaris */
-
-#include <unistd.h>
-#include <pwd.h>
-#include <netdb.h>
-#include <dirent.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/socket.h>
-#include <sys/wait.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#define SOCKET_READ(A,B,C) read(A,B,C)
-#define SOCKET_WRITE(A,B,C) write(A,B,C)
-#define SOCKET_CLOSE(A) if (A >= 0) close(A)
-#define TTY_FLUSH()
-
-#endif /* Not Win32 */
-
-/* some functions to mutate the way these work */
-#define malloc(A) ax_malloc(A)
-#ifndef realloc
-#define realloc(A,B) ax_realloc(A,B)
-#endif
-#define calloc(A,B) ax_calloc(A,B)
-
-EXP_FUNC void * STDCALL ax_malloc(size_t s);
-EXP_FUNC void * STDCALL ax_realloc(void *y, size_t s);
-EXP_FUNC void * STDCALL ax_calloc(size_t n, size_t s);
-EXP_FUNC int STDCALL ax_open(const char *pathname, int flags);
-
-#ifdef CONFIG_PLATFORM_LINUX
-void exit_now(const char *format, ...) __attribute((noreturn));
-#else
-void exit_now(const char *format, ...);
-#endif
-
-/* Mutexing definitions */
-#if defined(CONFIG_SSL_CTX_MUTEXING)
-#if defined(WIN32)
-#define SSL_CTX_MUTEX_TYPE HANDLE
-#define SSL_CTX_MUTEX_INIT(A) A=CreateMutex(0, FALSE, 0)
-#define SSL_CTX_MUTEX_DESTROY(A) CloseHandle(A)
-#define SSL_CTX_LOCK(A) WaitForSingleObject(A, INFINITE)
-#define SSL_CTX_UNLOCK(A) ReleaseMutex(A)
-#else
-#include <pthread.h>
-#define SSL_CTX_MUTEX_TYPE pthread_mutex_t
-#define SSL_CTX_MUTEX_INIT(A) pthread_mutex_init(&A, NULL)
-#define SSL_CTX_MUTEX_DESTROY(A) pthread_mutex_destroy(&A)
-#define SSL_CTX_LOCK(A) pthread_mutex_lock(&A)
-#define SSL_CTX_UNLOCK(A) pthread_mutex_unlock(&A)
-#endif
-#else /* no mutexing */
-#define SSL_CTX_MUTEX_INIT(A)
-#define SSL_CTX_MUTEX_DESTROY(A)
-#define SSL_CTX_LOCK(A)
-#define SSL_CTX_UNLOCK(A)
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/axTLS/src/ssl/p12.c b/axTLS/src/ssl/p12.c
deleted file mode 100644
index 2bafaf7..0000000
--- a/axTLS/src/ssl/p12.c
+++ /dev/null
@@ -1,483 +0,0 @@
-/*
- * Copyright (c) 2007, Cameron Rich
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * * Neither the name of the axTLS project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * Process PKCS#8/PKCS#12 keys.
- *
- * The decoding of a PKCS#12 key is fairly specific - this code was tested on a
- * key generated with:
- *
- * openssl pkcs12 -export -in axTLS.x509_1024.pem -inkey axTLS.key_1024.pem
- * -keypbe PBE-SHA1-RC4-128 -certpbe PBE-SHA1-RC4-128
- * -name "p12_withoutCA" -out axTLS.withoutCA.p12 -password pass:abcd
- *
- * or with a certificate chain:
- *
- * openssl pkcs12 -export -in axTLS.x509_1024.pem -inkey axTLS.key_1024.pem
- * -certfile axTLS.ca_x509.pem -keypbe PBE-SHA1-RC4-128 -certpbe
- * PBE-SHA1-RC4-128 -name "p12_withCA" -out axTLS.withCA.p12 -password pass:abcd
- *
- * Note that the PBE has to be specified with PBE-SHA1-RC4-128. The
- * private/public keys/certs have to use RSA encryption. Both the integrity
- * and privacy passwords are the same.
- *
- * The PKCS#8 files were generated with something like:
- *
- * PEM format:
- * openssl pkcs8 -in axTLS.key_512.pem -passout pass:abcd -topk8 -v1
- * PBE-SHA1-RC4-128 -out axTLS.encrypted_pem.p8
- *
- * DER format:
- * openssl pkcs8 -in axTLS.key_512.pem -passout pass:abcd -topk8 -outform DER
- * -v1 PBE-SHA1-RC4-128 -out axTLS.encrypted.p8
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include "os_port.h"
-#include "ssl.h"
-
-/* all commented out if not used */
-#ifdef CONFIG_SSL_USE_PKCS12
-
-#define BLOCK_SIZE 64
-#define PKCS12_KEY_ID 1
-#define PKCS12_IV_ID 2
-#define PKCS12_MAC_ID 3
-
-static char *make_uni_pass(const char *password, int *uni_pass_len);
-static int p8_decrypt(const char *uni_pass, int uni_pass_len,
- const uint8_t *salt, int iter,
- uint8_t *priv_key, int priv_key_len, int id);
-static int p8_add_key(SSL_CTX *ssl_ctx, uint8_t *priv_key);
-static int get_pbe_params(uint8_t *buf, int *offset,
- const uint8_t **salt, int *iterations);
-
-/*
- * Take a raw pkcs8 block and then decrypt it and turn it into a normal key.
- */
-int pkcs8_decode(SSL_CTX *ssl_ctx, SSLObjLoader *ssl_obj, const char *password)
-{
- uint8_t *buf = ssl_obj->buf;
- int len, offset = 0;
- int iterations;
- int ret = SSL_NOT_OK;
- uint8_t *version = NULL;
- const uint8_t *salt;
- uint8_t *priv_key;
- int uni_pass_len;
- char *uni_pass = make_uni_pass(password, &uni_pass_len);
-
- if (asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0)
- {
-#ifdef CONFIG_SSL_FULL_MODE
- printf("Error: Invalid p8 ASN.1 file\n");
-#endif
- goto error;
- }
-
- /* unencrypted key? */
- if (asn1_get_int(buf, &offset, &version) > 0 && *version == 0)
- {
- ret = p8_add_key(ssl_ctx, buf);
- goto error;
- }
-
- if (get_pbe_params(buf, &offset, &salt, &iterations) < 0)
- goto error;
-
- if ((len = asn1_next_obj(buf, &offset, ASN1_OCTET_STRING)) < 0)
- goto error;
-
- priv_key = &buf[offset];
-
- p8_decrypt(uni_pass, uni_pass_len, salt,
- iterations, priv_key, len, PKCS12_KEY_ID);
- ret = p8_add_key(ssl_ctx, priv_key);
-
-error:
- free(version);
- free(uni_pass);
- return ret;
-}
-
-/*
- * Take the unencrypted pkcs8 and turn it into a private key
- */
-static int p8_add_key(SSL_CTX *ssl_ctx, uint8_t *priv_key)
-{
- uint8_t *buf = priv_key;
- int len, offset = 0;
- int ret = SSL_NOT_OK;
-
- /* Skip the preamble and go straight to the private key.
- We only support rsaEncryption (1.2.840.113549.1.1.1) */
- if (asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
- asn1_skip_obj(buf, &offset, ASN1_INTEGER) < 0 ||
- asn1_skip_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
- (len = asn1_next_obj(buf, &offset, ASN1_OCTET_STRING)) < 0)
- goto error;
-
- ret = asn1_get_private_key(&buf[offset], len, &ssl_ctx->rsa_ctx);
-
-error:
- return ret;
-}
-
-/*
- * Create the unicode password
- */
-static char *make_uni_pass(const char *password, int *uni_pass_len)
-{
- int pass_len = 0, i;
- char *uni_pass;
-
- if (password == NULL)
- {
- password = "";
- }
-
- uni_pass = (char *)malloc((strlen(password)+1)*2);
-
- /* modify the password into a unicode version */
- for (i = 0; i < (int)strlen(password); i++)
- {
- uni_pass[pass_len++] = 0;
- uni_pass[pass_len++] = password[i];
- }
-
- uni_pass[pass_len++] = 0; /* null terminate */
- uni_pass[pass_len++] = 0;
- *uni_pass_len = pass_len;
- return uni_pass;
-}
-
-/*
- * Decrypt a pkcs8 block.
- */
-static int p8_decrypt(const char *uni_pass, int uni_pass_len,
- const uint8_t *salt, int iter,
- uint8_t *priv_key, int priv_key_len, int id)
-{
- uint8_t p[BLOCK_SIZE*2];
- uint8_t d[BLOCK_SIZE];
- uint8_t Ai[SHA1_SIZE];
- SHA1_CTX sha_ctx;
- RC4_CTX rc4_ctx;
- int i;
-
- for (i = 0; i < BLOCK_SIZE; i++)
- {
- p[i] = salt[i % SALT_SIZE];
- p[BLOCK_SIZE+i] = uni_pass[i % uni_pass_len];
- d[i] = id;
- }
-
- /* get the key - no IV since we are using RC4 */
- SHA1_Init(&sha_ctx);
- SHA1_Update(&sha_ctx, d, sizeof(d));
- SHA1_Update(&sha_ctx, p, sizeof(p));
- SHA1_Final(Ai, &sha_ctx);
-
- for (i = 1; i < iter; i++)
- {
- SHA1_Init(&sha_ctx);
- SHA1_Update(&sha_ctx, Ai, SHA1_SIZE);
- SHA1_Final(Ai, &sha_ctx);
- }
-
- /* do the decryption */
- if (id == PKCS12_KEY_ID)
- {
- RC4_setup(&rc4_ctx, Ai, 16);
- RC4_crypt(&rc4_ctx, priv_key, priv_key, priv_key_len);
- }
- else /* MAC */
- memcpy(priv_key, Ai, SHA1_SIZE);
-
- return 0;
-}
-
-/*
- * Take a raw pkcs12 block and the decrypt it and turn it into a certificate(s)
- * and keys.
- */
-int pkcs12_decode(SSL_CTX *ssl_ctx, SSLObjLoader *ssl_obj, const char *password)
-{
- uint8_t *buf = ssl_obj->buf;
- int len, iterations, auth_safes_start,
- auth_safes_end, auth_safes_len, key_offset, offset = 0;
- int all_certs = 0;
- uint8_t *version = NULL, *auth_safes = NULL, *cert, *orig_mac;
- uint8_t key[SHA1_SIZE];
- uint8_t mac[SHA1_SIZE];
- const uint8_t *salt;
- int uni_pass_len, ret = SSL_OK;
- char *uni_pass = make_uni_pass(password, &uni_pass_len);
- static const uint8_t pkcs_data[] = /* pkc7 data */
- { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01 };
- static const uint8_t pkcs_encrypted[] = /* pkc7 encrypted */
- { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x06 };
- static const uint8_t pkcs8_key_bag[] = /* 1.2.840.113549.1.12.10.1.2 */
- { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x0a, 0x01, 0x02 };
-
- if (asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0)
- {
-#ifdef CONFIG_SSL_FULL_MODE
- printf("Error: Invalid p12 ASN.1 file\n");
-#endif
- goto error;
- }
-
- if (asn1_get_int(buf, &offset, &version) < 0 || *version != 3)
- {
- ret = SSL_ERROR_INVALID_VERSION;
- goto error;
- }
-
- /* remove all the boring pcks7 bits */
- if (asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
- (len = asn1_next_obj(buf, &offset, ASN1_OID)) < 0 ||
- len != sizeof(pkcs_data) ||
- memcmp(&buf[offset], pkcs_data, sizeof(pkcs_data)))
- goto error;
-
- offset += len;
-
- if (asn1_next_obj(buf, &offset, ASN1_EXPLICIT_TAG) < 0 ||
- asn1_next_obj(buf, &offset, ASN1_OCTET_STRING) < 0)
- goto error;
-
- /* work out the MAC start/end points (done on AuthSafes) */
- auth_safes_start = offset;
- auth_safes_end = offset;
- if (asn1_skip_obj(buf, &auth_safes_end, ASN1_SEQUENCE) < 0)
- goto error;
-
- auth_safes_len = auth_safes_end - auth_safes_start;
- auth_safes = malloc(auth_safes_len);
-
- memcpy(auth_safes, &buf[auth_safes_start], auth_safes_len);
-
- if (asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
- asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
- (len = asn1_next_obj(buf, &offset, ASN1_OID)) < 0 ||
- (len != sizeof(pkcs_encrypted) ||
- memcmp(&buf[offset], pkcs_encrypted, sizeof(pkcs_encrypted))))
- goto error;
-
- offset += len;
-
- if (asn1_next_obj(buf, &offset, ASN1_EXPLICIT_TAG) < 0 ||
- asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
- asn1_skip_obj(buf, &offset, ASN1_INTEGER) < 0 ||
- asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
- (len = asn1_next_obj(buf, &offset, ASN1_OID)) < 0 ||
- len != sizeof(pkcs_data) ||
- memcmp(&buf[offset], pkcs_data, sizeof(pkcs_data)))
- goto error;
-
- offset += len;
-
- /* work out the salt for the certificate */
- if (get_pbe_params(buf, &offset, &salt, &iterations) < 0 ||
- (len = asn1_next_obj(buf, &offset, ASN1_IMPLICIT_TAG)) < 0)
- goto error;
-
- /* decrypt the certificate */
- cert = &buf[offset];
- if ((ret = p8_decrypt(uni_pass, uni_pass_len, salt, iterations, cert,
- len, PKCS12_KEY_ID)) < 0)
- goto error;
-
- offset += len;
-
- /* load the certificate */
- key_offset = 0;
- all_certs = asn1_next_obj(cert, &key_offset, ASN1_SEQUENCE);
-
- /* keep going until all certs are loaded */
- while (key_offset < all_certs)
- {
- int cert_offset = key_offset;
-
- if (asn1_skip_obj(cert, &cert_offset, ASN1_SEQUENCE) < 0 ||
- asn1_next_obj(cert, &key_offset, ASN1_SEQUENCE) < 0 ||
- asn1_skip_obj(cert, &key_offset, ASN1_OID) < 0 ||
- asn1_next_obj(cert, &key_offset, ASN1_EXPLICIT_TAG) < 0 ||
- asn1_next_obj(cert, &key_offset, ASN1_SEQUENCE) < 0 ||
- asn1_skip_obj(cert, &key_offset, ASN1_OID) < 0 ||
- asn1_next_obj(cert, &key_offset, ASN1_EXPLICIT_TAG) < 0 ||
- (len = asn1_next_obj(cert, &key_offset, ASN1_OCTET_STRING)) < 0)
- goto error;
-
- if ((ret = add_cert(ssl_ctx, &cert[key_offset], len)) < 0)
- goto error;
-
- key_offset = cert_offset;
- }
-
- if (asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
- (len = asn1_next_obj(buf, &offset, ASN1_OID)) < 0 ||
- len != sizeof(pkcs_data) ||
- memcmp(&buf[offset], pkcs_data, sizeof(pkcs_data)))
- goto error;
-
- offset += len;
-
- if (asn1_next_obj(buf, &offset, ASN1_EXPLICIT_TAG) < 0 ||
- asn1_next_obj(buf, &offset, ASN1_OCTET_STRING) < 0 ||
- asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
- asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
- (len = asn1_next_obj(buf, &offset, ASN1_OID)) < 0 ||
- (len != sizeof(pkcs8_key_bag)) ||
- memcmp(&buf[offset], pkcs8_key_bag, sizeof(pkcs8_key_bag)))
- goto error;
-
- offset += len;
-
- /* work out the salt for the private key */
- if (asn1_next_obj(buf, &offset, ASN1_EXPLICIT_TAG) < 0 ||
- asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
- get_pbe_params(buf, &offset, &salt, &iterations) < 0 ||
- (len = asn1_next_obj(buf, &offset, ASN1_OCTET_STRING)) < 0)
- goto error;
-
- /* decrypt the private key */
- cert = &buf[offset];
- if ((ret = p8_decrypt(uni_pass, uni_pass_len, salt, iterations, cert,
- len, PKCS12_KEY_ID)) < 0)
- goto error;
-
- offset += len;
-
- /* load the private key */
- if ((ret = p8_add_key(ssl_ctx, cert)) < 0)
- goto error;
-
- /* miss out on friendly name, local key id etc */
- if (asn1_skip_obj(buf, &offset, ASN1_SET) < 0)
- goto error;
-
- /* work out the MAC */
- if (asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
- asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
- asn1_skip_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
- (len = asn1_next_obj(buf, &offset, ASN1_OCTET_STRING)) < 0 ||
- len != SHA1_SIZE)
- goto error;
-
- orig_mac = &buf[offset];
- offset += len;
-
- /* get the salt */
- if ((len = asn1_next_obj(buf, &offset, ASN1_OCTET_STRING)) < 0 || len != 8)
- goto error;
-
- salt = &buf[offset];
-
- /* work out what the mac should be */
- if ((ret = p8_decrypt(uni_pass, uni_pass_len, salt, iterations,
- key, SHA1_SIZE, PKCS12_MAC_ID)) < 0)
- goto error;
-
- hmac_sha1(auth_safes, auth_safes_len, key, SHA1_SIZE, mac);
-
- if (memcmp(mac, orig_mac, SHA1_SIZE))
- {
- ret = SSL_ERROR_INVALID_HMAC;
- goto error;
- }
-
-error:
- free(version);
- free(uni_pass);
- free(auth_safes);
- return ret;
-}
-
-/*
- * Retrieve the salt/iteration details from a PBE block.
- */
-static int get_pbe_params(uint8_t *buf, int *offset,
- const uint8_t **salt, int *iterations)
-{
- static const uint8_t pbeSH1RC4[] = /* pbeWithSHAAnd128BitRC4 */
- { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x01 };
-
- int i, len;
- uint8_t *iter = NULL;
- int error_code = SSL_ERROR_NOT_SUPPORTED;
-
- /* Get the PBE type */
- if (asn1_next_obj(buf, offset, ASN1_SEQUENCE) < 0 ||
- (len = asn1_next_obj(buf, offset, ASN1_OID)) < 0)
- goto error;
-
- /* we expect pbeWithSHAAnd128BitRC4 (1.2.840.113549.1.12.1.1)
- which is the only algorithm we support */
- if (len != sizeof(pbeSH1RC4) ||
- memcmp(&buf[*offset], pbeSH1RC4, sizeof(pbeSH1RC4)))
- {
-#ifdef CONFIG_SSL_FULL_MODE
- printf("Error: pkcs8/pkcs12 must use \"PBE-SHA1-RC4-128\"\n");
-#endif
- goto error;
- }
-
- *offset += len;
-
- if (asn1_next_obj(buf, offset, ASN1_SEQUENCE) < 0 ||
- (len = asn1_next_obj(buf, offset, ASN1_OCTET_STRING)) < 0 ||
- len != 8)
- goto error;
-
- *salt = &buf[*offset];
- *offset += len;
-
- if ((len = asn1_get_int(buf, offset, &iter)) < 0)
- goto error;
-
- *iterations = 0;
- for (i = 0; i < len; i++)
- {
- (*iterations) <<= 8;
- (*iterations) += iter[i];
- }
-
- free(iter);
- error_code = SSL_OK; /* got here - we are ok */
-
-error:
- return error_code;
-}
-
-#endif
diff --git a/axTLS/src/ssl/private_key.h b/axTLS/src/ssl/private_key.h
deleted file mode 100644
index ce7985c..0000000
--- a/axTLS/src/ssl/private_key.h
+++ /dev/null
@@ -1,54 +0,0 @@
-unsigned char default_private_key[] = {
- 0x30, 0x82, 0x02, 0x5d, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xcd,
- 0xfd, 0x89, 0x48, 0xbe, 0x36, 0xb9, 0x95, 0x76, 0xd4, 0x13, 0x30, 0x0e,
- 0xbf, 0xb2, 0xed, 0x67, 0x0a, 0xc0, 0x16, 0x3f, 0x51, 0x09, 0x9d, 0x29,
- 0x2f, 0xb2, 0x6d, 0x3f, 0x3e, 0x6c, 0x2f, 0x90, 0x80, 0xa1, 0x71, 0xdf,
- 0xbe, 0x38, 0xc5, 0xcb, 0xa9, 0x9a, 0x40, 0x14, 0x90, 0x0a, 0xf9, 0xb7,
- 0x07, 0x0b, 0xe1, 0xda, 0xe7, 0x09, 0xbf, 0x0d, 0x57, 0x41, 0x86, 0x60,
- 0xa1, 0xc1, 0x27, 0x91, 0x5b, 0x0a, 0x98, 0x46, 0x1b, 0xf6, 0xa2, 0x84,
- 0xf8, 0x65, 0xc7, 0xce, 0x2d, 0x96, 0x17, 0xaa, 0x91, 0xf8, 0x61, 0x04,
- 0x50, 0x70, 0xeb, 0xb4, 0x43, 0xb7, 0xdc, 0x9a, 0xcc, 0x31, 0x01, 0x14,
- 0xd4, 0xcd, 0xcc, 0xc2, 0x37, 0x6d, 0x69, 0x82, 0xd6, 0xc6, 0xc4, 0xbe,
- 0xf2, 0x34, 0xa5, 0xc9, 0xa6, 0x19, 0x53, 0x32, 0x7a, 0x86, 0x0e, 0x91,
- 0x82, 0x0f, 0xa1, 0x42, 0x54, 0xaa, 0x01, 0x02, 0x03, 0x01, 0x00, 0x01,
- 0x02, 0x81, 0x81, 0x00, 0x95, 0xaa, 0x6e, 0x11, 0xf5, 0x6a, 0x8b, 0xa2,
- 0xc6, 0x48, 0xc6, 0x7c, 0x37, 0x6b, 0x1f, 0x55, 0x10, 0x76, 0x26, 0x24,
- 0xc3, 0xf2, 0x5c, 0x5a, 0xdd, 0x2e, 0xf3, 0xa4, 0x1e, 0xbc, 0x7b, 0x1c,
- 0x80, 0x10, 0x85, 0xbc, 0xd8, 0x45, 0x3c, 0xb8, 0xb2, 0x06, 0x53, 0xb5,
- 0xd5, 0x7a, 0xe7, 0x0e, 0x92, 0xe6, 0x42, 0xc2, 0xe2, 0x2a, 0xd5, 0xd1,
- 0x03, 0x9f, 0x6f, 0x53, 0x74, 0x68, 0x72, 0x8e, 0xbf, 0x03, 0xbb, 0xab,
- 0xbd, 0xa1, 0xf9, 0x81, 0x7d, 0x12, 0xd4, 0x9d, 0xb6, 0xae, 0x4c, 0xad,
- 0xca, 0xa8, 0xc9, 0x80, 0x8d, 0x0d, 0xd5, 0xd0, 0xa1, 0xbf, 0xec, 0x60,
- 0x48, 0x49, 0xed, 0x97, 0x0f, 0x5e, 0xed, 0xfc, 0x39, 0x15, 0x96, 0x9e,
- 0x5d, 0xe2, 0xb4, 0x5d, 0x2e, 0x04, 0xdc, 0x08, 0xa2, 0x65, 0x29, 0x2d,
- 0x37, 0xfb, 0x62, 0x90, 0x1b, 0x7b, 0xe5, 0x3a, 0x58, 0x05, 0x55, 0xc1,
- 0x02, 0x41, 0x00, 0xfc, 0x69, 0x28, 0xc9, 0xa8, 0xc4, 0x5c, 0xe3, 0xd0,
- 0x5e, 0xaa, 0xda, 0xde, 0x87, 0x74, 0xdb, 0xcb, 0x40, 0x78, 0x8e, 0x1d,
- 0x12, 0x96, 0x16, 0x61, 0x3f, 0xb3, 0x3e, 0xa3, 0x0d, 0xdc, 0x49, 0xa5,
- 0x25, 0x87, 0xc5, 0x97, 0x85, 0x9d, 0xbb, 0xb4, 0xf0, 0x44, 0xfd, 0x6c,
- 0xe8, 0xd2, 0x8c, 0xec, 0x33, 0x81, 0x46, 0x1e, 0x10, 0x12, 0x33, 0x16,
- 0x95, 0x00, 0x4f, 0x75, 0xb4, 0xe5, 0x79, 0x02, 0x41, 0x00, 0xd0, 0xeb,
- 0x65, 0x07, 0x10, 0x3b, 0xd9, 0x03, 0xeb, 0xdc, 0x6f, 0x4b, 0x8f, 0xc3,
- 0x87, 0xce, 0x76, 0xd6, 0xc5, 0x14, 0x21, 0x4e, 0xe7, 0x4f, 0x1b, 0xe8,
- 0x05, 0xf8, 0x84, 0x1a, 0xe0, 0xc5, 0xd6, 0xe3, 0x08, 0xb3, 0x54, 0x57,
- 0x02, 0x1f, 0xd4, 0xd9, 0xfb, 0xff, 0x40, 0xb1, 0x56, 0x1c, 0x60, 0xf7,
- 0xac, 0x91, 0xf3, 0xd3, 0xc6, 0x7f, 0x84, 0xfd, 0x84, 0x9d, 0xea, 0x26,
- 0xee, 0xc9, 0x02, 0x41, 0x00, 0xa6, 0xcf, 0x1c, 0x6c, 0x81, 0x03, 0x1c,
- 0x5c, 0x56, 0x05, 0x6a, 0x26, 0x70, 0xef, 0xd6, 0x13, 0xb7, 0x74, 0x28,
- 0xf7, 0xca, 0x50, 0xd1, 0x2d, 0x83, 0x21, 0x64, 0xe4, 0xdd, 0x3f, 0x38,
- 0xb8, 0xd6, 0xd2, 0x41, 0xb3, 0x1c, 0x9a, 0xea, 0x0d, 0xf5, 0xda, 0xdf,
- 0xcd, 0x17, 0x9f, 0x9a, 0x1e, 0x15, 0xaf, 0x48, 0x1c, 0xbd, 0x9b, 0x63,
- 0x5b, 0xad, 0xed, 0xd4, 0xa1, 0xae, 0xa9, 0x59, 0x09, 0x02, 0x40, 0x4e,
- 0x08, 0xce, 0xa8, 0x8f, 0xc0, 0xba, 0xf3, 0x83, 0x02, 0xc8, 0x33, 0x62,
- 0x14, 0x77, 0xc2, 0x7f, 0x93, 0x02, 0xf3, 0xdc, 0xe9, 0x1a, 0xee, 0xea,
- 0x8e, 0x84, 0xc4, 0x69, 0x9b, 0x9c, 0x7f, 0x69, 0x1f, 0x4e, 0x1d, 0xa5,
- 0x90, 0x06, 0x44, 0x1b, 0x7d, 0xfc, 0x69, 0x40, 0x21, 0xbc, 0xf7, 0x46,
- 0xa4, 0xdc, 0x39, 0x7b, 0xe8, 0x8b, 0x49, 0x10, 0x44, 0x9d, 0x67, 0x5a,
- 0x91, 0x86, 0x39, 0x02, 0x40, 0x41, 0x2c, 0x4e, 0xfe, 0xd9, 0x90, 0x89,
- 0x00, 0x5c, 0x94, 0x0a, 0x4a, 0x7e, 0x1b, 0x1a, 0x80, 0x06, 0x01, 0x37,
- 0xda, 0x50, 0x61, 0x9d, 0x9c, 0xfe, 0x25, 0x7f, 0xd8, 0xd4, 0xc4, 0x9e,
- 0x81, 0xf2, 0x0c, 0x1e, 0x38, 0x21, 0x1e, 0x90, 0x3f, 0xd4, 0xba, 0x6c,
- 0x53, 0xcb, 0xf0, 0x77, 0x79, 0x9b, 0xf1, 0xfa, 0x3f, 0x81, 0xdc, 0xf3,
- 0x21, 0x02, 0x6d, 0xb7, 0x95, 0xc3, 0x2e, 0xce, 0xd5
-};
-unsigned int default_private_key_len = 609;
diff --git a/axTLS/src/ssl/ssl.h b/axTLS/src/ssl/ssl.h
deleted file mode 100644
index 198efc6..0000000
--- a/axTLS/src/ssl/ssl.h
+++ /dev/null
@@ -1,499 +0,0 @@
-/*
- * Copyright (c) 2007, Cameron Rich
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * * Neither the name of the axTLS project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @mainpage axTLS API
- *
- * @image html axolotl.jpg
- *
- * The axTLS library has features such as:
- * - The TLSv1 SSL client/server protocol
- * - No requirement to use any openssl libraries.
- * - A choice between AES block (128/256 bit) and RC4 (128 bit) stream ciphers.
- * - RSA encryption/decryption with variable sized keys (up to 4096 bits).
- * - Certificate chaining and peer authentication.
- * - Session resumption, session renegotiation.
- * - ASN.1, X.509, PKCS#8, PKCS#12 keys/certificates with DER/PEM encoding.
- * - Highly configurable compile time options.
- * - Portable across many platforms (written in ANSI C), and has language
- * bindings in C, C#, VB.NET, Java, Perl and Lua.
- * - Partial openssl API compatibility (via a wrapper).
- * - A very small footprint (around 50-60kB for the library in 'server-only'
- * mode).
- * - No dependencies on sockets - can use serial connections for example.
- * - A very simple API - ~ 20 functions/methods.
- *
- * A list of these functions/methods are described below.
- *
- * @ref c_api
- *
- * @ref bigint_api
- *
- * @ref csharp_api
- *
- * @ref java_api
- */
-#ifndef HEADER_SSL_H
-#define HEADER_SSL_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <time.h>
-
-/* need to predefine before ssl_lib.h gets to it */
-#define SSL_SESSION_ID_SIZE 32
-
-#include "tls1.h"
-
-/* The optional parameters that can be given to the client/server SSL engine */
-#define SSL_CLIENT_AUTHENTICATION 0x00010000
-#define SSL_SERVER_VERIFY_LATER 0x00020000
-#define SSL_NO_DEFAULT_KEY 0x00040000
-#define SSL_DISPLAY_STATES 0x00080000
-#define SSL_DISPLAY_BYTES 0x00100000
-#define SSL_DISPLAY_CERTS 0x00200000
-#define SSL_DISPLAY_RSA 0x00400000
-#define SSL_CONNECT_IN_PARTS 0x00800000
-
-/* errors that can be generated */
-#define SSL_OK 0
-#define SSL_NOT_OK -1
-#define SSL_ERROR_DEAD -2
-#define SSL_CLOSE_NOTIFY -3
-#define SSL_ERROR_CONN_LOST -256
-#define SSL_ERROR_SOCK_SETUP_FAILURE -258
-#define SSL_ERROR_INVALID_HANDSHAKE -260
-#define SSL_ERROR_INVALID_PROT_MSG -261
-#define SSL_ERROR_INVALID_HMAC -262
-#define SSL_ERROR_INVALID_VERSION -263
-#define SSL_ERROR_INVALID_SESSION -265
-#define SSL_ERROR_NO_CIPHER -266
-#define SSL_ERROR_BAD_CERTIFICATE -268
-#define SSL_ERROR_INVALID_KEY -269
-#define SSL_ERROR_FINISHED_INVALID -271
-#define SSL_ERROR_NO_CERT_DEFINED -272
-#define SSL_ERROR_NO_CLIENT_RENOG -273
-#define SSL_ERROR_NOT_SUPPORTED -274
-#define SSL_X509_OFFSET -512
-#define SSL_X509_ERROR(A) (SSL_X509_OFFSET+A)
-
-/* alert types that are recognized */
-#define SSL_ALERT_TYPE_WARNING 1
-#define SLL_ALERT_TYPE_FATAL 2
-
-/* these are all the alerts that are recognized */
-#define SSL_ALERT_CLOSE_NOTIFY 0
-#define SSL_ALERT_UNEXPECTED_MESSAGE 10
-#define SSL_ALERT_BAD_RECORD_MAC 20
-#define SSL_ALERT_HANDSHAKE_FAILURE 40
-#define SSL_ALERT_BAD_CERTIFICATE 42
-#define SSL_ALERT_ILLEGAL_PARAMETER 47
-#define SSL_ALERT_DECODE_ERROR 50
-#define SSL_ALERT_DECRYPT_ERROR 51
-#define SSL_ALERT_INVALID_VERSION 70
-#define SSL_ALERT_NO_RENEGOTIATION 100
-
-/* The ciphers that are supported */
-#define SSL_AES128_SHA 0x2f
-#define SSL_AES256_SHA 0x35
-#define SSL_RC4_128_SHA 0x05
-#define SSL_RC4_128_MD5 0x04
-
-/* build mode ids' */
-#define SSL_BUILD_SKELETON_MODE 0x01
-#define SSL_BUILD_SERVER_ONLY 0x02
-#define SSL_BUILD_ENABLE_VERIFICATION 0x03
-#define SSL_BUILD_ENABLE_CLIENT 0x04
-#define SSL_BUILD_FULL_MODE 0x05
-
-/* offsets to retrieve configuration information */
-#define SSL_BUILD_MODE 0
-#define SSL_MAX_CERT_CFG_OFFSET 1
-#define SSL_MAX_CA_CERT_CFG_OFFSET 2
-#define SSL_HAS_PEM 3
-
-/* default session sizes */
-#define SSL_DEFAULT_SVR_SESS 5
-#define SSL_DEFAULT_CLNT_SESS 1
-
-/* X.509/X.520 distinguished name types */
-#define SSL_X509_CERT_COMMON_NAME 0
-#define SSL_X509_CERT_ORGANIZATION 1
-#define SSL_X509_CERT_ORGANIZATIONAL_NAME 2
-#define SSL_X509_CA_CERT_COMMON_NAME 3
-#define SSL_X509_CA_CERT_ORGANIZATION 4
-#define SSL_X509_CA_CERT_ORGANIZATIONAL_NAME 5
-
-/* SSL object loader types */
-#define SSL_OBJ_X509_CERT 1
-#define SSL_OBJ_X509_CACERT 2
-#define SSL_OBJ_RSA_KEY 3
-#define SSL_OBJ_PKCS8 4
-#define SSL_OBJ_PKCS12 5
-
-/**
- * @defgroup c_api Standard C API
- * @brief The standard interface in C.
- * @{
- */
-
-/**
- * @brief Establish a new client/server context.
- *
- * This function is called before any client/server SSL connections are made.
- *
- * Each new connection will use the this context's private key and
- * certificate chain. If a different certificate chain is required, then a
- * different context needs to be be used.
- *
- * There are two threading models supported - a single thread with one
- * SSL_CTX can support any number of SSL connections - and multiple threads can
- * support one SSL_CTX object each (the default). But if a single SSL_CTX
- * object uses many SSL objects in individual threads, then the
- * CONFIG_SSL_CTX_MUTEXING option needs to be configured.
- *
- * @param options [in] Any particular options. At present the options
- * supported are:
- * - SSL_SERVER_VERIFY_LATER (client only): Don't stop a handshake if the server
- * authentication fails. The certificate can be authenticated later with a
- * call to ssl_verify_cert().
- * - 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_DISPLAY_BYTES (full mode build only): Display the byte sequences
- * during the handshake.
- * - SSL_DISPLAY_STATES (full mode build only): Display the state changes
- * during the handshake.
- * - SSL_DISPLAY_CERTS (full mode build only): Display the certificates that
- * are passed during a handshake.
- * - SSL_DISPLAY_RSA (full mode build only): Display the RSA key details that
- * are passed during a handshake.
- * - SSL_CONNECT_IN_PARTS (client only): To use a non-blocking version of
- * ssl_client_new().
- * @param num_sessions [in] The number of sessions to be used for session
- * caching. If this value is 0, then there is no session caching. This option
- * is not used in skeleton mode.
- * @return A client/server context.
- */
-EXP_FUNC SSL_CTX * STDCALL ssl_ctx_new(uint32_t options, int num_sessions);
-
-/**
- * @brief Remove a client/server context.
- *
- * Frees any used resources used by this context. Each connection will be
- * sent a "Close Notify" alert (if possible).
- * @param ssl_ctx [in] The client/server context.
- */
-EXP_FUNC void STDCALL ssl_ctx_free(SSL_CTX *ssl_ctx);
-
-/**
- * @brief (server only) Establish a new SSL connection to an SSL client.
- *
- * It is up to the application to establish the logical connection (whether it
- * is a socket, serial connection etc).
- * @param ssl_ctx [in] The server context.
- * @param client_fd [in] The client's file descriptor.
- * @return An SSL object reference.
- */
-EXP_FUNC SSL * STDCALL ssl_server_new(SSL_CTX *ssl_ctx, int client_fd);
-
-/**
- * @brief (client only) Establish a new SSL connection to an SSL server.
- *
- * It is up to the application to establish the initial logical connection
- * (whether it is a socket, serial connection etc).
- *
- * This is a normally a blocking call - it will finish when the handshake is
- * complete (or has failed). To use in non-blocking mode, set
- * SSL_CONNECT_IN_PARTS in ssl_ctx_new().
- * @param ssl_ctx [in] The client context.
- * @param client_fd [in] The client's file descriptor.
- * @param session_id [in] A 32 byte session id for session resumption. This
- * can be null if no session resumption is being used or required. This option
- * is not used in skeleton mode.
- * @param sess_id_size The size of the session id (max 32)
- * @return An SSL object reference. Use ssl_handshake_status() to check
- * if a handshake succeeded.
- */
-EXP_FUNC SSL * STDCALL ssl_client_new(SSL_CTX *ssl_ctx, int client_fd, const uint8_t *session_id, uint8_t sess_id_size);
-
-/**
- * @brief Free any used resources on this connection.
-
- * A "Close Notify" message is sent on this connection (if possible). It is up
- * to the application to close the socket or file descriptor.
- * @param ssl [in] The ssl object reference.
- */
-EXP_FUNC void STDCALL ssl_free(SSL *ssl);
-
-/**
- * @brief Read the SSL data stream.
- * If the socket is non-blocking and data is blocked then SSO_OK will be
- * returned.
- * @param ssl [in] An SSL object reference.
- * @param in_data [out] If the read was successful, a pointer to the read
- * buffer will be here. Do NOT ever free this memory as this buffer is used in
- * sucessive calls. If the call was unsuccessful, this value will be null.
- * @return The number of decrypted bytes:
- * - if > 0, then the handshaking is complete and we are returning the number
- * of decrypted bytes.
- * - SSL_OK if the handshaking stage is successful (but not yet complete).
- * - < 0 if an error.
- * @see ssl.h for the error code list.
- * @note Use in_data before doing any successive ssl calls.
- */
-EXP_FUNC int STDCALL ssl_read(SSL *ssl, uint8_t **in_data);
-
-/**
- * @brief Write to the SSL data stream.
- * if the socket is non-blocking and data is blocked then a check is made
- * to ensure that all data is sent (i.e. blocked mode is forced).
- * @param ssl [in] An SSL obect reference.
- * @param out_data [in] The data to be written
- * @param out_len [in] The number of bytes to be written.
- * @return The number of bytes sent, or if < 0 if an error.
- * @see ssl.h for the error code list.
- */
-EXP_FUNC int STDCALL ssl_write(SSL *ssl, const uint8_t *out_data, int out_len);
-
-/**
- * @brief Find an ssl object based on a file descriptor.
- *
- * Goes through the list of SSL objects maintained in a client/server context
- * to look for a file descriptor match.
- * @param ssl_ctx [in] The client/server context.
- * @param client_fd [in] The file descriptor.
- * @return A reference to the SSL object. Returns null if the object could not
- * be found.
- */
-EXP_FUNC SSL * STDCALL ssl_find(SSL_CTX *ssl_ctx, int client_fd);
-
-/**
- * @brief Get the session id for a handshake.
- *
- * This will be a 32 byte sequence and is available after the first
- * handshaking messages are sent.
- * @param ssl [in] An SSL object reference.
- * @return The session id as a 32 byte sequence.
- * @note A SSLv23 handshake may have only 16 valid bytes.
- */
-EXP_FUNC const uint8_t * STDCALL ssl_get_session_id(const SSL *ssl);
-
-/**
- * @brief Get the session id size for a handshake.
- *
- * This will normally be 32 but could be 0 (no session id) or something else.
- * @param ssl [in] An SSL object reference.
- * @return The size of the session id.
- */
-EXP_FUNC uint8_t STDCALL ssl_get_session_id_size(const SSL *ssl);
-
-/**
- * @brief Return the cipher id (in the SSL form).
- * @param ssl [in] An SSL object reference.
- * @return The cipher id. This will be one of the following:
- * - SSL_AES128_SHA (0x2f)
- * - SSL_AES256_SHA (0x35)
- * - SSL_RC4_128_SHA (0x05)
- * - SSL_RC4_128_MD5 (0x04)
- */
-EXP_FUNC uint8_t STDCALL ssl_get_cipher_id(const SSL *ssl);
-
-/**
- * @brief Return the status of the handshake.
- * @param ssl [in] An SSL object reference.
- * @return SSL_OK if the handshake is complete and ok.
- * @see ssl.h for the error code list.
- */
-EXP_FUNC int STDCALL ssl_handshake_status(const SSL *ssl);
-
-/**
- * @brief Retrieve various parameters about the axTLS engine.
- * @param offset [in] The configuration offset. It will be one of the following:
- * - SSL_BUILD_MODE The build mode. This will be one of the following:
- * - SSL_BUILD_SERVER_ONLY (basic server mode)
- * - SSL_BUILD_ENABLE_VERIFICATION (server can do client authentication)
- * - SSL_BUILD_ENABLE_CLIENT (client/server capabilties)
- * - SSL_BUILD_FULL_MODE (client/server with diagnostics)
- * - SSL_BUILD_SKELETON_MODE (skeleton mode)
- * - SSL_MAX_CERT_CFG_OFFSET The maximum number of certificates allowed.
- * - SSL_MAX_CA_CERT_CFG_OFFSET The maximum number of CA certificates allowed.
- * - SSL_HAS_PEM 1 if supported
- * @return The value of the requested parameter.
- */
-EXP_FUNC int STDCALL ssl_get_config(int offset);
-
-/**
- * @brief Display why the handshake failed.
- *
- * This call is only useful in a 'full mode' build. The output is to stdout.
- * @param error_code [in] An error code.
- * @see ssl.h for the error code list.
- */
-EXP_FUNC void STDCALL ssl_display_error(int error_code);
-
-/**
- * @brief Authenticate a received certificate.
- *
- * This call is usually made by a client after a handshake is complete and the
- * context is in SSL_SERVER_VERIFY_LATER mode.
- * @param ssl [in] An SSL object reference.
- * @return SSL_OK if the certificate is verified.
- */
-EXP_FUNC int STDCALL ssl_verify_cert(const SSL *ssl);
-
-/**
- * @brief Retrieve an X.509 distinguished name component.
- *
- * When a handshake is complete and a certificate has been exchanged, then the
- * details of the remote certificate can be retrieved.
- *
- * This will usually be used by a client to check that the server's common
- * name matches the URL.
- *
- * @param ssl [in] An SSL object reference.
- * @param component [in] one of:
- * - SSL_X509_CERT_COMMON_NAME
- * - SSL_X509_CERT_ORGANIZATION
- * - SSL_X509_CERT_ORGANIZATIONAL_NAME
- * - SSL_X509_CA_CERT_COMMON_NAME
- * - SSL_X509_CA_CERT_ORGANIZATION
- * - SSL_X509_CA_CERT_ORGANIZATIONAL_NAME
- * @return The appropriate string (or null if not defined)
- * @note Verification build mode must be enabled.
- */
-EXP_FUNC const char * STDCALL ssl_get_cert_dn(const SSL *ssl, int component);
-
-/**
- * @brief Retrieve a Subject Alternative DNSName
- *
- * When a handshake is complete and a certificate has been exchanged, then the
- * details of the remote certificate can be retrieved.
- *
- * This will usually be used by a client to check that the server's DNS
- * name matches the URL.
- *
- * @param ssl [in] An SSL object reference.
- * @param dnsindex [in] The index of the DNS name to retrieve.
- * @return The appropriate string (or null if not defined)
- * @note Verification build mode must be enabled.
- */
-EXP_FUNC const char * STDCALL ssl_get_cert_subject_alt_dnsname(const SSL *ssl, int dnsindex);
-
-/**
- * @brief Force the client to perform its handshake again.
- *
- * For a client this involves sending another "client hello" message.
- * For the server is means sending a "hello request" message.
- *
- * This is a blocking call on the client (until the handshake completes).
- *
- * @param ssl [in] An SSL object reference.
- * @return SSL_OK if renegotiation instantiation was ok
- */
-EXP_FUNC int STDCALL ssl_renegotiate(SSL *ssl);
-
-/**
- * @brief Process a file that is in binary DER or ASCII PEM format.
- *
- * These are temporary objects that are used to load private keys,
- * certificates etc into memory.
- * @param ssl_ctx [in] The client/server context.
- * @param obj_type [in] The format of the file. Can be one of:
- * - SSL_OBJ_X509_CERT (no password required)
- * - SSL_OBJ_X509_CACERT (no password required)
- * - SSL_OBJ_RSA_KEY (AES128/AES256 PEM encryption supported)
- * - SSL_OBJ_PKCS8 (RC4-128 encrypted data supported)
- * - SSL_OBJ_PKCS12 (RC4-128 encrypted data supported)
- *
- * PEM files are automatically detected (if supported). The object type is
- * also detected, and so is not relevant for these types of files.
- * @param filename [in] The location of a file in DER/PEM format.
- * @param password [in] The password used. Can be null if not required.
- * @return SSL_OK if all ok
- * @note Not available in skeleton build mode.
- */
-EXP_FUNC int STDCALL ssl_obj_load(SSL_CTX *ssl_ctx, int obj_type, const char *filename, const char *password);
-
-/**
- * @brief Process binary data.
- *
- * These are temporary objects that are used to load private keys,
- * certificates etc into memory.
- * @param ssl_ctx [in] The client/server context.
- * @param obj_type [in] The format of the memory data.
- * @param data [in] The binary data to be loaded.
- * @param len [in] The amount of data to be loaded.
- * @param password [in] The password used. Can be null if not required.
- * @return SSL_OK if all ok
- * @see ssl_obj_load for more details on obj_type.
- */
-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 signed with an internal private key in ssl_ctx.
- *
- * @param ssl_ctx [in] The client/server context.
- * @param options [in] Not used yet.
- * @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 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, uint32_t options, const char * dn[], uint8_t **cert_data);
-#endif
-
-/**
- * @brief Return the axTLS library version as a string.
- */
-EXP_FUNC const char * STDCALL ssl_version(void);
-
-/** @} */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/axTLS/src/ssl/tls1.c b/axTLS/src/ssl/tls1.c
deleted file mode 100644
index 4b18365..0000000
--- a/axTLS/src/ssl/tls1.c
+++ /dev/null
@@ -1,2195 +0,0 @@
-/*
- * Copyright (c) 2007, Cameron Rich
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * * Neither the name of the axTLS project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * Common ssl/tlsv1 code to both the client and server implementations.
- */
-
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include "os_port.h"
-#include "ssl.h"
-
-/* The session expiry time */
-#define SSL_EXPIRY_TIME (CONFIG_SSL_EXPIRY_TIME*3600)
-
-static const uint8_t g_hello_request[] = { HS_HELLO_REQUEST, 0, 0, 0 };
-static const uint8_t g_chg_cipher_spec_pkt[] = { 1 };
-static const char * server_finished = "server finished";
-static const char * client_finished = "client finished";
-
-static int do_handshake(SSL *ssl, uint8_t *buf, int read_len);
-static int set_key_block(SSL *ssl, int is_write);
-static int verify_digest(SSL *ssl, int mode, const uint8_t *buf, int read_len);
-static void *crypt_new(SSL *ssl, uint8_t *key, uint8_t *iv, int is_decrypt);
-static int send_raw_packet(SSL *ssl, uint8_t protocol);
-
-/**
- * The server will pick the cipher based on the order that the order that the
- * ciphers are listed. This order is defined at compile time.
- */
-#ifdef CONFIG_SSL_SKELETON_MODE
-const uint8_t ssl_prot_prefs[NUM_PROTOCOLS] =
-{ SSL_RC4_128_SHA };
-#else
-static void session_free(SSL_SESSION *ssl_sessions[], int sess_index);
-
-const uint8_t ssl_prot_prefs[NUM_PROTOCOLS] =
-#ifdef CONFIG_SSL_PROT_LOW /* low security, fast speed */
-{ SSL_RC4_128_SHA, SSL_AES128_SHA, SSL_AES256_SHA, SSL_RC4_128_MD5 };
-#elif CONFIG_SSL_PROT_MEDIUM /* medium security, medium speed */
-{ SSL_AES128_SHA, SSL_AES256_SHA, SSL_RC4_128_SHA, SSL_RC4_128_MD5 };
-#else /* CONFIG_SSL_PROT_HIGH */ /* high security, low speed */
-{ SSL_AES256_SHA, SSL_AES128_SHA, SSL_RC4_128_SHA, SSL_RC4_128_MD5 };
-#endif
-#endif /* CONFIG_SSL_SKELETON_MODE */
-
-/**
- * The cipher map containing all the essentials for each cipher.
- */
-#ifdef CONFIG_SSL_SKELETON_MODE
-static const cipher_info_t cipher_info[NUM_PROTOCOLS] =
-{
- { /* RC4-SHA */
- SSL_RC4_128_SHA, /* RC4-SHA */
- 16, /* key size */
- 0, /* iv size */
- 2*(SHA1_SIZE+16), /* key block size */
- 0, /* no padding */
- SHA1_SIZE, /* digest size */
- hmac_sha1, /* hmac algorithm */
- (crypt_func)RC4_crypt, /* encrypt */
- (crypt_func)RC4_crypt /* decrypt */
- },
-};
-#else
-static const cipher_info_t cipher_info[NUM_PROTOCOLS] =
-{
- { /* AES128-SHA */
- SSL_AES128_SHA, /* AES128-SHA */
- 16, /* key size */
- 16, /* iv size */
- 2*(SHA1_SIZE+16+16), /* key block size */
- 16, /* block padding size */
- SHA1_SIZE, /* digest size */
- hmac_sha1, /* hmac algorithm */
- (crypt_func)AES_cbc_encrypt, /* encrypt */
- (crypt_func)AES_cbc_decrypt /* decrypt */
- },
- { /* AES256-SHA */
- SSL_AES256_SHA, /* AES256-SHA */
- 32, /* key size */
- 16, /* iv size */
- 2*(SHA1_SIZE+32+16), /* key block size */
- 16, /* block padding size */
- SHA1_SIZE, /* digest size */
- hmac_sha1, /* hmac algorithm */
- (crypt_func)AES_cbc_encrypt, /* encrypt */
- (crypt_func)AES_cbc_decrypt /* decrypt */
- },
- { /* RC4-SHA */
- SSL_RC4_128_SHA, /* RC4-SHA */
- 16, /* key size */
- 0, /* iv size */
- 2*(SHA1_SIZE+16), /* key block size */
- 0, /* no padding */
- SHA1_SIZE, /* digest size */
- hmac_sha1, /* hmac algorithm */
- (crypt_func)RC4_crypt, /* encrypt */
- (crypt_func)RC4_crypt /* decrypt */
- },
- /*
- * This protocol is from SSLv2 days and is unlikely to be used - but was
- * useful for testing different possible digest algorithms.
- */
- { /* RC4-MD5 */
- SSL_RC4_128_MD5, /* RC4-MD5 */
- 16, /* key size */
- 0, /* iv size */
- 2*(MD5_SIZE+16), /* key block size */
- 0, /* no padding */
- MD5_SIZE, /* digest size */
- hmac_md5, /* hmac algorithm */
- (crypt_func)RC4_crypt, /* encrypt */
- (crypt_func)RC4_crypt /* decrypt */
- },
-};
-#endif
-
-static void prf(const uint8_t *sec, int sec_len, uint8_t *seed, int seed_len,
- uint8_t *out, int olen);
-static const cipher_info_t *get_cipher_info(uint8_t cipher);
-static void increment_read_sequence(SSL *ssl);
-static void increment_write_sequence(SSL *ssl);
-static void add_hmac_digest(SSL *ssl, int snd, uint8_t *hmac_header,
- const uint8_t *buf, int buf_len, uint8_t *hmac_buf);
-
-/* win32 VC6.0 doesn't have variadic macros */
-#if defined(WIN32) && !defined(CONFIG_SSL_FULL_MODE)
-void DISPLAY_BYTES(SSL *ssl, const char *format,
- const uint8_t *data, int size, ...) {}
-#endif
-
-/**
- * Establish a new client/server context.
- */
-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);
-
-#ifndef CONFIG_SSL_SKELETON_MODE
- if (num_sessions)
- {
- ssl_ctx->ssl_sessions = (SSL_SESSION **)
- calloc(1, num_sessions*sizeof(SSL_SESSION *));
- }
-#endif
-
- return ssl_ctx;
-}
-
-/*
- * Remove a client/server context.
- */
-EXP_FUNC void STDCALL ssl_ctx_free(SSL_CTX *ssl_ctx)
-{
- SSL *ssl;
- int i;
-
- if (ssl_ctx == NULL)
- return;
-
- ssl = ssl_ctx->head;
-
- /* clear out all the ssl entries */
- while (ssl)
- {
- SSL *next = ssl->next;
- ssl_free(ssl);
- ssl = next;
- }
-
-#ifndef CONFIG_SSL_SKELETON_MODE
- /* clear out all the sessions */
- for (i = 0; i < ssl_ctx->num_sessions; i++)
- session_free(ssl_ctx->ssl_sessions, i);
-
- free(ssl_ctx->ssl_sessions);
-#endif
-
- i = 0;
- while (i < CONFIG_SSL_MAX_CERTS && ssl_ctx->certs[i].buf)
- {
- free(ssl_ctx->certs[i].buf);
- ssl_ctx->certs[i++].buf = NULL;
- }
-
-#ifdef CONFIG_SSL_CERT_VERIFICATION
- remove_ca_certs(ssl_ctx->ca_cert_ctx);
-#endif
- ssl_ctx->chain_length = 0;
- SSL_CTX_MUTEX_DESTROY(ssl_ctx->mutex);
- RSA_free(ssl_ctx->rsa_ctx);
- RNG_terminate();
- free(ssl_ctx);
-}
-
-/*
- * Free any used resources used by this connection.
- */
-EXP_FUNC void STDCALL ssl_free(SSL *ssl)
-{
- SSL_CTX *ssl_ctx;
-
- if (ssl == NULL) /* just ignore null pointers */
- return;
-
- /* only notify if we weren't notified first */
- /* spec says we must notify when we are dying */
- if (!IS_SET_SSL_FLAG(SSL_SENT_CLOSE_NOTIFY))
- send_alert(ssl, SSL_ALERT_CLOSE_NOTIFY);
-
- ssl_ctx = ssl->ssl_ctx;
-
- SSL_CTX_LOCK(ssl_ctx->mutex);
-
- /* adjust the server SSL list */
- if (ssl->prev)
- ssl->prev->next = ssl->next;
- else
- ssl_ctx->head = ssl->next;
-
- if (ssl->next)
- ssl->next->prev = ssl->prev;
- else
- ssl_ctx->tail = ssl->prev;
-
- SSL_CTX_UNLOCK(ssl_ctx->mutex);
-
- /* may already be free - but be sure */
- free(ssl->encrypt_ctx);
- free(ssl->decrypt_ctx);
- disposable_free(ssl);
-#ifdef CONFIG_SSL_CERT_VERIFICATION
- x509_free(ssl->x509_ctx);
-#endif
-
- free(ssl);
-}
-
-EXP_FUNC int STDCALL ssl_handshake(SSL_CTX* ctx);
-
-/*
- * Read the SSL connection and send any alerts for various errors.
- */
-EXP_FUNC int STDCALL ssl_read(SSL *ssl, uint8_t **in_data)
-{
- int ret = basic_read(ssl, in_data);
-
- /* check for return code so we can send an alert */
- if (ret < SSL_OK && ret != SSL_CLOSE_NOTIFY)
- {
- if (ret != SSL_ERROR_CONN_LOST)
- {
- send_alert(ssl, ret);
-#ifndef CONFIG_SSL_SKELETON_MODE
- /* something nasty happened, so get rid of this session */
- kill_ssl_session(ssl->ssl_ctx->ssl_sessions, ssl);
-#endif
- }
- }
-
- return ret;
-}
-
-/*
- * Write application data to the client
- */
-EXP_FUNC int STDCALL ssl_write(SSL *ssl, const uint8_t *out_data, int out_len)
-{
- int n = out_len, nw, i, tot = 0;
-
- /* maximum size of a TLS packet is around 16kB, so fragment */
- do
- {
- nw = n;
-
- if (nw > RT_MAX_PLAIN_LENGTH) /* fragment if necessary */
- nw = RT_MAX_PLAIN_LENGTH;
-
- if ((i = send_packet(ssl, PT_APP_PROTOCOL_DATA,
- &out_data[tot], nw)) <= 0)
- {
- out_len = i; /* an error */
- break;
- }
-
- tot += i;
- n -= i;
- } while (n > 0);
-
- return out_len;
-}
-
-/**
- * Add a certificate to the certificate chain.
- */
-int add_cert(SSL_CTX *ssl_ctx, const uint8_t *buf, int len)
-{
- int ret = SSL_ERROR_NO_CERT_DEFINED, i = 0;
- SSL_CERT *ssl_cert;
- X509_CTX *cert = NULL;
- int offset;
-
- while (ssl_ctx->certs[i].buf && i < CONFIG_SSL_MAX_CERTS)
- i++;
-
- if (i == CONFIG_SSL_MAX_CERTS) /* too many certs */
- {
-#ifdef CONFIG_SSL_FULL_MODE
- printf("Error: maximum number of certs added (%d) - change of "
- "compile-time configuration required\n",
- CONFIG_SSL_MAX_CERTS);
-#endif
- goto error;
- }
-
- if ((ret = x509_new(buf, &offset, &cert)))
- goto error;
-
-#if defined (CONFIG_SSL_FULL_MODE)
- if (ssl_ctx->options & SSL_DISPLAY_CERTS)
- x509_print(cert, NULL);
-#endif
-
- ssl_cert = &ssl_ctx->certs[i];
- ssl_cert->size = len;
- ssl_cert->buf = (uint8_t *)malloc(len);
- memcpy(ssl_cert->buf, buf, len);
- ssl_ctx->chain_length++;
- len -= offset;
- ret = SSL_OK; /* ok so far */
-
- /* recurse? */
- if (len > 0)
- {
- ret = add_cert(ssl_ctx, &buf[offset], len);
- }
-
-error:
- x509_free(cert); /* don't need anymore */
- return ret;
-}
-
-#ifdef CONFIG_SSL_CERT_VERIFICATION
-/**
- * Add a certificate authority.
- */
-int add_cert_auth(SSL_CTX *ssl_ctx, const uint8_t *buf, int len)
-{
- int ret = SSL_OK; /* ignore errors for now */
- int i = 0;
- 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++;
-
- while (len > 0)
- {
- int offset;
- if (i >= CONFIG_X509_MAX_CA_CERTS)
- {
-#ifdef CONFIG_SSL_FULL_MODE
- printf("Error: maximum number of CA certs added (%d) - change of "
- "compile-time configuration required\n",
- CONFIG_X509_MAX_CA_CERTS);
-#endif
- break;
- }
-
-
- /* ignore the return code */
- if (x509_new(buf, &offset, &ca_cert_ctx->cert[i]) == X509_OK)
- {
-#if defined (CONFIG_SSL_FULL_MODE)
- if (ssl_ctx->options & SSL_DISPLAY_CERTS)
- x509_print(ca_cert_ctx->cert[i], NULL);
-#endif
- }
-
- i++;
- len -= offset;
- }
-
- return ret;
-}
-
-/*
- * Retrieve an X.509 distinguished name component
- */
-EXP_FUNC const char * STDCALL ssl_get_cert_dn(const SSL *ssl, int component)
-{
- if (ssl->x509_ctx == NULL)
- return NULL;
-
- switch (component)
- {
- case SSL_X509_CERT_COMMON_NAME:
- return ssl->x509_ctx->cert_dn[X509_COMMON_NAME];
-
- case SSL_X509_CERT_ORGANIZATION:
- return ssl->x509_ctx->cert_dn[X509_ORGANIZATION];
-
- case SSL_X509_CERT_ORGANIZATIONAL_NAME:
- return ssl->x509_ctx->cert_dn[X509_ORGANIZATIONAL_UNIT];
-
- case SSL_X509_CA_CERT_COMMON_NAME:
- return ssl->x509_ctx->ca_cert_dn[X509_COMMON_NAME];
-
- case SSL_X509_CA_CERT_ORGANIZATION:
- return ssl->x509_ctx->ca_cert_dn[X509_ORGANIZATION];
-
- case SSL_X509_CA_CERT_ORGANIZATIONAL_NAME:
- return ssl->x509_ctx->ca_cert_dn[X509_ORGANIZATIONAL_UNIT];
-
- default:
- return NULL;
- }
-}
-
-/*
- * Retrieve a "Subject Alternative Name" from a v3 certificate
- */
-EXP_FUNC const char * STDCALL ssl_get_cert_subject_alt_dnsname(const SSL *ssl,
- int dnsindex)
-{
- int i;
-
- if (ssl->x509_ctx == NULL || ssl->x509_ctx->subject_alt_dnsnames == NULL)
- return NULL;
-
- for (i = 0; i < dnsindex; ++i)
- {
- if (ssl->x509_ctx->subject_alt_dnsnames[i] == NULL)
- return NULL;
- }
-
- return ssl->x509_ctx->subject_alt_dnsnames[dnsindex];
-}
-
-#endif /* CONFIG_SSL_CERT_VERIFICATION */
-
-/*
- * Find an ssl object based on the client's file descriptor.
- */
-EXP_FUNC SSL * STDCALL ssl_find(SSL_CTX *ssl_ctx, int client_fd)
-{
- SSL *ssl;
-
- SSL_CTX_LOCK(ssl_ctx->mutex);
- ssl = ssl_ctx->head;
-
- /* search through all the ssl entries */
- while (ssl)
- {
- if (ssl->client_fd == client_fd)
- {
- SSL_CTX_UNLOCK(ssl_ctx->mutex);
- return ssl;
- }
-
- ssl = ssl->next;
- }
-
- SSL_CTX_UNLOCK(ssl_ctx->mutex);
- return NULL;
-}
-
-/*
- * Force the client to perform its handshake again.
- */
-EXP_FUNC int STDCALL ssl_renegotiate(SSL *ssl)
-{
- int ret = SSL_OK;
-
- disposable_new(ssl);
-#ifdef CONFIG_SSL_ENABLE_CLIENT
- if (IS_SET_SSL_FLAG(SSL_IS_CLIENT))
- {
- ret = do_client_connect(ssl);
- }
- else
-#endif
- {
- send_packet(ssl, PT_HANDSHAKE_PROTOCOL,
- g_hello_request, sizeof(g_hello_request));
- SET_SSL_FLAG(SSL_NEED_RECORD);
- }
-
- return ret;
-}
-
-/**
- * @brief Get what we need for key info.
- * @param cipher [in] The cipher information we are after
- * @param key_size [out] The key size for the cipher
- * @param iv_size [out] The iv size for the cipher
- * @return The amount of key information we need.
- */
-static const cipher_info_t *get_cipher_info(uint8_t cipher)
-{
- int i;
-
- for (i = 0; i < NUM_PROTOCOLS; i++)
- {
- if (cipher_info[i].cipher == cipher)
- {
- return &cipher_info[i];
- }
- }
-
- return NULL; /* error */
-}
-
-/*
- * Get a new ssl context for a new connection.
- */
-SSL *ssl_new(SSL_CTX *ssl_ctx, int client_fd)
-{
- SSL *ssl = (SSL *)calloc(1, sizeof(SSL));
- ssl->ssl_ctx = ssl_ctx;
- ssl->need_bytes = SSL_RECORD_SIZE; /* need a record */
- ssl->client_fd = client_fd;
- ssl->flag = SSL_NEED_RECORD;
- ssl->bm_data = ssl->bm_all_data+BM_RECORD_OFFSET; /* space at the start */
- ssl->hs_status = SSL_NOT_OK; /* not connected */
-#ifdef CONFIG_ENABLE_VERIFICATION
- ssl->ca_cert_ctx = ssl_ctx->ca_cert_ctx;
-#endif
- disposable_new(ssl);
-
- /* a bit hacky but saves a few bytes of memory */
- ssl->flag |= ssl_ctx->options;
- SSL_CTX_LOCK(ssl_ctx->mutex);
-
- if (ssl_ctx->head == NULL)
- {
- ssl_ctx->head = ssl;
- ssl_ctx->tail = ssl;
- }
- else
- {
- ssl->prev = ssl_ctx->tail;
- ssl_ctx->tail->next = ssl;
- ssl_ctx->tail = ssl;
- }
-
- SSL_CTX_UNLOCK(ssl_ctx->mutex);
- return ssl;
-}
-
-/*
- * Add a private key to a context.
- */
-int add_private_key(SSL_CTX *ssl_ctx, SSLObjLoader *ssl_obj)
-{
- int ret = SSL_OK;
-
- /* get the private key details */
- if (asn1_get_private_key(ssl_obj->buf, ssl_obj->len, &ssl_ctx->rsa_ctx))
- {
- ret = SSL_ERROR_INVALID_KEY;
- goto error;
- }
-
-error:
- return ret;
-}
-
-/**
- * Increment the read sequence number (as a 64 bit endian indepenent #)
- */
-static void increment_read_sequence(SSL *ssl)
-{
- int i;
-
- for (i = 7; i >= 0; i--)
- {
- if (++ssl->read_sequence[i])
- break;
- }
-}
-
-/**
- * Increment the read sequence number (as a 64 bit endian indepenent #)
- */
-static void increment_write_sequence(SSL *ssl)
-{
- int i;
-
- for (i = 7; i >= 0; i--)
- {
- if (++ssl->write_sequence[i])
- break;
- }
-}
-
-/**
- * Work out the HMAC digest in a packet.
- */
-static void add_hmac_digest(SSL *ssl, int mode, uint8_t *hmac_header,
- const uint8_t *buf, int buf_len, uint8_t *hmac_buf)
-{
- int hmac_len = buf_len + 8 + SSL_RECORD_SIZE;
- uint8_t *t_buf = (uint8_t *)alloca(hmac_len+10);
-
- memcpy(t_buf, (mode == SSL_SERVER_WRITE || mode == SSL_CLIENT_WRITE) ?
- ssl->write_sequence : ssl->read_sequence, 8);
- memcpy(&t_buf[8], hmac_header, SSL_RECORD_SIZE);
- memcpy(&t_buf[8+SSL_RECORD_SIZE], buf, buf_len);
-
- ssl->cipher_info->hmac(t_buf, hmac_len,
- (mode == SSL_SERVER_WRITE || mode == SSL_CLIENT_READ) ?
- ssl->server_mac : ssl->client_mac,
- ssl->cipher_info->digest_size, hmac_buf);
-
-#if 0
- print_blob("record", ssl->hmac_tx, SSL_RECORD_SIZE);
- print_blob("buf", buf, buf_len);
- if (mode == SSL_SERVER_WRITE || mode == SSL_CLIENT_WRITE)
- {
- print_blob("write seq", ssl->write_sequence, 8);
- }
- else
- {
- print_blob("read seq", ssl->read_sequence, 8);
- }
-
- if (mode == SSL_SERVER_WRITE || mode == SSL_CLIENT_READ)
- {
- print_blob("server mac",
- ssl->server_mac, ssl->cipher_info->digest_size);
- }
- else
- {
- print_blob("client mac",
- ssl->client_mac, ssl->cipher_info->digest_size);
- }
- print_blob("hmac", hmac_buf, SHA1_SIZE);
-#endif
-}
-
-/**
- * Verify that the digest of a packet is correct.
- */
-static int verify_digest(SSL *ssl, int mode, const uint8_t *buf, int read_len)
-{
- uint8_t hmac_buf[SHA1_SIZE];
- int hmac_offset;
-
- if (ssl->cipher_info->padding_size)
- {
- int last_blk_size = buf[read_len-1], i;
- hmac_offset = read_len-last_blk_size-ssl->cipher_info->digest_size-1;
-
- /* guard against a timing attack - make sure we do the digest */
- if (hmac_offset < 0)
- {
- hmac_offset = 0;
- }
- else
- {
- /* already looked at last byte */
- for (i = 1; i < last_blk_size; i++)
- {
- if (buf[read_len-i] != last_blk_size)
- {
- hmac_offset = 0;
- break;
- }
- }
- }
- }
- else /* stream cipher */
- {
- hmac_offset = read_len - ssl->cipher_info->digest_size;
-
- if (hmac_offset < 0)
- {
- hmac_offset = 0;
- }
- }
-
- /* sanity check the offset */
- ssl->hmac_header[3] = hmac_offset >> 8; /* insert size */
- ssl->hmac_header[4] = hmac_offset & 0xff;
- add_hmac_digest(ssl, mode, ssl->hmac_header, buf, hmac_offset, hmac_buf);
-
- if (memcmp(hmac_buf, &buf[hmac_offset], ssl->cipher_info->digest_size))
- {
- return SSL_ERROR_INVALID_HMAC;
- }
-
- return hmac_offset;
-}
-
-/**
- * Add a packet to the end of our sent and received packets, so that we may use
- * it to calculate the hash at the end.
- */
-void add_packet(SSL *ssl, const uint8_t *pkt, int len)
-{
- MD5_Update(&ssl->dc->md5_ctx, pkt, len);
- SHA1_Update(&ssl->dc->sha1_ctx, pkt, len);
-}
-
-/**
- * Work out the MD5 PRF.
- */
-static void p_hash_md5(const uint8_t *sec, int sec_len,
- uint8_t *seed, int seed_len, uint8_t *out, int olen)
-{
- uint8_t a1[128];
-
- /* A(1) */
- hmac_md5(seed, seed_len, sec, sec_len, a1);
- memcpy(&a1[MD5_SIZE], seed, seed_len);
- hmac_md5(a1, MD5_SIZE+seed_len, sec, sec_len, out);
-
- while (olen > MD5_SIZE)
- {
- uint8_t a2[MD5_SIZE];
- out += MD5_SIZE;
- olen -= MD5_SIZE;
-
- /* A(N) */
- hmac_md5(a1, MD5_SIZE, sec, sec_len, a2);
- memcpy(a1, a2, MD5_SIZE);
-
- /* work out the actual hash */
- hmac_md5(a1, MD5_SIZE+seed_len, sec, sec_len, out);
- }
-}
-
-/**
- * Work out the SHA1 PRF.
- */
-static void p_hash_sha1(const uint8_t *sec, int sec_len,
- uint8_t *seed, int seed_len, uint8_t *out, int olen)
-{
- uint8_t a1[128];
-
- /* A(1) */
- hmac_sha1(seed, seed_len, sec, sec_len, a1);
- memcpy(&a1[SHA1_SIZE], seed, seed_len);
- hmac_sha1(a1, SHA1_SIZE+seed_len, sec, sec_len, out);
-
- while (olen > SHA1_SIZE)
- {
- uint8_t a2[SHA1_SIZE];
- out += SHA1_SIZE;
- olen -= SHA1_SIZE;
-
- /* A(N) */
- hmac_sha1(a1, SHA1_SIZE, sec, sec_len, a2);
- memcpy(a1, a2, SHA1_SIZE);
-
- /* work out the actual hash */
- hmac_sha1(a1, SHA1_SIZE+seed_len, sec, sec_len, out);
- }
-}
-
-/**
- * Work out the PRF.
- */
-static void prf(const uint8_t *sec, int sec_len, uint8_t *seed, int seed_len,
- uint8_t *out, int olen)
-{
- int len, i;
- const uint8_t *S1, *S2;
- uint8_t xbuf[256]; /* needs to be > the amount of key data */
- uint8_t ybuf[256]; /* needs to be > the amount of key data */
-
- len = sec_len/2;
- S1 = sec;
- S2 = &sec[len];
- len += (sec_len & 1); /* add for odd, make longer */
-
- p_hash_md5(S1, len, seed, seed_len, xbuf, olen);
- p_hash_sha1(S2, len, seed, seed_len, ybuf, olen);
-
- for (i = 0; i < olen; i++)
- out[i] = xbuf[i] ^ ybuf[i];
-}
-
-/**
- * Generate a master secret based on the client/server random data and the
- * premaster secret.
- */
-void generate_master_secret(SSL *ssl, const uint8_t *premaster_secret)
-{
- uint8_t buf[128]; /* needs to be > 13+32+32 in size */
- strcpy((char *)buf, "master secret");
- memcpy(&buf[13], ssl->dc->client_random, SSL_RANDOM_SIZE);
- memcpy(&buf[45], ssl->dc->server_random, SSL_RANDOM_SIZE);
- prf(premaster_secret, SSL_SECRET_SIZE, buf, 77, ssl->dc->master_secret,
- SSL_SECRET_SIZE);
-}
-
-/**
- * Generate a 'random' blob of data used for the generation of keys.
- */
-static void generate_key_block(uint8_t *client_random, uint8_t *server_random,
- uint8_t *master_secret, uint8_t *key_block, int key_block_size)
-{
- uint8_t buf[128];
- strcpy((char *)buf, "key expansion");
- memcpy(&buf[13], server_random, SSL_RANDOM_SIZE);
- memcpy(&buf[45], client_random, SSL_RANDOM_SIZE);
- prf(master_secret, SSL_SECRET_SIZE, buf, 77, key_block, key_block_size);
-}
-
-/**
- * Calculate the digest used in the finished message. This function also
- * doubles up as a certificate verify function.
- */
-void finished_digest(SSL *ssl, const char *label, uint8_t *digest)
-{
- uint8_t mac_buf[128];
- uint8_t *q = mac_buf;
- MD5_CTX md5_ctx = ssl->dc->md5_ctx;
- SHA1_CTX sha1_ctx = ssl->dc->sha1_ctx;
-
- if (label)
- {
- strcpy((char *)q, label);
- q += strlen(label);
- }
-
- MD5_Final(q, &md5_ctx);
- q += MD5_SIZE;
-
- SHA1_Final(q, &sha1_ctx);
- q += SHA1_SIZE;
-
- if (label)
- {
- prf(ssl->dc->master_secret, SSL_SECRET_SIZE, mac_buf, (int)(q-mac_buf),
- digest, SSL_FINISHED_HASH_SIZE);
- }
- else /* for use in a certificate verify */
- {
- memcpy(digest, mac_buf, MD5_SIZE + SHA1_SIZE);
- }
-
-#if 0
- printf("label: %s\n", label);
- print_blob("master secret", ssl->dc->master_secret, 48);
- print_blob("mac_buf", mac_buf, q-mac_buf);
- print_blob("finished digest", digest, SSL_FINISHED_HASH_SIZE);
-#endif
-}
-
-/**
- * Retrieve (and initialise) the context of a cipher.
- */
-static void *crypt_new(SSL *ssl, uint8_t *key, uint8_t *iv, int is_decrypt)
-{
- switch (ssl->cipher)
- {
-#ifndef CONFIG_SSL_SKELETON_MODE
- case SSL_AES128_SHA:
- {
- AES_CTX *aes_ctx = (AES_CTX *)malloc(sizeof(AES_CTX));
- AES_set_key(aes_ctx, key, iv, AES_MODE_128);
-
- if (is_decrypt)
- {
- AES_convert_key(aes_ctx);
- }
-
- return (void *)aes_ctx;
- }
-
- case SSL_AES256_SHA:
- {
- AES_CTX *aes_ctx = (AES_CTX *)malloc(sizeof(AES_CTX));
- AES_set_key(aes_ctx, key, iv, AES_MODE_256);
-
- if (is_decrypt)
- {
- AES_convert_key(aes_ctx);
- }
-
- return (void *)aes_ctx;
- }
-
- case SSL_RC4_128_MD5:
-#endif
- case SSL_RC4_128_SHA:
- {
- RC4_CTX *rc4_ctx = (RC4_CTX *)malloc(sizeof(RC4_CTX));
- RC4_setup(rc4_ctx, key, 16);
- return (void *)rc4_ctx;
- }
- }
-
- return NULL; /* its all gone wrong */
-}
-
-/**
- * Send a packet over the socket.
- */
-static int send_raw_packet(SSL *ssl, uint8_t protocol)
-{
- uint8_t *rec_buf = ssl->bm_all_data;
- int pkt_size = SSL_RECORD_SIZE+ssl->bm_index;
- int sent = 0;
- int ret = SSL_OK;
-
- rec_buf[0] = protocol;
- rec_buf[1] = 0x03; /* version = 3.1 or higher */
- rec_buf[2] = ssl->version & 0x0f;
- rec_buf[3] = ssl->bm_index >> 8;
- rec_buf[4] = ssl->bm_index & 0xff;
-
- DISPLAY_BYTES(ssl, "sending %d bytes", ssl->bm_all_data,
- pkt_size, pkt_size);
-
- while (sent < pkt_size)
- {
- ret = SOCKET_WRITE(ssl->client_fd,
- &ssl->bm_all_data[sent], pkt_size-sent);
-
- if (ret >= 0)
- sent += ret;
- else
- {
-
-#ifdef WIN32
- if (GetLastError() != WSAEWOULDBLOCK)
-#else
- if (errno != EAGAIN && errno != EWOULDBLOCK)
-#endif
- return SSL_ERROR_CONN_LOST;
- }
-
- /* keep going until the write buffer has some space */
- if (sent != pkt_size)
- {
- fd_set wfds;
- FD_ZERO(&wfds);
- FD_SET(ssl->client_fd, &wfds);
-
- /* block and wait for it */
- if (select(ssl->client_fd + 1, NULL, &wfds, NULL, NULL) < 0)
- return SSL_ERROR_CONN_LOST;
- }
- }
-
- SET_SSL_FLAG(SSL_NEED_RECORD); /* reset for next time */
- ssl->bm_index = 0;
-
- if (protocol != PT_APP_PROTOCOL_DATA)
- {
- /* always return SSL_OK during handshake */
- ret = SSL_OK;
- }
-
- return ret;
-}
-
-/**
- * Send an encrypted packet with padding bytes if necessary.
- */
-int send_packet(SSL *ssl, uint8_t protocol, const uint8_t *in, int length)
-{
- int ret, msg_length = 0;
-
- /* if our state is bad, don't bother */
- if (ssl->hs_status == SSL_ERROR_DEAD)
- return SSL_ERROR_CONN_LOST;
-
- if (in) /* has the buffer already been initialised? */
- {
- memcpy(ssl->bm_data, in, length);
- }
-
- msg_length += length;
-
- if (IS_SET_SSL_FLAG(SSL_TX_ENCRYPTED))
- {
- int mode = IS_SET_SSL_FLAG(SSL_IS_CLIENT) ?
- SSL_CLIENT_WRITE : SSL_SERVER_WRITE;
- uint8_t hmac_header[SSL_RECORD_SIZE] =
- {
- protocol,
- 0x03, /* version = 3.1 or higher */
- ssl->version & 0x0f,
- msg_length >> 8,
- msg_length & 0xff
- };
-
- if (protocol == PT_HANDSHAKE_PROTOCOL)
- {
- DISPLAY_STATE(ssl, 1, ssl->bm_data[0], 0);
-
- if (ssl->bm_data[0] != HS_HELLO_REQUEST)
- {
- add_packet(ssl, ssl->bm_data, msg_length);
- }
- }
-
- /* add the packet digest */
- add_hmac_digest(ssl, mode, hmac_header, ssl->bm_data, msg_length,
- &ssl->bm_data[msg_length]);
- msg_length += ssl->cipher_info->digest_size;
-
- /* add padding? */
- if (ssl->cipher_info->padding_size)
- {
- int last_blk_size = msg_length%ssl->cipher_info->padding_size;
- int pad_bytes = ssl->cipher_info->padding_size - last_blk_size;
-
- /* ensure we always have at least 1 padding byte */
- if (pad_bytes == 0)
- pad_bytes += ssl->cipher_info->padding_size;
-
- memset(&ssl->bm_data[msg_length], pad_bytes-1, pad_bytes);
- msg_length += pad_bytes;
- }
-
- DISPLAY_BYTES(ssl, "unencrypted write", ssl->bm_data, msg_length);
- increment_write_sequence(ssl);
-
- /* add the explicit IV for TLS1.1 */
- if (ssl->version >= SSL_PROTOCOL_VERSION1_1 &&
- ssl->cipher_info->iv_size)
-
- {
- uint8_t iv_size = ssl->cipher_info->iv_size;
- uint8_t *t_buf = alloca(msg_length + iv_size);
- memcpy(t_buf + iv_size, ssl->bm_data, msg_length);
- get_random(iv_size, t_buf);
- msg_length += iv_size;
- memcpy(ssl->bm_data, t_buf, msg_length);
- }
-
- /* now encrypt the packet */
- ssl->cipher_info->encrypt(ssl->encrypt_ctx, ssl->bm_data,
- ssl->bm_data, msg_length);
- }
- else if (protocol == PT_HANDSHAKE_PROTOCOL)
- {
- DISPLAY_STATE(ssl, 1, ssl->bm_data[0], 0);
-
- if (ssl->bm_data[0] != HS_HELLO_REQUEST)
- {
- add_packet(ssl, ssl->bm_data, length);
- }
- }
-
- ssl->bm_index = msg_length;
- if ((ret = send_raw_packet(ssl, protocol)) <= 0)
- return ret;
-
- return length; /* just return what we wanted to send */
-}
-
-/**
- * Work out the cipher keys we are going to use for this session based on the
- * master secret.
- */
-static int set_key_block(SSL *ssl, int is_write)
-{
- const cipher_info_t *ciph_info = get_cipher_info(ssl->cipher);
- uint8_t *q;
- uint8_t client_key[32], server_key[32]; /* big enough for AES256 */
- uint8_t client_iv[16], server_iv[16]; /* big enough for AES128/256 */
- int is_client = IS_SET_SSL_FLAG(SSL_IS_CLIENT);
-
- if (ciph_info == NULL)
- return -1;
-
- /* only do once in a handshake */
- if (ssl->dc->key_block == NULL)
- {
- ssl->dc->key_block = (uint8_t *)malloc(ciph_info->key_block_size);
-
-#if 0
- print_blob("client", ssl->dc->client_random, 32);
- print_blob("server", ssl->dc->server_random, 32);
- print_blob("master", ssl->dc->master_secret, SSL_SECRET_SIZE);
-#endif
- generate_key_block(ssl->dc->client_random, ssl->dc->server_random,
- ssl->dc->master_secret, ssl->dc->key_block,
- ciph_info->key_block_size);
-#if 0
- print_blob("keyblock", ssl->key_block, ciph_info->key_block_size);
-#endif
- }
-
- q = ssl->dc->key_block;
-
- if ((is_client && is_write) || (!is_client && !is_write))
- {
- memcpy(ssl->client_mac, q, ciph_info->digest_size);
- }
-
- q += ciph_info->digest_size;
-
- if ((!is_client && is_write) || (is_client && !is_write))
- {
- memcpy(ssl->server_mac, q, ciph_info->digest_size);
- }
-
- q += ciph_info->digest_size;
- memcpy(client_key, q, ciph_info->key_size);
- q += ciph_info->key_size;
- memcpy(server_key, q, ciph_info->key_size);
- q += ciph_info->key_size;
-
-#ifndef CONFIG_SSL_SKELETON_MODE
- if (ciph_info->iv_size) /* RC4 has no IV, AES does */
- {
- memcpy(client_iv, q, ciph_info->iv_size);
- q += ciph_info->iv_size;
- memcpy(server_iv, q, ciph_info->iv_size);
- q += ciph_info->iv_size;
- }
-#endif
-
- free(is_write ? ssl->encrypt_ctx : ssl->decrypt_ctx);
-
- /* now initialise the ciphers */
- if (is_client)
- {
- finished_digest(ssl, server_finished, ssl->dc->final_finish_mac);
-
- if (is_write)
- ssl->encrypt_ctx = crypt_new(ssl, client_key, client_iv, 0);
- else
- ssl->decrypt_ctx = crypt_new(ssl, server_key, server_iv, 1);
- }
- else
- {
- finished_digest(ssl, client_finished, ssl->dc->final_finish_mac);
-
- if (is_write)
- ssl->encrypt_ctx = crypt_new(ssl, server_key, server_iv, 0);
- else
- ssl->decrypt_ctx = crypt_new(ssl, client_key, client_iv, 1);
- }
-
- ssl->cipher_info = ciph_info;
- return 0;
-}
-
-/**
- * Read the SSL connection.
- */
-int basic_read(SSL *ssl, uint8_t **in_data)
-{
- int ret = SSL_OK;
- int read_len, is_client = IS_SET_SSL_FLAG(SSL_IS_CLIENT);
- uint8_t *buf = ssl->bm_data;
-
- read_len = SOCKET_READ(ssl->client_fd, &buf[ssl->bm_read_index],
- ssl->need_bytes-ssl->got_bytes);
-
- if (read_len < 0)
- {
-#ifdef WIN32
- if (GetLastError() == WSAEWOULDBLOCK)
-#else
- if (errno == EAGAIN || errno == EWOULDBLOCK)
-#endif
- return 0;
- }
-
- /* connection has gone, so die */
- if (read_len <= 0)
- {
- ret = SSL_ERROR_CONN_LOST;
- ssl->hs_status = SSL_ERROR_DEAD; /* make sure it stays dead */
- goto error;
- }
-
- DISPLAY_BYTES(ssl, "received %d bytes",
- &ssl->bm_data[ssl->bm_read_index], read_len, read_len);
-
- ssl->got_bytes += read_len;
- ssl->bm_read_index += read_len;
-
- /* haven't quite got what we want, so try again later */
- if (ssl->got_bytes < ssl->need_bytes)
- return SSL_OK;
-
- read_len = ssl->got_bytes;
- ssl->got_bytes = 0;
-
- if (IS_SET_SSL_FLAG(SSL_NEED_RECORD))
- {
- /* check for sslv2 "client hello" */
- if (buf[0] & 0x80 && buf[2] == 1)
- {
-#ifdef CONFIG_SSL_ENABLE_V23_HANDSHAKE
- uint8_t version = (buf[3] << 4) + buf[4];
- DISPLAY_BYTES(ssl, "ssl2 record", buf, 5);
-
- /* should be v3.1 (TLSv1) or better */
- ssl->version = ssl->client_version = version;
-
- if (version > SSL_PROTOCOL_VERSION_MAX)
- {
- /* use client's version */
- ssl->version = SSL_PROTOCOL_VERSION_MAX;
- }
- else if (version < SSL_PROTOCOL_MIN_VERSION)
- {
- ret = SSL_ERROR_INVALID_VERSION;
- ssl_display_error(ret);
- return ret;
- }
-
- add_packet(ssl, &buf[2], 3);
- ret = process_sslv23_client_hello(ssl);
-#else
- printf("Error: no SSLv23 handshaking allowed\n"); TTY_FLUSH();
- ret = SSL_ERROR_NOT_SUPPORTED;
-#endif
- goto error; /* not an error - just get out of here */
- }
-
- ssl->need_bytes = (buf[3] << 8) + buf[4];
-
- /* do we violate the spec with the message size? */
- if (ssl->need_bytes > RT_MAX_PLAIN_LENGTH+RT_EXTRA-BM_RECORD_OFFSET)
- {
- ret = SSL_ERROR_INVALID_PROT_MSG;
- goto error;
- }
-
- CLR_SSL_FLAG(SSL_NEED_RECORD);
- memcpy(ssl->hmac_header, buf, 3); /* store for hmac */
- ssl->record_type = buf[0];
- goto error; /* no error, we're done */
- }
-
- /* for next time - just do it now in case of an error */
- SET_SSL_FLAG(SSL_NEED_RECORD);
- ssl->need_bytes = SSL_RECORD_SIZE;
-
- /* decrypt if we need to */
- if (IS_SET_SSL_FLAG(SSL_RX_ENCRYPTED))
- {
- ssl->cipher_info->decrypt(ssl->decrypt_ctx, buf, buf, read_len);
-
- if (ssl->version >= SSL_PROTOCOL_VERSION1_1 &&
- ssl->cipher_info->iv_size)
- {
- buf += ssl->cipher_info->iv_size;
- read_len -= ssl->cipher_info->iv_size;
- }
-
- read_len = verify_digest(ssl,
- is_client ? SSL_CLIENT_READ : SSL_SERVER_READ, buf, read_len);
-
- /* does the hmac work? */
- if (read_len < 0)
- {
- ret = read_len;
- goto error;
- }
-
- DISPLAY_BYTES(ssl, "decrypted", buf, read_len);
- increment_read_sequence(ssl);
- }
-
- /* The main part of the SSL packet */
- switch (ssl->record_type)
- {
- case PT_HANDSHAKE_PROTOCOL:
- if (ssl->dc != NULL)
- {
- ssl->dc->bm_proc_index = 0;
- ret = do_handshake(ssl, buf, read_len);
- }
- else /* no client renegotiation allowed */
- {
- ret = SSL_ERROR_NO_CLIENT_RENOG;
- goto error;
- }
- break;
-
- case PT_CHANGE_CIPHER_SPEC:
- if (ssl->next_state != HS_FINISHED)
- {
- ret = SSL_ERROR_INVALID_HANDSHAKE;
- goto error;
- }
-
- /* all encrypted from now on */
- SET_SSL_FLAG(SSL_RX_ENCRYPTED);
- if (set_key_block(ssl, 0) < 0)
- {
- ret = SSL_ERROR_INVALID_HANDSHAKE;
- goto error;
- }
-
- memset(ssl->read_sequence, 0, 8);
- break;
-
- case PT_APP_PROTOCOL_DATA:
- if (in_data)
- {
- *in_data = buf; /* point to the work buffer */
- (*in_data)[read_len] = 0; /* null terminate just in case */
- }
-
- ret = read_len;
- break;
-
- case PT_ALERT_PROTOCOL:
- /* return the alert # with alert bit set */
- if(buf[0] == SSL_ALERT_TYPE_WARNING &&
- buf[1] == SSL_ALERT_CLOSE_NOTIFY)
- {
- ret = SSL_CLOSE_NOTIFY;
- send_alert(ssl, SSL_ALERT_CLOSE_NOTIFY);
- SET_SSL_FLAG(SSL_SENT_CLOSE_NOTIFY);
- }
- else
- {
- ret = -buf[1];
- DISPLAY_ALERT(ssl, buf[1]);
- }
-
- break;
-
- default:
- ret = SSL_ERROR_INVALID_PROT_MSG;
- break;
- }
-
-error:
- ssl->bm_read_index = 0; /* reset to go again */
-
- if (ret < SSL_OK && in_data)/* if all wrong, then clear this buffer ptr */
- *in_data = NULL;
-
- return ret;
-}
-
-/**
- * Do some basic checking of data and then perform the appropriate handshaking.
- */
-static int do_handshake(SSL *ssl, uint8_t *buf, int read_len)
-{
- int hs_len = (buf[2]<<8) + buf[3];
- uint8_t handshake_type = buf[0];
- int ret = SSL_OK;
- int is_client = IS_SET_SSL_FLAG(SSL_IS_CLIENT);
-
- /* some integrity checking on the handshake */
- PARANOIA_CHECK(read_len-SSL_HS_HDR_SIZE, hs_len);
-
- if (handshake_type != ssl->next_state)
- {
- /* handle a special case on the client */
- if (!is_client || handshake_type != HS_CERT_REQ ||
- ssl->next_state != HS_SERVER_HELLO_DONE)
- {
- ret = SSL_ERROR_INVALID_HANDSHAKE;
- goto error;
- }
- }
-
- hs_len += SSL_HS_HDR_SIZE; /* adjust for when adding packets */
- ssl->bm_index = hs_len; /* store the size and check later */
- DISPLAY_STATE(ssl, 0, handshake_type, 0);
-
- if (handshake_type != HS_CERT_VERIFY && handshake_type != HS_HELLO_REQUEST)
- add_packet(ssl, buf, hs_len);
-
-#if defined(CONFIG_SSL_ENABLE_CLIENT)
- ret = is_client ?
- do_clnt_handshake(ssl, handshake_type, buf, hs_len) :
- do_svr_handshake(ssl, handshake_type, buf, hs_len);
-#else
- ret = do_svr_handshake(ssl, handshake_type, buf, hs_len);
-#endif
-
- /* just use recursion to get the rest */
- if (hs_len < read_len && ret == SSL_OK)
- ret = do_handshake(ssl, &buf[hs_len], read_len-hs_len);
-
-error:
- return ret;
-}
-
-/**
- * Sends the change cipher spec message. We have just read a finished message
- * from the client.
- */
-int send_change_cipher_spec(SSL *ssl)
-{
- int ret = send_packet(ssl, PT_CHANGE_CIPHER_SPEC,
- g_chg_cipher_spec_pkt, sizeof(g_chg_cipher_spec_pkt));
- SET_SSL_FLAG(SSL_TX_ENCRYPTED);
-
- if (ret >= 0 && set_key_block(ssl, 1) < 0)
- ret = SSL_ERROR_INVALID_HANDSHAKE;
-
- memset(ssl->write_sequence, 0, 8);
- return ret;
-}
-
-/**
- * Send a "finished" message
- */
-int send_finished(SSL *ssl)
-{
- uint8_t buf[SSL_FINISHED_HASH_SIZE+4] = {
- HS_FINISHED, 0, 0, SSL_FINISHED_HASH_SIZE };
-
- /* now add the finished digest mac (12 bytes) */
- finished_digest(ssl,
- IS_SET_SSL_FLAG(SSL_IS_CLIENT) ?
- client_finished : server_finished, &buf[4]);
-
-#ifndef CONFIG_SSL_SKELETON_MODE
- /* store in the session cache */
- if (!IS_SET_SSL_FLAG(SSL_SESSION_RESUME) && ssl->ssl_ctx->num_sessions)
- {
- memcpy(ssl->session->master_secret,
- ssl->dc->master_secret, SSL_SECRET_SIZE);
- }
-#endif
-
- return send_packet(ssl, PT_HANDSHAKE_PROTOCOL,
- buf, SSL_FINISHED_HASH_SIZE+4);
-}
-
-/**
- * Send an alert message.
- * Return 1 if the alert was an "error".
- */
-int send_alert(SSL *ssl, int error_code)
-{
- int alert_num = 0;
- int is_warning = 0;
- uint8_t buf[2];
-
- /* Don't bother we're already dead */
- if (ssl->hs_status == SSL_ERROR_DEAD)
- {
- return SSL_ERROR_CONN_LOST;
- }
-
-#ifdef CONFIG_SSL_FULL_MODE
- if (IS_SET_SSL_FLAG(SSL_DISPLAY_STATES))
- ssl_display_error(error_code);
-#endif
-
- switch (error_code)
- {
- case SSL_ALERT_CLOSE_NOTIFY:
- is_warning = 1;
- alert_num = SSL_ALERT_CLOSE_NOTIFY;
- break;
-
- case SSL_ERROR_CONN_LOST: /* don't send alert just yet */
- is_warning = 1;
- break;
-
- case SSL_ERROR_INVALID_HANDSHAKE:
- case SSL_ERROR_INVALID_PROT_MSG:
- alert_num = SSL_ALERT_HANDSHAKE_FAILURE;
- break;
-
- case SSL_ERROR_INVALID_HMAC:
- case SSL_ERROR_FINISHED_INVALID:
- alert_num = SSL_ALERT_BAD_RECORD_MAC;
- break;
-
- case SSL_ERROR_INVALID_VERSION:
- alert_num = SSL_ALERT_INVALID_VERSION;
- break;
-
- case SSL_ERROR_INVALID_SESSION:
- case SSL_ERROR_NO_CIPHER:
- case SSL_ERROR_INVALID_KEY:
- alert_num = SSL_ALERT_ILLEGAL_PARAMETER;
- break;
-
- case SSL_ERROR_BAD_CERTIFICATE:
- alert_num = SSL_ALERT_BAD_CERTIFICATE;
- break;
-
- case SSL_ERROR_NO_CLIENT_RENOG:
- alert_num = SSL_ALERT_NO_RENEGOTIATION;
- break;
-
- default:
- /* a catch-all for any badly verified certificates */
- alert_num = (error_code <= SSL_X509_OFFSET) ?
- SSL_ALERT_BAD_CERTIFICATE : SSL_ALERT_UNEXPECTED_MESSAGE;
- break;
- }
-
- buf[0] = is_warning ? 1 : 2;
- buf[1] = alert_num;
- send_packet(ssl, PT_ALERT_PROTOCOL, buf, sizeof(buf));
- DISPLAY_ALERT(ssl, alert_num);
- return is_warning ? 0 : 1;
-}
-
-/**
- * Process a client finished message.
- */
-int process_finished(SSL *ssl, uint8_t *buf, int hs_len)
-{
- int ret = SSL_OK;
- int is_client = IS_SET_SSL_FLAG(SSL_IS_CLIENT);
- int resume = IS_SET_SSL_FLAG(SSL_SESSION_RESUME);
-
- PARANOIA_CHECK(ssl->bm_index, SSL_FINISHED_HASH_SIZE+4);
-
- /* check that we all work before we continue */
- if (memcmp(ssl->dc->final_finish_mac, &buf[4], SSL_FINISHED_HASH_SIZE))
- return SSL_ERROR_FINISHED_INVALID;
-
- if ((!is_client && !resume) || (is_client && resume))
- {
- if ((ret = send_change_cipher_spec(ssl)) == SSL_OK)
- ret = send_finished(ssl);
- }
-
- /* if we ever renegotiate */
- ssl->next_state = is_client ? HS_HELLO_REQUEST : HS_CLIENT_HELLO;
- ssl->hs_status = ret; /* set the final handshake status */
-
-error:
- return ret;
-}
-
-/**
- * Send a certificate.
- */
-int send_certificate(SSL *ssl)
-{
- int i = 0;
- uint8_t *buf = ssl->bm_data;
- int offset = 7;
- int chain_length;
-
- buf[0] = HS_CERTIFICATE;
- buf[1] = 0;
- buf[4] = 0;
-
- while (i < ssl->ssl_ctx->chain_length)
- {
- SSL_CERT *cert = &ssl->ssl_ctx->certs[i];
- buf[offset++] = 0;
- buf[offset++] = cert->size >> 8; /* cert 1 length */
- buf[offset++] = cert->size & 0xff;
- memcpy(&buf[offset], cert->buf, cert->size);
- offset += cert->size;
- i++;
- }
-
- chain_length = offset - 7;
- buf[5] = chain_length >> 8; /* cert chain length */
- buf[6] = chain_length & 0xff;
- chain_length += 3;
- buf[2] = chain_length >> 8; /* handshake length */
- buf[3] = chain_length & 0xff;
- ssl->bm_index = offset;
- return send_packet(ssl, PT_HANDSHAKE_PROTOCOL, NULL, offset);
-}
-
-/**
- * Create a blob of memory that we'll get rid of once the handshake is
- * complete.
- */
-void disposable_new(SSL *ssl)
-{
- if (ssl->dc == NULL)
- {
- ssl->dc = (DISPOSABLE_CTX *)calloc(1, sizeof(DISPOSABLE_CTX));
- MD5_Init(&ssl->dc->md5_ctx);
- SHA1_Init(&ssl->dc->sha1_ctx);
- }
-}
-
-/**
- * Remove the temporary blob of memory.
- */
-void disposable_free(SSL *ssl)
-{
- if (ssl->dc)
- {
- free(ssl->dc->key_block);
- memset(ssl->dc, 0, sizeof(DISPOSABLE_CTX));
- free(ssl->dc);
- ssl->dc = NULL;
- }
-
-}
-
-#ifndef CONFIG_SSL_SKELETON_MODE /* no session resumption in this mode */
-/**
- * Find if an existing session has the same session id. If so, use the
- * master secret from this session for session resumption.
- */
-SSL_SESSION *ssl_session_update(int max_sessions, SSL_SESSION *ssl_sessions[],
- SSL *ssl, const uint8_t *session_id)
-{
- time_t tm = time(NULL);
- time_t oldest_sess_time = tm;
- SSL_SESSION *oldest_sess = NULL;
- int i;
-
- /* no sessions? Then bail */
- if (max_sessions == 0)
- return NULL;
-
- SSL_CTX_LOCK(ssl->ssl_ctx->mutex);
- if (session_id)
- {
- for (i = 0; i < max_sessions; i++)
- {
- if (ssl_sessions[i])
- {
- /* kill off any expired sessions */
- if (tm > ssl_sessions[i]->conn_time + SSL_EXPIRY_TIME)
- {
- session_free(ssl_sessions, i);
- continue;
- }
-
- /* if the session id matches, it must still be less than
- the expiry time */
- if (memcmp(ssl_sessions[i]->session_id, session_id,
- SSL_SESSION_ID_SIZE) == 0)
- {
- ssl->session_index = i;
- memcpy(ssl->dc->master_secret,
- ssl_sessions[i]->master_secret, SSL_SECRET_SIZE);
- SET_SSL_FLAG(SSL_SESSION_RESUME);
- SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex);
- return ssl_sessions[i]; /* a session was found */
- }
- }
- }
- }
-
- /* If we've got here, no matching session was found - so create one */
- for (i = 0; i < max_sessions; i++)
- {
- if (ssl_sessions[i] == NULL)
- {
- /* perfect, this will do */
- ssl_sessions[i] = (SSL_SESSION *)calloc(1, sizeof(SSL_SESSION));
- ssl_sessions[i]->conn_time = tm;
- ssl->session_index = i;
- SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex);
- return ssl_sessions[i]; /* return the session object */
- }
- else if (ssl_sessions[i]->conn_time <= oldest_sess_time)
- {
- /* find the oldest session */
- oldest_sess_time = ssl_sessions[i]->conn_time;
- oldest_sess = ssl_sessions[i];
- ssl->session_index = i;
- }
- }
-
- /* ok, we've used up all of our sessions. So blow the oldest session away */
- if (oldest_sess != NULL)
- {
- oldest_sess->conn_time = tm;
- memset(oldest_sess->session_id, 0, sizeof(SSL_SESSION_ID_SIZE));
- memset(oldest_sess->master_secret, 0, sizeof(SSL_SECRET_SIZE));
- }
-
- SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex);
- return oldest_sess;
-}
-
-/**
- * Free an existing session.
- */
-static void session_free(SSL_SESSION *ssl_sessions[], int sess_index)
-{
- if (ssl_sessions[sess_index])
- {
- free(ssl_sessions[sess_index]);
- ssl_sessions[sess_index] = NULL;
- }
-}
-
-/**
- * This ssl object doesn't want this session anymore.
- */
-void kill_ssl_session(SSL_SESSION **ssl_sessions, SSL *ssl)
-{
- SSL_CTX_LOCK(ssl->ssl_ctx->mutex);
-
- if (ssl->ssl_ctx->num_sessions)
- {
- session_free(ssl_sessions, ssl->session_index);
- ssl->session = NULL;
- }
-
- SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex);
-}
-#endif /* CONFIG_SSL_SKELETON_MODE */
-
-/*
- * Get the session id for a handshake. This will be a 32 byte sequence.
- */
-EXP_FUNC const uint8_t * STDCALL ssl_get_session_id(const SSL *ssl)
-{
- return ssl->session_id;
-}
-
-/*
- * Get the session id size for a handshake.
- */
-EXP_FUNC uint8_t STDCALL ssl_get_session_id_size(const SSL *ssl)
-{
- return ssl->sess_id_size;
-}
-
-/*
- * Return the cipher id (in the SSL form).
- */
-EXP_FUNC uint8_t STDCALL ssl_get_cipher_id(const SSL *ssl)
-{
- return ssl->cipher;
-}
-
-/*
- * Return the status of the handshake.
- */
-EXP_FUNC int STDCALL ssl_handshake_status(const SSL *ssl)
-{
- return ssl->hs_status;
-}
-
-/*
- * Retrieve various parameters about the SSL engine.
- */
-EXP_FUNC int STDCALL ssl_get_config(int offset)
-{
- switch (offset)
- {
- /* return the appropriate build mode */
- case SSL_BUILD_MODE:
-#if defined(CONFIG_SSL_FULL_MODE)
- return SSL_BUILD_FULL_MODE;
-#elif defined(CONFIG_SSL_ENABLE_CLIENT)
- return SSL_BUILD_ENABLE_CLIENT;
-#elif defined(CONFIG_ENABLE_VERIFICATION)
- return SSL_BUILD_ENABLE_VERIFICATION;
-#elif defined(CONFIG_SSL_SERVER_ONLY )
- return SSL_BUILD_SERVER_ONLY;
-#else
- return SSL_BUILD_SKELETON_MODE;
-#endif
-
- case SSL_MAX_CERT_CFG_OFFSET:
- return CONFIG_SSL_MAX_CERTS;
-
-#ifdef CONFIG_SSL_CERT_VERIFICATION
- case SSL_MAX_CA_CERT_CFG_OFFSET:
- return CONFIG_X509_MAX_CA_CERTS;
-#endif
-#ifdef CONFIG_SSL_HAS_PEM
- case SSL_HAS_PEM:
- return 1;
-#endif
- default:
- return 0;
- }
-}
-
-#ifdef CONFIG_SSL_CERT_VERIFICATION
-/**
- * Authenticate a received certificate.
- */
-EXP_FUNC int STDCALL ssl_verify_cert(const SSL *ssl)
-{
- int ret;
- SSL_CTX_LOCK(ssl->ssl_ctx->mutex);
- ret = x509_verify(ssl->ssl_ctx->ca_cert_ctx, ssl->x509_ctx);
- SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex);
-
- if (ret) /* modify into an SSL error type */
- {
- ret = SSL_X509_ERROR(ret);
- }
-
- return ret;
-}
-
-/**
- * Process a certificate message.
- */
-int process_certificate(SSL *ssl, X509_CTX **x509_ctx)
-{
- int ret = SSL_OK;
- uint8_t *buf = &ssl->bm_data[ssl->dc->bm_proc_index];
- int pkt_size = ssl->bm_index;
- int cert_size, offset = 5;
- int total_cert_size = (buf[offset]<<8) + buf[offset+1];
- int is_client = IS_SET_SSL_FLAG(SSL_IS_CLIENT);
- X509_CTX **chain = x509_ctx;
- offset += 2;
-
- PARANOIA_CHECK(total_cert_size, offset);
-
- while (offset < total_cert_size)
- {
- offset++; /* skip empty char */
- cert_size = (buf[offset]<<8) + buf[offset+1];
- offset += 2;
-
- if (x509_new(&buf[offset], NULL, chain))
- {
- ret = SSL_ERROR_BAD_CERTIFICATE;
- goto error;
- }
-
- chain = &((*chain)->next);
- offset += cert_size;
- }
-
- PARANOIA_CHECK(pkt_size, offset);
-
- /* if we are client we can do the verify now or later */
- if (is_client && !IS_SET_SSL_FLAG(SSL_SERVER_VERIFY_LATER))
- {
- ret = ssl_verify_cert(ssl);
- }
-
- ssl->next_state = is_client ? HS_SERVER_HELLO_DONE : HS_CLIENT_KEY_XCHG;
- ssl->dc->bm_proc_index += offset;
-error:
- return ret;
-}
-
-#endif /* CONFIG_SSL_CERT_VERIFICATION */
-
-/**
- * Debugging routine to display SSL handshaking stuff.
- */
-#ifdef CONFIG_SSL_FULL_MODE
-/**
- * Debugging routine to display SSL states.
- */
-void DISPLAY_STATE(SSL *ssl, int is_send, uint8_t state, int not_ok)
-{
- const char *str;
-
- if (!IS_SET_SSL_FLAG(SSL_DISPLAY_STATES))
- return;
-
- printf(not_ok ? "Error - invalid State:\t" : "State:\t");
- printf(is_send ? "sending " : "receiving ");
-
- switch (state)
- {
- case HS_HELLO_REQUEST:
- str = "Hello Request (0)";
- break;
-
- case HS_CLIENT_HELLO:
- str = "Client Hello (1)";
- break;
-
- case HS_SERVER_HELLO:
- str = "Server Hello (2)";
- break;
-
- case HS_CERTIFICATE:
- str = "Certificate (11)";
- break;
-
- case HS_SERVER_KEY_XCHG:
- str = "Certificate Request (12)";
- break;
-
- case HS_CERT_REQ:
- str = "Certificate Request (13)";
- break;
-
- case HS_SERVER_HELLO_DONE:
- str = "Server Hello Done (14)";
- break;
-
- case HS_CERT_VERIFY:
- str = "Certificate Verify (15)";
- break;
-
- case HS_CLIENT_KEY_XCHG:
- str = "Client Key Exchange (16)";
- break;
-
- case HS_FINISHED:
- str = "Finished (16)";
- break;
-
- default:
- str = "Error (Unknown)";
-
- break;
- }
-
- printf("%s\n", str);
- TTY_FLUSH();
-}
-
-/**
- * Debugging routine to display RSA objects
- */
-void DISPLAY_RSA(SSL *ssl, const RSA_CTX *rsa_ctx)
-{
- if (!IS_SET_SSL_FLAG(SSL_DISPLAY_RSA))
- return;
-
- RSA_print(rsa_ctx);
- TTY_FLUSH();
-}
-
-/**
- * Debugging routine to display SSL handshaking bytes.
- */
-void DISPLAY_BYTES(SSL *ssl, const char *format,
- const uint8_t *data, int size, ...)
-{
- va_list(ap);
-
- if (!IS_SET_SSL_FLAG(SSL_DISPLAY_BYTES))
- return;
-
- va_start(ap, size);
- print_blob(format, data, size, va_arg(ap, char *));
- va_end(ap);
- TTY_FLUSH();
-}
-
-/**
- * Debugging routine to display SSL handshaking errors.
- */
-EXP_FUNC void STDCALL ssl_display_error(int error_code)
-{
- if (error_code == SSL_OK)
- return;
-
- printf("Error: ");
-
- /* X509 error? */
- if (error_code < SSL_X509_OFFSET)
- {
- printf("%s\n", x509_display_error(error_code - SSL_X509_OFFSET));
- return;
- }
-
- /* SSL alert error code */
- if (error_code > SSL_ERROR_CONN_LOST)
- {
- printf("SSL error %d\n", -error_code);
- return;
- }
-
- switch (error_code)
- {
- case SSL_ERROR_DEAD:
- printf("connection dead");
- break;
-
- case SSL_ERROR_INVALID_HANDSHAKE:
- printf("invalid handshake");
- break;
-
- case SSL_ERROR_INVALID_PROT_MSG:
- printf("invalid protocol message");
- break;
-
- case SSL_ERROR_INVALID_HMAC:
- printf("invalid mac");
- break;
-
- case SSL_ERROR_INVALID_VERSION:
- printf("invalid version");
- break;
-
- case SSL_ERROR_INVALID_SESSION:
- printf("invalid session");
- break;
-
- case SSL_ERROR_NO_CIPHER:
- printf("no cipher");
- break;
-
- case SSL_ERROR_CONN_LOST:
- printf("connection lost");
- break;
-
- case SSL_ERROR_BAD_CERTIFICATE:
- printf("bad certificate");
- break;
-
- case SSL_ERROR_INVALID_KEY:
- printf("invalid key");
- break;
-
- case SSL_ERROR_FINISHED_INVALID:
- printf("finished invalid");
- break;
-
- case SSL_ERROR_NO_CERT_DEFINED:
- printf("no certificate defined");
- break;
-
- case SSL_ERROR_NO_CLIENT_RENOG:
- printf("client renegotiation not supported");
- break;
-
- case SSL_ERROR_NOT_SUPPORTED:
- printf("Option not supported");
- break;
-
- default:
- printf("undefined as yet - %d", error_code);
- break;
- }
-
- printf("\n");
- TTY_FLUSH();
-}
-
-/**
- * Debugging routine to display alerts.
- */
-void DISPLAY_ALERT(SSL *ssl, int alert)
-{
- if (!IS_SET_SSL_FLAG(SSL_DISPLAY_STATES))
- return;
-
- printf("Alert: ");
-
- switch (alert)
- {
- case SSL_ALERT_CLOSE_NOTIFY:
- printf("close notify");
- break;
-
- case SSL_ALERT_INVALID_VERSION:
- printf("invalid version");
- break;
-
- case SSL_ALERT_BAD_CERTIFICATE:
- printf("bad certificate");
- break;
-
- case SSL_ALERT_UNEXPECTED_MESSAGE:
- printf("unexpected message");
- break;
-
- case SSL_ALERT_BAD_RECORD_MAC:
- printf("bad record mac");
- break;
-
- case SSL_ALERT_HANDSHAKE_FAILURE:
- printf("handshake failure");
- break;
-
- case SSL_ALERT_ILLEGAL_PARAMETER:
- printf("illegal parameter");
- break;
-
- case SSL_ALERT_DECODE_ERROR:
- printf("decode error");
- break;
-
- case SSL_ALERT_DECRYPT_ERROR:
- printf("decrypt error");
- break;
-
- case SSL_ALERT_NO_RENEGOTIATION:
- printf("no renegotiation");
- break;
-
- default:
- printf("alert - (unknown %d)", alert);
- break;
- }
-
- printf("\n");
- TTY_FLUSH();
-}
-
-#endif /* CONFIG_SSL_FULL_MODE */
-
-/**
- * Return the version of this library.
- */
-EXP_FUNC const char * STDCALL ssl_version()
-{
- static const char * axtls_version = AXTLS_VERSION;
- return axtls_version;
-}
-
-/**
- * Enable the various language bindings to work regardless of the
- * configuration - they just return an error statement and a bad return code.
- */
-#if !defined(CONFIG_SSL_FULL_MODE)
-EXP_FUNC void STDCALL ssl_display_error(int error_code) {}
-#endif
-
-#ifdef CONFIG_BINDINGS
-#if !defined(CONFIG_SSL_ENABLE_CLIENT)
-EXP_FUNC SSL * STDCALL ssl_client_new(SSL_CTX *ssl_ctx, int client_fd, const
- uint8_t *session_id, uint8_t sess_id_size)
-{
- printf(unsupported_str);
- return NULL;
-}
-#endif
-
-#if !defined(CONFIG_SSL_CERT_VERIFICATION)
-EXP_FUNC int STDCALL ssl_verify_cert(const SSL *ssl)
-{
- printf(unsupported_str);
- return -1;
-}
-
-
-EXP_FUNC const char * STDCALL ssl_get_cert_dn(const SSL *ssl, int component)
-{
- printf(unsupported_str);
- return NULL;
-}
-
-EXP_FUNC const char * STDCALL ssl_get_cert_subject_alt_dnsname(const SSL *ssl, int index)
-{
- printf(unsupported_str);
- return NULL;
-}
-
-#endif /* CONFIG_SSL_CERT_VERIFICATION */
-
-#endif /* CONFIG_BINDINGS */
-
diff --git a/axTLS/src/ssl/tls1.h b/axTLS/src/ssl/tls1.h
deleted file mode 100644
index e73bc1a..0000000
--- a/axTLS/src/ssl/tls1.h
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * Copyright (c) 2007, Cameron Rich
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * * Neither the name of the axTLS project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @file tls1.h
- *
- * @brief The definitions for the TLS library.
- */
-#ifndef HEADER_SSL_LIB_H
-#define HEADER_SSL_LIB_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "version.h"
-#include "crypto.h"
-#include "crypto_misc.h"
-
-#define SSL_PROTOCOL_MIN_VERSION 0x31 /* TLS v1.0 */
-#define SSL_PROTOCOL_MINOR_VERSION 0x02 /* TLS v1.1 */
-#define SSL_PROTOCOL_VERSION_MAX 0x32 /* TLS v1.1 */
-#define SSL_PROTOCOL_VERSION1_1 0x32 /* TLS v1.1 */
-#define SSL_RANDOM_SIZE 32
-#define SSL_SECRET_SIZE 48
-#define SSL_FINISHED_HASH_SIZE 12
-#define SSL_RECORD_SIZE 5
-#define SSL_SERVER_READ 0
-#define SSL_SERVER_WRITE 1
-#define SSL_CLIENT_READ 2
-#define SSL_CLIENT_WRITE 3
-#define SSL_HS_HDR_SIZE 4
-
-/* the flags we use while establishing a connection */
-#define SSL_NEED_RECORD 0x0001
-#define SSL_TX_ENCRYPTED 0x0002
-#define SSL_RX_ENCRYPTED 0x0004
-#define SSL_SESSION_RESUME 0x0008
-#define SSL_IS_CLIENT 0x0010
-#define SSL_HAS_CERT_REQ 0x0020
-#define SSL_SENT_CLOSE_NOTIFY 0x0040
-
-/* some macros to muck around with flag bits */
-#define SET_SSL_FLAG(A) (ssl->flag |= A)
-#define CLR_SSL_FLAG(A) (ssl->flag &= ~A)
-#define IS_SET_SSL_FLAG(A) (ssl->flag & A)
-
-#define MAX_KEY_BYTE_SIZE 512 /* for a 4096 bit key */
-#define RT_MAX_PLAIN_LENGTH 16384
-#define RT_EXTRA 1024
-#define BM_RECORD_OFFSET 5
-
-#ifdef CONFIG_SSL_SKELETON_MODE
-#define NUM_PROTOCOLS 1
-#else
-#define NUM_PROTOCOLS 4
-#endif
-
-#define PARANOIA_CHECK(A, B) if (A < B) { \
- ret = SSL_ERROR_INVALID_HANDSHAKE; goto error; }
-
-/* protocol types */
-enum
-{
- PT_CHANGE_CIPHER_SPEC = 20,
- PT_ALERT_PROTOCOL,
- PT_HANDSHAKE_PROTOCOL,
- PT_APP_PROTOCOL_DATA
-};
-
-/* handshaking types */
-enum
-{
- HS_HELLO_REQUEST,
- HS_CLIENT_HELLO,
- HS_SERVER_HELLO,
- HS_CERTIFICATE = 11,
- HS_SERVER_KEY_XCHG,
- HS_CERT_REQ,
- HS_SERVER_HELLO_DONE,
- HS_CERT_VERIFY,
- HS_CLIENT_KEY_XCHG,
- HS_FINISHED = 20
-};
-
-typedef struct
-{
- uint8_t cipher;
- uint8_t key_size;
- uint8_t iv_size;
- uint8_t key_block_size;
- uint8_t padding_size;
- uint8_t digest_size;
- hmac_func hmac;
- crypt_func encrypt;
- crypt_func decrypt;
-} cipher_info_t;
-
-struct _SSLObjLoader
-{
- uint8_t *buf;
- int len;
-};
-
-typedef struct _SSLObjLoader SSLObjLoader;
-
-typedef struct
-{
- time_t conn_time;
- uint8_t session_id[SSL_SESSION_ID_SIZE];
- uint8_t master_secret[SSL_SECRET_SIZE];
-} SSL_SESSION;
-
-typedef struct
-{
- uint8_t *buf;
- int size;
-} SSL_CERT;
-
-typedef struct
-{
- MD5_CTX md5_ctx;
- SHA1_CTX sha1_ctx;
- uint8_t final_finish_mac[SSL_FINISHED_HASH_SIZE];
- uint8_t *key_block;
- uint8_t master_secret[SSL_SECRET_SIZE];
- uint8_t client_random[SSL_RANDOM_SIZE]; /* client's random sequence */
- uint8_t server_random[SSL_RANDOM_SIZE]; /* server's random sequence */
- uint16_t bm_proc_index;
-} DISPOSABLE_CTX;
-
-struct _SSL
-{
- uint32_t flag;
- uint16_t need_bytes;
- uint16_t got_bytes;
- uint8_t record_type;
- uint8_t cipher;
- uint8_t sess_id_size;
- uint8_t version;
- uint8_t client_version;
- int16_t next_state;
- int16_t hs_status;
- DISPOSABLE_CTX *dc; /* temporary data which we'll get rid of soon */
- int client_fd;
- const cipher_info_t *cipher_info;
- void *encrypt_ctx;
- void *decrypt_ctx;
- uint8_t bm_all_data[RT_MAX_PLAIN_LENGTH+RT_EXTRA];
- uint8_t *bm_data;
- uint16_t bm_index;
- 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 */
-#ifndef CONFIG_SSL_SKELETON_MODE
- uint16_t session_index;
- SSL_SESSION *session;
-#endif
-#ifdef CONFIG_SSL_CERT_VERIFICATION
- X509_CTX *x509_ctx;
-#endif
-
- uint8_t session_id[SSL_SESSION_ID_SIZE];
- uint8_t client_mac[SHA1_SIZE]; /* for HMAC verification */
- uint8_t server_mac[SHA1_SIZE]; /* for HMAC verification */
- uint8_t read_sequence[8]; /* 64 bit sequence number */
- uint8_t write_sequence[8]; /* 64 bit sequence number */
- uint8_t hmac_header[SSL_RECORD_SIZE]; /* rx hmac */
-};
-
-typedef struct _SSL SSL;
-
-struct _SSL_CTX
-{
- uint32_t options;
- uint8_t chain_length;
- RSA_CTX *rsa_ctx;
-#ifdef CONFIG_SSL_CERT_VERIFICATION
- CA_CERT_CTX *ca_cert_ctx;
-#endif
- SSL *head;
- SSL *tail;
- SSL_CERT certs[CONFIG_SSL_MAX_CERTS];
-#ifndef CONFIG_SSL_SKELETON_MODE
- uint16_t num_sessions;
- SSL_SESSION **ssl_sessions;
-#endif
-#ifdef CONFIG_SSL_CTX_MUTEXING
- SSL_CTX_MUTEX_TYPE mutex;
-#endif
-#ifdef CONFIG_OPENSSL_COMPATIBLE
- void *bonus_attr;
-#endif
-};
-
-typedef struct _SSL_CTX SSL_CTX;
-
-/* backwards compatibility */
-typedef struct _SSL_CTX SSLCTX;
-
-extern const uint8_t ssl_prot_prefs[NUM_PROTOCOLS];
-
-SSL *ssl_new(SSL_CTX *ssl_ctx, int client_fd);
-void disposable_new(SSL *ssl);
-void disposable_free(SSL *ssl);
-int send_packet(SSL *ssl, uint8_t protocol,
- const uint8_t *in, int length);
-int do_svr_handshake(SSL *ssl, int handshake_type, uint8_t *buf, int hs_len);
-int do_clnt_handshake(SSL *ssl, int handshake_type, uint8_t *buf, int hs_len);
-int process_finished(SSL *ssl, uint8_t *buf, int hs_len);
-int process_sslv23_client_hello(SSL *ssl);
-int send_alert(SSL *ssl, int error_code);
-int send_finished(SSL *ssl);
-int send_certificate(SSL *ssl);
-int basic_read(SSL *ssl, uint8_t **in_data);
-int send_change_cipher_spec(SSL *ssl);
-void finished_digest(SSL *ssl, const char *label, uint8_t *digest);
-void generate_master_secret(SSL *ssl, const uint8_t *premaster_secret);
-void add_packet(SSL *ssl, const uint8_t *pkt, int len);
-int add_cert(SSL_CTX *ssl_ctx, const uint8_t *buf, int len);
-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);
-#endif
-#ifdef CONFIG_SSL_ENABLE_CLIENT
-int do_client_connect(SSL *ssl);
-#endif
-
-#ifdef CONFIG_SSL_FULL_MODE
-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 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)
-#define DISPLAY_CERT(A,B)
-#define DISPLAY_RSA(A,B)
-#define DISPLAY_ALERT(A, B)
-#ifdef WIN32
-void DISPLAY_BYTES(SSL *ssl, const char *format,/* win32 has no variadic macros */
- const uint8_t *data, int size, ...);
-#else
-#define DISPLAY_BYTES(A,B,C,D,...)
-#endif
-#endif
-
-#ifdef CONFIG_SSL_CERT_VERIFICATION
-int process_certificate(SSL *ssl, X509_CTX **x509_ctx);
-#endif
-
-SSL_SESSION *ssl_session_update(int max_sessions,
- SSL_SESSION *ssl_sessions[], SSL *ssl,
- const uint8_t *session_id);
-void kill_ssl_session(SSL_SESSION **ssl_sessions, SSL *ssl);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/axTLS/src/ssl/tls1_clnt.c b/axTLS/src/ssl/tls1_clnt.c
deleted file mode 100644
index 196b40e..0000000
--- a/axTLS/src/ssl/tls1_clnt.c
+++ /dev/null
@@ -1,395 +0,0 @@
-/*
- * Copyright (c) 2007, Cameron Rich
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * * Neither the name of the axTLS project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <stdio.h>
-#include "os_port.h"
-#include "ssl.h"
-
-#ifdef CONFIG_SSL_ENABLE_CLIENT /* all commented out if no client */
-
-static int send_client_hello(SSL *ssl);
-static int process_server_hello(SSL *ssl);
-static int process_server_hello_done(SSL *ssl);
-static int send_client_key_xchg(SSL *ssl);
-static int process_cert_req(SSL *ssl);
-static int send_cert_verify(SSL *ssl);
-
-/*
- * Establish a new SSL connection to an SSL server.
- */
-EXP_FUNC SSL * STDCALL ssl_client_new(SSL_CTX *ssl_ctx, int client_fd, const
- uint8_t *session_id, uint8_t sess_id_size)
-{
- SSL *ssl = ssl_new(ssl_ctx, client_fd);
- ssl->version = SSL_PROTOCOL_VERSION_MAX; /* try top version first */
-
- if (session_id && ssl_ctx->num_sessions)
- {
- if (sess_id_size > SSL_SESSION_ID_SIZE) /* validity check */
- {
- ssl_free(ssl);
- return NULL;
- }
-
- memcpy(ssl->session_id, session_id, sess_id_size);
- ssl->sess_id_size = sess_id_size;
- SET_SSL_FLAG(SSL_SESSION_RESUME); /* just flag for later */
- }
-
- SET_SSL_FLAG(SSL_IS_CLIENT);
- do_client_connect(ssl);
- return ssl;
-}
-
-/*
- * Process the handshake record.
- */
-int do_clnt_handshake(SSL *ssl, int handshake_type, uint8_t *buf, int hs_len)
-{
- int ret;
-
- /* To get here the state must be valid */
- switch (handshake_type)
- {
- case HS_SERVER_HELLO:
- ret = process_server_hello(ssl);
- break;
-
- case HS_CERTIFICATE:
- ret = process_certificate(ssl, &ssl->x509_ctx);
- break;
-
- case HS_SERVER_HELLO_DONE:
- if ((ret = process_server_hello_done(ssl)) == SSL_OK)
- {
- if (IS_SET_SSL_FLAG(SSL_HAS_CERT_REQ))
- {
- if ((ret = send_certificate(ssl)) == SSL_OK &&
- (ret = send_client_key_xchg(ssl)) == SSL_OK)
- {
- send_cert_verify(ssl);
- }
- }
- else
- {
- ret = send_client_key_xchg(ssl);
- }
-
- if (ret == SSL_OK &&
- (ret = send_change_cipher_spec(ssl)) == SSL_OK)
- {
- ret = send_finished(ssl);
- }
- }
- break;
-
- case HS_CERT_REQ:
- ret = process_cert_req(ssl);
- break;
-
- case HS_FINISHED:
- ret = process_finished(ssl, buf, hs_len);
- disposable_free(ssl); /* free up some memory */
- /* note: client renegotiation is not allowed after this */
- break;
-
- case HS_HELLO_REQUEST:
- disposable_new(ssl);
- ret = do_client_connect(ssl);
- break;
-
- default:
- ret = SSL_ERROR_INVALID_HANDSHAKE;
- break;
- }
-
- return ret;
-}
-
-/*
- * Do the handshaking from the beginning.
- */
-int do_client_connect(SSL *ssl)
-{
- int ret = SSL_OK;
-
- send_client_hello(ssl); /* send the client hello */
- ssl->bm_read_index = 0;
- ssl->next_state = HS_SERVER_HELLO;
- ssl->hs_status = SSL_NOT_OK; /* not connected */
-
- /* sit in a loop until it all looks good */
- if (!IS_SET_SSL_FLAG(SSL_CONNECT_IN_PARTS))
- {
- while (ssl->hs_status != SSL_OK)
- {
- ret = ssl_read(ssl, NULL);
-
- if (ret < SSL_OK)
- break;
- }
-
- ssl->hs_status = ret; /* connected? */
- }
-
- return ret;
-}
-
-/*
- * Send the initial client hello.
- */
-static int send_client_hello(SSL *ssl)
-{
- uint8_t *buf = ssl->bm_data;
- time_t tm = time(NULL);
- uint8_t *tm_ptr = &buf[6]; /* time will go here */
- int i, offset;
-
- buf[0] = HS_CLIENT_HELLO;
- buf[1] = 0;
- buf[2] = 0;
- /* byte 3 is calculated later */
- buf[4] = 0x03;
- buf[5] = ssl->version & 0x0f;
-
- /* client random value - spec says that 1st 4 bytes are big endian time */
- *tm_ptr++ = (uint8_t)(((long)tm & 0xff000000) >> 24);
- *tm_ptr++ = (uint8_t)(((long)tm & 0x00ff0000) >> 16);
- *tm_ptr++ = (uint8_t)(((long)tm & 0x0000ff00) >> 8);
- *tm_ptr++ = (uint8_t)(((long)tm & 0x000000ff));
- get_random(SSL_RANDOM_SIZE-4, &buf[10]);
- memcpy(ssl->dc->client_random, &buf[6], SSL_RANDOM_SIZE);
- offset = 6 + SSL_RANDOM_SIZE;
-
- /* give session resumption a go */
- if (IS_SET_SSL_FLAG(SSL_SESSION_RESUME)) /* set initially by user */
- {
- buf[offset++] = ssl->sess_id_size;
- memcpy(&buf[offset], ssl->session_id, ssl->sess_id_size);
- offset += ssl->sess_id_size;
- CLR_SSL_FLAG(SSL_SESSION_RESUME); /* clear so we can set later */
- }
- else
- {
- /* no session id - because no session resumption just yet */
- buf[offset++] = 0;
- }
-
- buf[offset++] = 0; /* number of ciphers */
- buf[offset++] = NUM_PROTOCOLS*2;/* number of ciphers */
-
- /* put all our supported protocols in our request */
- for (i = 0; i < NUM_PROTOCOLS; i++)
- {
- buf[offset++] = 0; /* cipher we are using */
- buf[offset++] = ssl_prot_prefs[i];
- }
-
- buf[offset++] = 1; /* no compression */
- buf[offset++] = 0;
- buf[3] = offset - 4; /* handshake size */
-
- return send_packet(ssl, PT_HANDSHAKE_PROTOCOL, NULL, offset);
-}
-
-/*
- * Process the server hello.
- */
-static int process_server_hello(SSL *ssl)
-{
- uint8_t *buf = ssl->bm_data;
- int pkt_size = ssl->bm_index;
- int num_sessions = ssl->ssl_ctx->num_sessions;
- uint8_t sess_id_size;
- int offset, ret = SSL_OK;
-
- /* check that we are talking to a TLSv1 server */
- uint8_t version = (buf[4] << 4) + buf[5];
- if (version > SSL_PROTOCOL_VERSION_MAX)
- {
- version = SSL_PROTOCOL_VERSION_MAX;
- }
- else if (ssl->version < SSL_PROTOCOL_MIN_VERSION)
- {
- ret = SSL_ERROR_INVALID_VERSION;
- ssl_display_error(ret);
- goto error;
- }
-
- ssl->version = version;
-
- /* get the server random value */
- memcpy(ssl->dc->server_random, &buf[6], SSL_RANDOM_SIZE);
- offset = 6 + SSL_RANDOM_SIZE; /* skip of session id size */
- sess_id_size = buf[offset++];
-
- if (sess_id_size > SSL_SESSION_ID_SIZE)
- {
- ret = SSL_ERROR_INVALID_SESSION;
- goto error;
- }
-
- if (num_sessions)
- {
- ssl->session = ssl_session_update(num_sessions,
- ssl->ssl_ctx->ssl_sessions, ssl, &buf[offset]);
- memcpy(ssl->session->session_id, &buf[offset], sess_id_size);
-
- /* pad the rest with 0's */
- if (sess_id_size < SSL_SESSION_ID_SIZE)
- {
- memset(&ssl->session->session_id[sess_id_size], 0,
- SSL_SESSION_ID_SIZE-sess_id_size);
- }
- }
-
- memcpy(ssl->session_id, &buf[offset], sess_id_size);
- ssl->sess_id_size = sess_id_size;
- offset += sess_id_size;
-
- /* get the real cipher we are using */
- ssl->cipher = buf[++offset];
- ssl->next_state = IS_SET_SSL_FLAG(SSL_SESSION_RESUME) ?
- HS_FINISHED : HS_CERTIFICATE;
-
- offset++; // skip the compr
- PARANOIA_CHECK(pkt_size, offset);
- ssl->dc->bm_proc_index = offset+1;
-
-error:
- return ret;
-}
-
-/**
- * Process the server hello done message.
- */
-static int process_server_hello_done(SSL *ssl)
-{
- ssl->next_state = HS_FINISHED;
- return SSL_OK;
-}
-
-/*
- * Send a client key exchange message.
- */
-static int send_client_key_xchg(SSL *ssl)
-{
- uint8_t *buf = ssl->bm_data;
- uint8_t premaster_secret[SSL_SECRET_SIZE];
- int enc_secret_size = -1;
-
- buf[0] = HS_CLIENT_KEY_XCHG;
- buf[1] = 0;
-
- premaster_secret[0] = 0x03; /* encode the version number */
- premaster_secret[1] = SSL_PROTOCOL_MINOR_VERSION; /* must be TLS 1.1 */
- get_random(SSL_SECRET_SIZE-2, &premaster_secret[2]);
- DISPLAY_RSA(ssl, ssl->x509_ctx->rsa_ctx);
-
- /* rsa_ctx->bi_ctx is not thread-safe */
- SSL_CTX_LOCK(ssl->ssl_ctx->mutex);
- enc_secret_size = RSA_encrypt(ssl->x509_ctx->rsa_ctx, premaster_secret,
- SSL_SECRET_SIZE, &buf[6], 0);
- SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex);
-
- buf[2] = (enc_secret_size + 2) >> 8;
- buf[3] = (enc_secret_size + 2) & 0xff;
- buf[4] = enc_secret_size >> 8;
- buf[5] = enc_secret_size & 0xff;
-
- generate_master_secret(ssl, premaster_secret);
- return send_packet(ssl, PT_HANDSHAKE_PROTOCOL, NULL, enc_secret_size+6);
-}
-
-/*
- * Process the certificate request.
- */
-static int process_cert_req(SSL *ssl)
-{
- uint8_t *buf = &ssl->bm_data[ssl->dc->bm_proc_index];
- int ret = SSL_OK;
- int offset = (buf[2] << 4) + buf[3];
- int pkt_size = ssl->bm_index;
-
- /* don't do any processing - we will send back an RSA certificate anyway */
- ssl->next_state = HS_SERVER_HELLO_DONE;
- SET_SSL_FLAG(SSL_HAS_CERT_REQ);
- ssl->dc->bm_proc_index += offset;
- PARANOIA_CHECK(pkt_size, offset);
-error:
- return ret;
-}
-
-/*
- * Send a certificate verify message.
- */
-static int send_cert_verify(SSL *ssl)
-{
- uint8_t *buf = ssl->bm_data;
- uint8_t dgst[MD5_SIZE+SHA1_SIZE];
- RSA_CTX *rsa_ctx = ssl->ssl_ctx->rsa_ctx;
- int n = 0, ret;
-
- DISPLAY_RSA(ssl, rsa_ctx);
-
- buf[0] = HS_CERT_VERIFY;
- buf[1] = 0;
-
- finished_digest(ssl, NULL, dgst); /* calculate the digest */
-
- /* rsa_ctx->bi_ctx is not thread-safe */
- if (rsa_ctx)
- {
- SSL_CTX_LOCK(ssl->ssl_ctx->mutex);
- n = RSA_encrypt(rsa_ctx, dgst, sizeof(dgst), &buf[6], 1);
- SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex);
-
- if (n == 0)
- {
- ret = SSL_ERROR_INVALID_KEY;
- goto error;
- }
- }
-
- buf[4] = n >> 8; /* add the RSA size (not officially documented) */
- buf[5] = n & 0xff;
- n += 2;
- buf[2] = n >> 8;
- buf[3] = n & 0xff;
- ret = send_packet(ssl, PT_HANDSHAKE_PROTOCOL, NULL, n+4);
-
-error:
- return ret;
-}
-
-#endif /* CONFIG_SSL_ENABLE_CLIENT */
diff --git a/axTLS/src/ssl/tls1_svr.c b/axTLS/src/ssl/tls1_svr.c
deleted file mode 100644
index f374928..0000000
--- a/axTLS/src/ssl/tls1_svr.c
+++ /dev/null
@@ -1,478 +0,0 @@
-/*
- * Copyright (c) 2007, Cameron Rich
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * * Neither the name of the axTLS project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include "os_port.h"
-#include "ssl.h"
-
-static const uint8_t g_hello_done[] = { HS_SERVER_HELLO_DONE, 0, 0, 0 };
-
-static int process_client_hello(SSL *ssl);
-static int send_server_hello_sequence(SSL *ssl);
-static int send_server_hello(SSL *ssl);
-static int send_server_hello_done(SSL *ssl);
-static int process_client_key_xchg(SSL *ssl);
-#ifdef CONFIG_SSL_CERT_VERIFICATION
-static int send_certificate_request(SSL *ssl);
-static int process_cert_verify(SSL *ssl);
-#endif
-
-/*
- * Establish a new SSL connection to an SSL client.
- */
-EXP_FUNC SSL * STDCALL ssl_server_new(SSL_CTX *ssl_ctx, int client_fd)
-{
- SSL *ssl;
-
- ssl = ssl_new(ssl_ctx, client_fd);
- ssl->next_state = HS_CLIENT_HELLO;
-
-#ifdef CONFIG_SSL_FULL_MODE
- if (ssl_ctx->chain_length == 0)
- printf("Warning - no server certificate defined\n"); TTY_FLUSH();
-#endif
-
- return ssl;
-}
-
-/*
- * Process the handshake record.
- */
-int do_svr_handshake(SSL *ssl, int handshake_type, uint8_t *buf, int hs_len)
-{
- int ret = SSL_OK;
- ssl->hs_status = SSL_NOT_OK; /* not connected */
-
- /* To get here the state must be valid */
- switch (handshake_type)
- {
- case HS_CLIENT_HELLO:
- if ((ret = process_client_hello(ssl)) == SSL_OK)
- ret = send_server_hello_sequence(ssl);
- break;
-
-#ifdef CONFIG_SSL_CERT_VERIFICATION
- case HS_CERTIFICATE:/* the client sends its cert */
- ret = process_certificate(ssl, &ssl->x509_ctx);
-
- if (ret == SSL_OK) /* verify the cert */
- {
- int cert_res;
- cert_res = x509_verify(
- ssl->ssl_ctx->ca_cert_ctx, ssl->x509_ctx);
- ret = (cert_res == 0) ? SSL_OK : SSL_X509_ERROR(cert_res);
- }
- break;
-
- case HS_CERT_VERIFY:
- ret = process_cert_verify(ssl);
- add_packet(ssl, buf, hs_len); /* needs to be done after */
- break;
-#endif
- case HS_CLIENT_KEY_XCHG:
- ret = process_client_key_xchg(ssl);
- break;
-
- case HS_FINISHED:
- ret = process_finished(ssl, buf, hs_len);
- disposable_free(ssl); /* free up some memory */
- break;
- }
-
- return ret;
-}
-
-/*
- * Process a client hello message.
- */
-static int process_client_hello(SSL *ssl)
-{
- uint8_t *buf = ssl->bm_data;
- uint8_t *record_buf = ssl->hmac_header;
- int pkt_size = ssl->bm_index;
- int i, j, cs_len, id_len, offset = 6 + SSL_RANDOM_SIZE;
- int ret = SSL_OK;
-
- uint8_t version = (record_buf[1] << 4) + record_buf[2];
- ssl->version = ssl->client_version = version;
-
- if (version > SSL_PROTOCOL_VERSION_MAX)
- {
- /* use client's version instead */
- ssl->version = SSL_PROTOCOL_VERSION_MAX;
- }
- else if (version < SSL_PROTOCOL_MIN_VERSION) /* old version supported? */
- {
- ret = SSL_ERROR_INVALID_VERSION;
- ssl_display_error(ret);
- goto error;
- }
-
- memcpy(ssl->dc->client_random, &buf[6], SSL_RANDOM_SIZE);
-
- /* process the session id */
- id_len = buf[offset++];
- if (id_len > SSL_SESSION_ID_SIZE)
- {
- return SSL_ERROR_INVALID_SESSION;
- }
-
-#ifndef CONFIG_SSL_SKELETON_MODE
- ssl->session = ssl_session_update(ssl->ssl_ctx->num_sessions,
- ssl->ssl_ctx->ssl_sessions, ssl, id_len ? &buf[offset] : NULL);
-#endif
-
- offset += id_len;
- cs_len = (buf[offset]<<8) + buf[offset+1];
- offset += 3; /* add 1 due to all cipher suites being 8 bit */
-
- PARANOIA_CHECK(pkt_size, offset);
-
- /* work out what cipher suite we are going to use - client defines
- the preference */
- for (i = 0; i < cs_len; i += 2)
- {
- for (j = 0; j < NUM_PROTOCOLS; j++)
- {
- if (ssl_prot_prefs[j] == buf[offset+i]) /* got a match? */
- {
- ssl->cipher = ssl_prot_prefs[j];
- goto do_state;
- }
- }
- }
-
- /* ouch! protocol is not supported */
- ret = SSL_ERROR_NO_CIPHER;
-
-do_state:
-error:
- return ret;
-}
-
-#ifdef CONFIG_SSL_ENABLE_V23_HANDSHAKE
-/*
- * Some browsers use a hybrid SSLv2 "client hello"
- */
-int process_sslv23_client_hello(SSL *ssl)
-{
- uint8_t *buf = ssl->bm_data;
- int bytes_needed = ((buf[0] & 0x7f) << 8) + buf[1];
- int ret = SSL_OK;
-
- /* we have already read 3 extra bytes so far */
- int read_len = SOCKET_READ(ssl->client_fd, buf, bytes_needed-3);
- int cs_len = buf[1];
- int id_len = buf[3];
- int ch_len = buf[5];
- int i, j, offset = 8; /* start at first cipher */
- int random_offset = 0;
-
- DISPLAY_BYTES(ssl, "received %d bytes", buf, read_len, read_len);
-
- add_packet(ssl, buf, read_len);
-
- /* connection has gone, so die */
- if (bytes_needed < 0)
- {
- return SSL_ERROR_CONN_LOST;
- }
-
- /* now work out what cipher suite we are going to use */
- for (j = 0; j < NUM_PROTOCOLS; j++)
- {
- for (i = 0; i < cs_len; i += 3)
- {
- if (ssl_prot_prefs[j] == buf[offset+i])
- {
- ssl->cipher = ssl_prot_prefs[j];
- goto server_hello;
- }
- }
- }
-
- /* ouch! protocol is not supported */
- ret = SSL_ERROR_NO_CIPHER;
- goto error;
-
-server_hello:
- /* get the session id */
- offset += cs_len - 2; /* we've gone 2 bytes past the end */
-#ifndef CONFIG_SSL_SKELETON_MODE
- ssl->session = ssl_session_update(ssl->ssl_ctx->num_sessions,
- ssl->ssl_ctx->ssl_sessions, ssl, id_len ? &buf[offset] : NULL);
-#endif
-
- /* get the client random data */
- offset += id_len;
-
- /* random can be anywhere between 16 and 32 bytes long - so it is padded
- * with 0's to the left */
- if (ch_len == 0x10)
- {
- random_offset += 0x10;
- }
-
- memcpy(&ssl->dc->client_random[random_offset], &buf[offset], ch_len);
- ret = send_server_hello_sequence(ssl);
-
-error:
- return ret;
-}
-#endif
-
-/*
- * Send the entire server hello sequence
- */
-static int send_server_hello_sequence(SSL *ssl)
-{
- int ret;
-
- if ((ret = send_server_hello(ssl)) == SSL_OK)
- {
-#ifndef CONFIG_SSL_SKELETON_MODE
- /* resume handshake? */
- if (IS_SET_SSL_FLAG(SSL_SESSION_RESUME))
- {
- if ((ret = send_change_cipher_spec(ssl)) == SSL_OK)
- {
- ret = send_finished(ssl);
- ssl->next_state = HS_FINISHED;
- }
- }
- else
-#endif
- if ((ret = send_certificate(ssl)) == SSL_OK)
- {
-#ifdef CONFIG_SSL_CERT_VERIFICATION
- /* ask the client for its certificate */
- if (IS_SET_SSL_FLAG(SSL_CLIENT_AUTHENTICATION))
- {
- if ((ret = send_certificate_request(ssl)) == SSL_OK)
- {
- ret = send_server_hello_done(ssl);
- ssl->next_state = HS_CERTIFICATE;
- }
- }
- else
-#endif
- {
- ret = send_server_hello_done(ssl);
- ssl->next_state = HS_CLIENT_KEY_XCHG;
- }
- }
- }
-
- return ret;
-}
-
-/*
- * Send a server hello message.
- */
-static int send_server_hello(SSL *ssl)
-{
- uint8_t *buf = ssl->bm_data;
- int offset = 0;
-
- buf[0] = HS_SERVER_HELLO;
- buf[1] = 0;
- buf[2] = 0;
- /* byte 3 is calculated later */
- buf[4] = 0x03;
- buf[5] = ssl->version & 0x0f;
-
- /* server random value */
- get_random(SSL_RANDOM_SIZE, &buf[6]);
- memcpy(ssl->dc->server_random, &buf[6], SSL_RANDOM_SIZE);
- offset = 6 + SSL_RANDOM_SIZE;
-
-#ifndef CONFIG_SSL_SKELETON_MODE
- if (IS_SET_SSL_FLAG(SSL_SESSION_RESUME))
- {
- /* retrieve id from session cache */
- buf[offset++] = SSL_SESSION_ID_SIZE;
- memcpy(&buf[offset], ssl->session->session_id, SSL_SESSION_ID_SIZE);
- memcpy(ssl->session_id, ssl->session->session_id, SSL_SESSION_ID_SIZE);
- ssl->sess_id_size = SSL_SESSION_ID_SIZE;
- offset += SSL_SESSION_ID_SIZE;
- }
- else /* generate our own session id */
-#endif
- {
-#ifndef CONFIG_SSL_SKELETON_MODE
- buf[offset++] = SSL_SESSION_ID_SIZE;
- get_random(SSL_SESSION_ID_SIZE, &buf[offset]);
- memcpy(ssl->session_id, &buf[offset], SSL_SESSION_ID_SIZE);
- ssl->sess_id_size = SSL_SESSION_ID_SIZE;
-
- /* store id in session cache */
- if (ssl->ssl_ctx->num_sessions)
- {
- memcpy(ssl->session->session_id,
- ssl->session_id, SSL_SESSION_ID_SIZE);
- }
-
- offset += SSL_SESSION_ID_SIZE;
-#else
- buf[offset++] = 0; /* don't bother with session id in skelton mode */
-#endif
- }
-
- buf[offset++] = 0; /* cipher we are using */
- buf[offset++] = ssl->cipher;
- buf[offset++] = 0; /* no compression */
- buf[3] = offset - 4; /* handshake size */
- return send_packet(ssl, PT_HANDSHAKE_PROTOCOL, NULL, offset);
-}
-
-/*
- * Send the server hello done message.
- */
-static int send_server_hello_done(SSL *ssl)
-{
- return send_packet(ssl, PT_HANDSHAKE_PROTOCOL,
- g_hello_done, sizeof(g_hello_done));
-}
-
-/*
- * Pull apart a client key exchange message. Decrypt the pre-master key (using
- * our RSA private key) and then work out the master key. Initialise the
- * ciphers.
- */
-static int process_client_key_xchg(SSL *ssl)
-{
- uint8_t *buf = &ssl->bm_data[ssl->dc->bm_proc_index];
- int pkt_size = ssl->bm_index;
- int premaster_size, secret_length = (buf[2] << 8) + buf[3];
- uint8_t premaster_secret[MAX_KEY_BYTE_SIZE];
- RSA_CTX *rsa_ctx = ssl->ssl_ctx->rsa_ctx;
- int offset = 4;
- int ret = SSL_OK;
-
- if (rsa_ctx == NULL)
- {
- ret = SSL_ERROR_NO_CERT_DEFINED;
- goto error;
- }
-
- /* is there an extra size field? */
- if ((secret_length - 2) == rsa_ctx->num_octets)
- offset += 2;
-
- PARANOIA_CHECK(pkt_size, rsa_ctx->num_octets+offset);
-
- /* rsa_ctx->bi_ctx is not thread-safe */
- SSL_CTX_LOCK(ssl->ssl_ctx->mutex);
- premaster_size = RSA_decrypt(rsa_ctx, &buf[offset], premaster_secret, 1);
- SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex);
-
- if (premaster_size != SSL_SECRET_SIZE ||
- premaster_secret[0] != 0x03 || /* must be the same as client
- offered version */
- premaster_secret[1] != (ssl->client_version & 0x0f))
- {
- /* guard against a Bleichenbacher attack */
- get_random(SSL_SECRET_SIZE, premaster_secret);
- /* and continue - will die eventually when checking the mac */
- }
-
-#if 0
- print_blob("pre-master", premaster_secret, SSL_SECRET_SIZE);
-#endif
-
- generate_master_secret(ssl, premaster_secret);
-
-#ifdef CONFIG_SSL_CERT_VERIFICATION
- ssl->next_state = IS_SET_SSL_FLAG(SSL_CLIENT_AUTHENTICATION) ?
- HS_CERT_VERIFY : HS_FINISHED;
-#else
- ssl->next_state = HS_FINISHED;
-#endif
-
- ssl->dc->bm_proc_index += rsa_ctx->num_octets+offset;
-error:
- return ret;
-}
-
-#ifdef CONFIG_SSL_CERT_VERIFICATION
-static const uint8_t g_cert_request[] = { HS_CERT_REQ, 0, 0, 4, 1, 0, 0, 0 };
-
-/*
- * Send the certificate request message.
- */
-static int send_certificate_request(SSL *ssl)
-{
- return send_packet(ssl, PT_HANDSHAKE_PROTOCOL,
- g_cert_request, sizeof(g_cert_request));
-}
-
-/*
- * Ensure the client has the private key by first decrypting the packet and
- * then checking the packet digests.
- */
-static int process_cert_verify(SSL *ssl)
-{
- uint8_t *buf = &ssl->bm_data[ssl->dc->bm_proc_index];
- int pkt_size = ssl->bm_index;
- uint8_t dgst_buf[MAX_KEY_BYTE_SIZE];
- uint8_t dgst[MD5_SIZE+SHA1_SIZE];
- X509_CTX *x509_ctx = ssl->x509_ctx;
- int ret = SSL_OK;
- int n;
-
- PARANOIA_CHECK(pkt_size, x509_ctx->rsa_ctx->num_octets+6);
- DISPLAY_RSA(ssl, x509_ctx->rsa_ctx);
-
- /* rsa_ctx->bi_ctx is not thread-safe */
- SSL_CTX_LOCK(ssl->ssl_ctx->mutex);
- n = RSA_decrypt(x509_ctx->rsa_ctx, &buf[6], dgst_buf, 0);
- SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex);
-
- if (n != SHA1_SIZE + MD5_SIZE)
- {
- ret = SSL_ERROR_INVALID_KEY;
- goto end_cert_vfy;
- }
-
- finished_digest(ssl, NULL, dgst); /* calculate the digest */
- if (memcmp(dgst_buf, dgst, MD5_SIZE + SHA1_SIZE))
- {
- ret = SSL_ERROR_INVALID_KEY;
- }
-
-end_cert_vfy:
- ssl->next_state = HS_FINISHED;
-error:
- return ret;
-}
-
-#endif
diff --git a/axTLS/src/ssl/version.h b/axTLS/src/ssl/version.h
deleted file mode 100644
index cc1ddb2..0000000
--- a/axTLS/src/ssl/version.h
+++ /dev/null
@@ -1 +0,0 @@
-#define AXTLS_VERSION "1.4.4"
diff --git a/axTLS/src/ssl/x509.c b/axTLS/src/ssl/x509.c
deleted file mode 100644
index 116fa00..0000000
--- a/axTLS/src/ssl/x509.c
+++ /dev/null
@@ -1,564 +0,0 @@
-/*
- * Copyright (c) 2007, Cameron Rich
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * * Neither the name of the axTLS project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @file x509.c
- *
- * Certificate processing.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include "os_port.h"
-#include "crypto_misc.h"
-
-#ifdef CONFIG_SSL_CERT_VERIFICATION
-/**
- * Retrieve the signature from a certificate.
- */
-static const uint8_t *get_signature(const uint8_t *asn1_sig, int *len)
-{
- int offset = 0;
- const uint8_t *ptr = NULL;
-
- if (asn1_next_obj(asn1_sig, &offset, ASN1_SEQUENCE) < 0 ||
- asn1_skip_obj(asn1_sig, &offset, ASN1_SEQUENCE))
- goto end_get_sig;
-
- if (asn1_sig[offset++] != ASN1_OCTET_STRING)
- goto end_get_sig;
- *len = get_asn1_length(asn1_sig, &offset);
- ptr = &asn1_sig[offset]; /* all ok */
-
-end_get_sig:
- return ptr;
-}
-
-#endif
-
-/**
- * Construct a new x509 object.
- * @return 0 if ok. < 0 if there was a problem.
- */
-int x509_new(const uint8_t *cert, int *len, X509_CTX **ctx)
-{
- int begin_tbs, end_tbs;
- int ret = X509_NOT_OK, offset = 0, cert_size = 0;
- X509_CTX *x509_ctx;
- BI_CTX *bi_ctx;
- SHA1_CTX sha_ctx_fp;
-
- *ctx = (X509_CTX *)calloc(1, sizeof(X509_CTX));
- x509_ctx = *ctx;
-
- /* get the certificate size */
- asn1_skip_obj(cert, &cert_size, ASN1_SEQUENCE);
-
- if (asn1_next_obj(cert, &offset, ASN1_SEQUENCE) < 0)
- goto end_cert;
-
- begin_tbs = offset; /* start of the tbs */
- end_tbs = begin_tbs; /* work out the end of the tbs */
- asn1_skip_obj(cert, &end_tbs, ASN1_SEQUENCE);
-
- if (asn1_next_obj(cert, &offset, ASN1_SEQUENCE) < 0)
- goto end_cert;
-
- if (cert[offset] == ASN1_EXPLICIT_TAG) /* optional version */
- {
- if (asn1_version(cert, &offset, x509_ctx))
- goto end_cert;
- }
-
- if (asn1_skip_obj(cert, &offset, ASN1_INTEGER) || /* serial number */
- asn1_next_obj(cert, &offset, ASN1_SEQUENCE) < 0)
- goto end_cert;
-
- /* make sure the signature is ok */
- if (asn1_signature_type(cert, &offset, x509_ctx))
- {
- ret = X509_VFY_ERROR_UNSUPPORTED_DIGEST;
- goto end_cert;
- }
-
- if (asn1_name(cert, &offset, x509_ctx->ca_cert_dn) ||
- asn1_validity(cert, &offset, x509_ctx) ||
- asn1_name(cert, &offset, x509_ctx->cert_dn) ||
- asn1_public_key(cert, &offset, x509_ctx))
- {
- goto end_cert;
- }
-
- bi_ctx = x509_ctx->rsa_ctx->bi_ctx;
-
- SHA1_Init(&sha_ctx_fp);
- SHA1_Update(&sha_ctx_fp, cert, cert_size);
- SHA1_Final(x509_ctx->sha1_fingerprint, &sha_ctx_fp);
-
-#ifdef CONFIG_SSL_CERT_VERIFICATION /* only care if doing verification */
- /* use the appropriate signature algorithm (SHA1/MD5/MD2) */
- if (x509_ctx->sig_type == SIG_TYPE_MD5)
- {
- MD5_CTX md5_ctx;
- uint8_t md5_dgst[MD5_SIZE];
- MD5_Init(&md5_ctx);
- MD5_Update(&md5_ctx, &cert[begin_tbs], end_tbs-begin_tbs);
- MD5_Final(md5_dgst, &md5_ctx);
- x509_ctx->digest = bi_import(bi_ctx, md5_dgst, MD5_SIZE);
- }
- else if (x509_ctx->sig_type == SIG_TYPE_SHA1)
- {
- SHA1_CTX sha_ctx;
- uint8_t sha_dgst[SHA1_SIZE];
- SHA1_Init(&sha_ctx);
- SHA1_Update(&sha_ctx, &cert[begin_tbs], end_tbs-begin_tbs);
- SHA1_Final(sha_dgst, &sha_ctx);
- x509_ctx->digest = bi_import(bi_ctx, sha_dgst, SHA1_SIZE);
- }
- else if (x509_ctx->sig_type == SIG_TYPE_MD2)
- {
- MD2_CTX md2_ctx;
- uint8_t md2_dgst[MD2_SIZE];
- MD2_Init(&md2_ctx);
- MD2_Update(&md2_ctx, &cert[begin_tbs], end_tbs-begin_tbs);
- MD2_Final(md2_dgst, &md2_ctx);
- x509_ctx->digest = bi_import(bi_ctx, md2_dgst, MD2_SIZE);
- }
-
- if (cert[offset] == ASN1_V3_DATA)
- {
- int suboffset;
-
- ++offset;
- get_asn1_length(cert, &offset);
-
- if ((suboffset = asn1_find_subjectaltname(cert, offset)) > 0)
- {
- if (asn1_next_obj(cert, &suboffset, ASN1_OCTET_STRING) > 0)
- {
- int altlen;
-
- if ((altlen = asn1_next_obj(cert,
- &suboffset, ASN1_SEQUENCE)) > 0)
- {
- int endalt = suboffset + altlen;
- int totalnames = 0;
-
- while (suboffset < endalt)
- {
- int type = cert[suboffset++];
- int dnslen = get_asn1_length(cert, &suboffset);
-
- if (type == ASN1_CONTEXT_DNSNAME)
- {
- x509_ctx->subject_alt_dnsnames = (char**)
- realloc(x509_ctx->subject_alt_dnsnames,
- (totalnames + 2) * sizeof(char*));
- x509_ctx->subject_alt_dnsnames[totalnames] =
- (char*)malloc(dnslen + 1);
- x509_ctx->subject_alt_dnsnames[totalnames+1] = NULL;
- memcpy(x509_ctx->subject_alt_dnsnames[totalnames],
- cert + suboffset, dnslen);
- x509_ctx->subject_alt_dnsnames[
- totalnames][dnslen] = 0;
- ++totalnames;
- }
-
- suboffset += dnslen;
- }
- }
- }
- }
- }
-
- offset = end_tbs; /* skip the rest of v3 data */
- if (asn1_skip_obj(cert, &offset, ASN1_SEQUENCE) ||
- asn1_signature(cert, &offset, x509_ctx))
- goto end_cert;
-#endif
- ret = X509_OK;
-end_cert:
- if (len)
- {
- *len = cert_size;
- }
-
- if (ret)
- {
-#ifdef CONFIG_SSL_FULL_MODE
- printf("Error: Invalid X509 ASN.1 file (%s)\n",
- x509_display_error(ret));
-#endif
- x509_free(x509_ctx);
- *ctx = NULL;
- }
-
- return ret;
-}
-
-/**
- * Free an X.509 object's resources.
- */
-void x509_free(X509_CTX *x509_ctx)
-{
- X509_CTX *next;
- int i;
-
- if (x509_ctx == NULL) /* if already null, then don't bother */
- return;
-
- for (i = 0; i < X509_NUM_DN_TYPES; i++)
- {
- free(x509_ctx->ca_cert_dn[i]);
- free(x509_ctx->cert_dn[i]);
- }
-
- free(x509_ctx->signature);
-
-#ifdef CONFIG_SSL_CERT_VERIFICATION
- if (x509_ctx->digest)
- {
- bi_free(x509_ctx->rsa_ctx->bi_ctx, x509_ctx->digest);
- }
-
- if (x509_ctx->subject_alt_dnsnames)
- {
- for (i = 0; x509_ctx->subject_alt_dnsnames[i]; ++i)
- free(x509_ctx->subject_alt_dnsnames[i]);
-
- free(x509_ctx->subject_alt_dnsnames);
- }
-#endif
-
- RSA_free(x509_ctx->rsa_ctx);
- next = x509_ctx->next;
- free(x509_ctx);
- x509_free(next); /* clear the chain */
-}
-
-#ifdef CONFIG_SSL_CERT_VERIFICATION
-/**
- * Take a signature and decrypt it.
- */
-static bigint *sig_verify(BI_CTX *ctx, const uint8_t *sig, int sig_len,
- bigint *modulus, bigint *pub_exp)
-{
- int i, size;
- bigint *decrypted_bi, *dat_bi;
- bigint *bir = NULL;
- uint8_t *block = (uint8_t *)alloca(sig_len);
-
- /* decrypt */
- dat_bi = bi_import(ctx, sig, sig_len);
- ctx->mod_offset = BIGINT_M_OFFSET;
-
- /* convert to a normal block */
- decrypted_bi = bi_mod_power2(ctx, dat_bi, modulus, pub_exp);
-
- bi_export(ctx, decrypted_bi, block, sig_len);
- ctx->mod_offset = BIGINT_M_OFFSET;
-
- i = 10; /* start at the first possible non-padded byte */
- while (block[i++] && i < sig_len);
- size = sig_len - i;
-
- /* get only the bit we want */
- if (size > 0)
- {
- int len;
- const uint8_t *sig_ptr = get_signature(&block[i], &len);
-
- if (sig_ptr)
- {
- bir = bi_import(ctx, sig_ptr, len);
- }
- }
-
- /* save a few bytes of memory */
- bi_clear_cache(ctx);
- return bir;
-}
-
-/**
- * Do some basic checks on the certificate chain.
- *
- * Certificate verification consists of a number of checks:
- * - The date of the certificate is after the start date.
- * - The date of the certificate is before the finish date.
- * - A root certificate exists in the certificate store.
- * - That the certificate(s) are not self-signed.
- * - The certificate chain is valid.
- * - The signature of the certificate is valid.
- */
-int x509_verify(const CA_CERT_CTX *ca_cert_ctx, const X509_CTX *cert)
-{
- int ret = X509_OK, i = 0;
- bigint *cert_sig;
- X509_CTX *next_cert = NULL;
- BI_CTX *ctx = NULL;
- bigint *mod = NULL, *expn = NULL;
- int match_ca_cert = 0;
- struct timeval tv;
- uint8_t is_self_signed = 0;
-
- if (cert == NULL)
- {
- ret = X509_VFY_ERROR_NO_TRUSTED_CERT;
- goto end_verify;
- }
-
- /* a self-signed certificate that is not in the CA store - use this
- to check the signature */
- if (asn1_compare_dn(cert->ca_cert_dn, cert->cert_dn) == 0)
- {
- is_self_signed = 1;
- ctx = cert->rsa_ctx->bi_ctx;
- mod = cert->rsa_ctx->m;
- expn = cert->rsa_ctx->e;
- }
-
- gettimeofday(&tv, NULL);
-
- /* check the not before date */
- if (tv.tv_sec < cert->not_before)
- {
- ret = X509_VFY_ERROR_NOT_YET_VALID;
- goto end_verify;
- }
-
- /* check the not after date */
- if (tv.tv_sec > cert->not_after)
- {
- ret = X509_VFY_ERROR_EXPIRED;
- goto end_verify;
- }
-
- next_cert = cert->next;
-
- /* last cert in the chain - look for a trusted cert */
- if (next_cert == NULL)
- {
- if (ca_cert_ctx != NULL)
- {
- /* go thu the CA store */
- while (i < CONFIG_X509_MAX_CA_CERTS && ca_cert_ctx->cert[i])
- {
- if (asn1_compare_dn(cert->ca_cert_dn,
- ca_cert_ctx->cert[i]->cert_dn) == 0)
- {
- /* use this CA certificate for signature verification */
- match_ca_cert = 1;
- ctx = ca_cert_ctx->cert[i]->rsa_ctx->bi_ctx;
- mod = ca_cert_ctx->cert[i]->rsa_ctx->m;
- expn = ca_cert_ctx->cert[i]->rsa_ctx->e;
- break;
- }
-
- i++;
- }
- }
-
- /* couldn't find a trusted cert (& let self-signed errors
- be returned) */
- if (!match_ca_cert && !is_self_signed)
- {
- ret = X509_VFY_ERROR_NO_TRUSTED_CERT;
- goto end_verify;
- }
- }
- else if (asn1_compare_dn(cert->ca_cert_dn, next_cert->cert_dn) != 0)
- {
- /* check the chain */
- ret = X509_VFY_ERROR_INVALID_CHAIN;
- goto end_verify;
- }
- else /* use the next certificate in the chain for signature verify */
- {
- ctx = next_cert->rsa_ctx->bi_ctx;
- mod = next_cert->rsa_ctx->m;
- expn = next_cert->rsa_ctx->e;
- }
-
- /* cert is self signed */
- if (!match_ca_cert && is_self_signed)
- {
- ret = X509_VFY_ERROR_SELF_SIGNED;
- goto end_verify;
- }
-
- /* check the signature */
- cert_sig = sig_verify(ctx, cert->signature, cert->sig_len,
- bi_clone(ctx, mod), bi_clone(ctx, expn));
-
- if (cert_sig && cert->digest)
- {
- if (bi_compare(cert_sig, cert->digest) != 0)
- ret = X509_VFY_ERROR_BAD_SIGNATURE;
-
-
- bi_free(ctx, cert_sig);
- }
- else
- {
- ret = X509_VFY_ERROR_BAD_SIGNATURE;
- }
-
- if (ret)
- goto end_verify;
-
- /* go down the certificate chain using recursion. */
- if (next_cert != NULL)
- {
- ret = x509_verify(ca_cert_ctx, next_cert);
- }
-
-end_verify:
- return ret;
-}
-#endif
-
-#if defined (CONFIG_SSL_FULL_MODE)
-/**
- * Used for diagnostics.
- */
-static const char *not_part_of_cert = "<Not Part Of Certificate>";
-void x509_print(const X509_CTX *cert, CA_CERT_CTX *ca_cert_ctx)
-{
- if (cert == NULL)
- return;
-
- printf("=== CERTIFICATE ISSUED TO ===\n");
- printf("Common Name (CN):\t\t");
- printf("%s\n", cert->cert_dn[X509_COMMON_NAME] ?
- cert->cert_dn[X509_COMMON_NAME] : not_part_of_cert);
-
- printf("Organization (O):\t\t");
- printf("%s\n", cert->cert_dn[X509_ORGANIZATION] ?
- cert->cert_dn[X509_ORGANIZATION] : not_part_of_cert);
-
- printf("Organizational Unit (OU):\t");
- printf("%s\n", cert->cert_dn[X509_ORGANIZATIONAL_UNIT] ?
- cert->cert_dn[X509_ORGANIZATIONAL_UNIT] : not_part_of_cert);
-
- printf("=== CERTIFICATE ISSUED BY ===\n");
- printf("Common Name (CN):\t\t");
- printf("%s\n", cert->ca_cert_dn[X509_COMMON_NAME] ?
- cert->ca_cert_dn[X509_COMMON_NAME] : not_part_of_cert);
-
- printf("Organization (O):\t\t");
- printf("%s\n", cert->ca_cert_dn[X509_ORGANIZATION] ?
- cert->ca_cert_dn[X509_ORGANIZATION] : not_part_of_cert);
-
- printf("Organizational Unit (OU):\t");
- printf("%s\n", cert->ca_cert_dn[X509_ORGANIZATIONAL_UNIT] ?
- cert->ca_cert_dn[X509_ORGANIZATIONAL_UNIT] : not_part_of_cert);
-
- printf("Not Before:\t\t\t%s", ctime(&cert->not_before));
- printf("Not After:\t\t\t%s", ctime(&cert->not_after));
- printf("RSA bitsize:\t\t\t%d\n", cert->rsa_ctx->num_octets*8);
- printf("Sig Type:\t\t\t");
- switch (cert->sig_type)
- {
- case SIG_TYPE_MD5:
- printf("MD5\n");
- break;
- case SIG_TYPE_SHA1:
- printf("SHA1\n");
- break;
- case SIG_TYPE_MD2:
- printf("MD2\n");
- break;
- default:
- printf("Unrecognized: %d\n", cert->sig_type);
- break;
- }
-
- if (ca_cert_ctx)
- {
- printf("Verify:\t\t\t\t%s\n",
- x509_display_error(x509_verify(ca_cert_ctx, cert)));
- }
-
-#if 0
- print_blob("Signature", cert->signature, cert->sig_len);
- bi_print("Modulus", cert->rsa_ctx->m);
- bi_print("Pub Exp", cert->rsa_ctx->e);
-#endif
-
- if (ca_cert_ctx)
- {
- x509_print(cert->next, ca_cert_ctx);
- }
-
- TTY_FLUSH();
-}
-
-const char * x509_display_error(int error)
-{
- switch (error)
- {
- case X509_OK:
- return "Certificate verify successful";
-
- case X509_NOT_OK:
- return "X509 not ok";
-
- case X509_VFY_ERROR_NO_TRUSTED_CERT:
- return "No trusted cert is available";
-
- case X509_VFY_ERROR_BAD_SIGNATURE:
- return "Bad signature";
-
- case X509_VFY_ERROR_NOT_YET_VALID:
- return "Cert is not yet valid";
-
- case X509_VFY_ERROR_EXPIRED:
- return "Cert has expired";
-
- case X509_VFY_ERROR_SELF_SIGNED:
- return "Cert is self-signed";
-
- case X509_VFY_ERROR_INVALID_CHAIN:
- return "Chain is invalid (check order of certs)";
-
- case X509_VFY_ERROR_UNSUPPORTED_DIGEST:
- return "Unsupported digest";
-
- case X509_INVALID_PRIV_KEY:
- return "Invalid private key";
-
- default:
- return "Unknown";
- }
-}
-#endif /* CONFIG_SSL_FULL_MODE */
-