Squashed 'tmk_core/' changes from 7967731..b9e0ea0
b9e0ea0 Merge commit '7fa9d8bdea3773d1195b04d98fcf27cf48ddd81d' as 'tool/mbed/mbed-sdk' 7fa9d8b Squashed 'tool/mbed/mbed-sdk/' content from commit 7c21ce5 git-subtree-dir: tmk_core git-subtree-split: b9e0ea08cb940de20b3610ecdda18e9d8cd7c552
This commit is contained in:
parent
a20ef7052c
commit
1fe4406f37
4198 changed files with 2016457 additions and 0 deletions
565
tool/mbed/mbed-sdk/libraries/net/https/axTLS/ssl/asn1.c
Normal file
565
tool/mbed/mbed-sdk/libraries/net/https/axTLS/ssl/asn1.c
Normal file
|
@ -0,0 +1,565 @@
|
|||
/*
|
||||
* 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"
|
||||
#include "config.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)++;
|
||||
int tmp = get_asn1_length(buf, offset);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/* Use the private key to mix up the RNG if possible. */
|
||||
RNG_custom_init(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;
|
||||
int asn1_type = buf[*offset];
|
||||
|
||||
/* some certs have this awful crud in them for some reason */
|
||||
if (asn1_type != ASN1_PRINTABLE_STR &&
|
||||
asn1_type != ASN1_PRINTABLE_STR2 &&
|
||||
asn1_type != ASN1_TELETEX_STR &&
|
||||
asn1_type != ASN1_IA5_STR &&
|
||||
asn1_type != ASN1_UNICODE_STR)
|
||||
goto end_pnt_str;
|
||||
|
||||
(*offset)++;
|
||||
len = get_asn1_length(buf, offset);
|
||||
|
||||
if (asn1_type == 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;
|
||||
}
|
||||
|
133
tool/mbed/mbed-sdk/libraries/net/https/axTLS/ssl/cert.h
Normal file
133
tool/mbed/mbed-sdk/libraries/net/https/axTLS/ssl/cert.h
Normal file
|
@ -0,0 +1,133 @@
|
|||
#ifndef CERT_H
|
||||
#define CERT_H
|
||||
|
||||
/*
|
||||
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;
|
||||
*/
|
||||
unsigned char default_certificate[] = {
|
||||
0x30, 0x82, 0x03, 0xb8, 0x30, 0x82, 0x03, 0x21, 0xa0, 0x03, 0x02, 0x01,
|
||||
0x02, 0x02, 0x09, 0x00, 0xe1, 0x40, 0xf0, 0x81, 0x55, 0x5d, 0xa4, 0x8f,
|
||||
0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
|
||||
0x05, 0x05, 0x00, 0x30, 0x81, 0x9a, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
|
||||
0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x4b, 0x31, 0x0d, 0x30, 0x0b, 0x06,
|
||||
0x03, 0x55, 0x04, 0x08, 0x13, 0x04, 0x54, 0x65, 0x73, 0x74, 0x31, 0x12,
|
||||
0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x54, 0x65, 0x73,
|
||||
0x74, 0x76, 0x69, 0x6c, 0x6c, 0x65, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03,
|
||||
0x55, 0x04, 0x0a, 0x13, 0x0e, 0x4e, 0x6f, 0x69, 0x73, 0x79, 0x20, 0x41,
|
||||
0x74, 0x6f, 0x6d, 0x20, 0x4c, 0x74, 0x64, 0x31, 0x11, 0x30, 0x0f, 0x06,
|
||||
0x03, 0x55, 0x04, 0x0b, 0x14, 0x08, 0x53, 0x65, 0x63, 0x75, 0x69, 0x72,
|
||||
0x08, 0x08, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
|
||||
0x0c, 0x41, 0x73, 0x68, 0x6c, 0x65, 0x79, 0x20, 0x4d, 0x69, 0x6c, 0x6c,
|
||||
0x73, 0x31, 0x25, 0x30, 0x23, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
|
||||
0x0d, 0x01, 0x09, 0x01, 0x16, 0x16, 0x61, 0x73, 0x68, 0x6c, 0x65, 0x79,
|
||||
0x40, 0x61, 0x73, 0x68, 0x6c, 0x65, 0x79, 0x6d, 0x69, 0x6c, 0x6c, 0x73,
|
||||
0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x30, 0x35,
|
||||
0x31, 0x33, 0x31, 0x37, 0x35, 0x32, 0x34, 0x31, 0x5a, 0x17, 0x0d, 0x34,
|
||||
0x36, 0x30, 0x33, 0x32, 0x31, 0x31, 0x37, 0x35, 0x32, 0x34, 0x31, 0x5a,
|
||||
0x30, 0x81, 0x9a, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
|
||||
0x13, 0x02, 0x55, 0x4b, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04,
|
||||
0x08, 0x13, 0x04, 0x54, 0x65, 0x73, 0x74, 0x31, 0x12, 0x30, 0x10, 0x06,
|
||||
0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x54, 0x65, 0x73, 0x74, 0x76, 0x69,
|
||||
0x6c, 0x6c, 0x65, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a,
|
||||
0x13, 0x0e, 0x4e, 0x6f, 0x69, 0x73, 0x79, 0x20, 0x41, 0x74, 0x6f, 0x6d,
|
||||
0x20, 0x4c, 0x74, 0x64, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04,
|
||||
0x0b, 0x14, 0x08, 0x53, 0x65, 0x63, 0x75, 0x69, 0x72, 0x08, 0x08, 0x31,
|
||||
0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0c, 0x41, 0x73,
|
||||
0x68, 0x6c, 0x65, 0x79, 0x20, 0x4d, 0x69, 0x6c, 0x6c, 0x73, 0x31, 0x25,
|
||||
0x30, 0x23, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09,
|
||||
0x01, 0x16, 0x16, 0x61, 0x73, 0x68, 0x6c, 0x65, 0x79, 0x40, 0x61, 0x73,
|
||||
0x68, 0x6c, 0x65, 0x79, 0x6d, 0x69, 0x6c, 0x6c, 0x73, 0x2e, 0x63, 0x6f,
|
||||
0x6d, 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, 0xb1, 0xe0, 0x59, 0x6a, 0x19, 0x08,
|
||||
0x0d, 0x21, 0x98, 0x79, 0x96, 0x16, 0x2a, 0x5a, 0x5c, 0x20, 0xeb, 0x66,
|
||||
0x1e, 0x9e, 0x1e, 0xc4, 0xef, 0x83, 0x42, 0x15, 0xd8, 0x4b, 0x14, 0xd3,
|
||||
0xe7, 0xba, 0xc8, 0xf6, 0xb4, 0x52, 0xdf, 0x18, 0xa6, 0x6b, 0x8b, 0xca,
|
||||
0x84, 0xdc, 0x21, 0x26, 0xfd, 0x7c, 0xde, 0xbd, 0x2b, 0x64, 0x0d, 0xd3,
|
||||
0x20, 0x7c, 0xe7, 0x0c, 0xfc, 0x3c, 0xa9, 0x09, 0xc0, 0xa7, 0x78, 0x3d,
|
||||
0xe9, 0x48, 0x50, 0x90, 0xd7, 0x3e, 0x46, 0x78, 0x8f, 0xfc, 0xc8, 0xb6,
|
||||
0x89, 0x41, 0x49, 0x15, 0x47, 0x27, 0x4b, 0x46, 0xcb, 0x11, 0x82, 0xd8,
|
||||
0x7b, 0x68, 0xb7, 0xc5, 0x64, 0x70, 0xaf, 0xe6, 0x80, 0x63, 0xfe, 0x53,
|
||||
0x70, 0xee, 0xd2, 0xa9, 0x2c, 0x40, 0x96, 0x9c, 0xd4, 0xa1, 0xcf, 0xd4,
|
||||
0x51, 0x9d, 0xe1, 0xa7, 0xf0, 0xfb, 0xa6, 0x49, 0x4c, 0x00, 0x05, 0xff,
|
||||
0x8f, 0x61, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x02, 0x30,
|
||||
0x81, 0xff, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04,
|
||||
0x14, 0xf1, 0x67, 0xe6, 0xd7, 0x73, 0xe7, 0x12, 0x0a, 0xe1, 0xc3, 0x5f,
|
||||
0x34, 0x97, 0x23, 0x0d, 0xa0, 0xc6, 0x7e, 0x10, 0xe8, 0x30, 0x81, 0xcf,
|
||||
0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x81, 0xc7, 0x30, 0x81, 0xc4, 0x80,
|
||||
0x14, 0xf1, 0x67, 0xe6, 0xd7, 0x73, 0xe7, 0x12, 0x0a, 0xe1, 0xc3, 0x5f,
|
||||
0x34, 0x97, 0x23, 0x0d, 0xa0, 0xc6, 0x7e, 0x10, 0xe8, 0xa1, 0x81, 0xa0,
|
||||
0xa4, 0x81, 0x9d, 0x30, 0x81, 0x9a, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
|
||||
0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x4b, 0x31, 0x0d, 0x30, 0x0b, 0x06,
|
||||
0x03, 0x55, 0x04, 0x08, 0x13, 0x04, 0x54, 0x65, 0x73, 0x74, 0x31, 0x12,
|
||||
0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x54, 0x65, 0x73,
|
||||
0x74, 0x76, 0x69, 0x6c, 0x6c, 0x65, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03,
|
||||
0x55, 0x04, 0x0a, 0x13, 0x0e, 0x4e, 0x6f, 0x69, 0x73, 0x79, 0x20, 0x41,
|
||||
0x74, 0x6f, 0x6d, 0x20, 0x4c, 0x74, 0x64, 0x31, 0x11, 0x30, 0x0f, 0x06,
|
||||
0x03, 0x55, 0x04, 0x0b, 0x14, 0x08, 0x53, 0x65, 0x63, 0x75, 0x69, 0x72,
|
||||
0x08, 0x08, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
|
||||
0x0c, 0x41, 0x73, 0x68, 0x6c, 0x65, 0x79, 0x20, 0x4d, 0x69, 0x6c, 0x6c,
|
||||
0x73, 0x31, 0x25, 0x30, 0x23, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
|
||||
0x0d, 0x01, 0x09, 0x01, 0x16, 0x16, 0x61, 0x73, 0x68, 0x6c, 0x65, 0x79,
|
||||
0x40, 0x61, 0x73, 0x68, 0x6c, 0x65, 0x79, 0x6d, 0x69, 0x6c, 0x6c, 0x73,
|
||||
0x2e, 0x63, 0x6f, 0x6d, 0x82, 0x09, 0x00, 0xe1, 0x40, 0xf0, 0x81, 0x55,
|
||||
0x5d, 0xa4, 0x8f, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05,
|
||||
0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
|
||||
0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00,
|
||||
0x89, 0x79, 0xf2, 0xa8, 0xd3, 0xc7, 0x02, 0x2d, 0x02, 0x68, 0x9a, 0xf1,
|
||||
0xa7, 0x10, 0xa2, 0x2c, 0x52, 0x12, 0xf2, 0x97, 0x39, 0x52, 0x83, 0x69,
|
||||
0xd7, 0xe7, 0x73, 0x1f, 0xf1, 0x02, 0x5e, 0xbe, 0x5f, 0xbe, 0x94, 0xa9,
|
||||
0x4d, 0x8f, 0xb7, 0x3c, 0x52, 0x35, 0x09, 0x0a, 0x69, 0xed, 0x5e, 0x12,
|
||||
0xc9, 0x4d, 0x59, 0xec, 0x47, 0xfa, 0x82, 0xe5, 0x79, 0xbc, 0x17, 0x9d,
|
||||
0xae, 0x02, 0x17, 0xb5, 0xfb, 0xca, 0xc7, 0x42, 0xf4, 0xb5, 0x48, 0x19,
|
||||
0x1c, 0xd4, 0xd6, 0xfb, 0x2a, 0x7b, 0x0e, 0x8b, 0x56, 0xcc, 0x8e, 0x7a,
|
||||
0xa8, 0xaf, 0x4e, 0x5a, 0xa1, 0xf1, 0x78, 0x37, 0x4d, 0x09, 0x03, 0x9a,
|
||||
0xde, 0x4c, 0x87, 0xbe, 0xb1, 0x93, 0x1a, 0x39, 0x9a, 0xbb, 0xa0, 0x5c,
|
||||
0xfe, 0x58, 0x71, 0x62, 0x20, 0x74, 0x04, 0xc5, 0x50, 0x6e, 0x7b, 0xad,
|
||||
0xbe, 0xb0, 0xaa, 0x64, 0xea, 0x48, 0xa7, 0x9f
|
||||
};
|
||||
unsigned int default_certificate_len = 956;
|
||||
|
||||
#endif
|
62
tool/mbed/mbed-sdk/libraries/net/https/axTLS/ssl/config.h
Normal file
62
tool/mbed/mbed-sdk/libraries/net/https/axTLS/ssl/config.h
Normal file
|
@ -0,0 +1,62 @@
|
|||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
#define CONFIG_DEBUG
|
||||
#define CONFIG_STRIP_UNWANTED_SECTIONS 1
|
||||
|
||||
/*
|
||||
* BigInt Options
|
||||
*/
|
||||
#define CONFIG_BIGINT_BARRETT 1
|
||||
#define CONFIG_BIGINT_CRT 1
|
||||
#define CONFIG_INTEGER_32BIT 1
|
||||
|
||||
/*
|
||||
* SSL Library
|
||||
*/
|
||||
#define CONFIG_SSL_ENABLE_CLIENT 1
|
||||
//#define CONFIG_SSL_SKELETON_MODE
|
||||
#define CONFIG_SSL_PROT_LOW 1
|
||||
//#undef CONFIG_SSL_PROT_MEDIUM
|
||||
//#undef CONFIG_SSL_PROT_HIGH
|
||||
#define CONFIG_SSL_USE_DEFAULT_KEY 1
|
||||
#define CONFIG_SSL_PRIVATE_KEY_LOCATION ""
|
||||
#define CONFIG_SSL_PRIVATE_KEY_PASSWORD ""
|
||||
#define CONFIG_SSL_X509_CERT_LOCATION ""
|
||||
#undef CONFIG_SSL_GENERATE_X509_CERT
|
||||
#define CONFIG_SSL_X509_COMMON_NAME ""
|
||||
#define CONFIG_SSL_X509_ORGANIZATION_NAME ""
|
||||
#define CONFIG_SSL_X509_ORGANIZATION_UNIT_NAME ""
|
||||
#undef CONFIG_SSL_ENABLE_V23_HANDSHAKE
|
||||
#undef CONFIG_SSL_HAS_PEM
|
||||
#undef CONFIG_SSL_USE_PKCS12
|
||||
#define CONFIG_SSL_EXPIRY_TIME 24
|
||||
#define CONFIG_X509_MAX_CA_CERTS 1
|
||||
#define CONFIG_SSL_MAX_CERTS 1
|
||||
#undef CONFIG_SSL_CTX_MUTEXING
|
||||
#undef CONFIG_USE_DEV_URANDOM
|
||||
#undef CONFIG_WIN32_USE_CRYPTO_LIB
|
||||
#undef CONFIG_OPENSSL_COMPATIBLE
|
||||
#undef CONFIG_PERFORMANCE_TESTING
|
||||
#undef CONFIG_SSL_TEST
|
||||
#undef CONFIG_AXTLSWRAP
|
||||
#undef CONFIG_AXHTTPD
|
||||
#undef CONFIG_HTTP_STATIC_BUILD
|
||||
#undef CONFIG_HTTP_HAS_CGI
|
||||
#define CONFIG_HTTP_CGI_EXTENSIONS ""
|
||||
#undef CONFIG_HTTP_ENABLE_LUA
|
||||
#define CONFIG_HTTP_LUA_PREFIX ""
|
||||
#undef CONFIG_HTTP_BUILD_LUA
|
||||
#define CONFIG_HTTP_CGI_LAUNCHER ""
|
||||
#undef CONFIG_HTTP_DIRECTORIES
|
||||
#undef CONFIG_HTTP_HAS_AUTHORIZATION
|
||||
#undef CONFIG_HTTP_HAS_IPV6
|
||||
#undef CONFIG_HTTP_ENABLE_DIFFERENT_USER
|
||||
#define CONFIG_HTTP_USER ""
|
||||
#undef CONFIG_HTTP_VERBOSE
|
||||
#undef CONFIG_HTTP_IS_DAEMON
|
||||
#define CONFIG_SSL_CERT_VERIFICATION
|
||||
#define CONFIG_SSL_FULL_MODE
|
||||
|
||||
#define MBED
|
||||
|
||||
#endif
|
176
tool/mbed/mbed-sdk/libraries/net/https/axTLS/ssl/crypto_misc.h
Normal file
176
tool/mbed/mbed-sdk/libraries/net/https/axTLS/ssl/crypto_misc.h
Normal file
|
@ -0,0 +1,176 @@
|
|||
/*
|
||||
* 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"
|
||||
#include "config.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
|
||||
|
||||
#include <time.h>
|
||||
|
||||
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;
|
||||
struct _x509_ctx *next;
|
||||
};
|
||||
|
||||
typedef struct _x509_ctx X509_CTX;
|
||||
typedef struct
|
||||
{
|
||||
X509_CTX *cert[CONFIG_X509_MAX_CA_CERTS];
|
||||
} CA_CERT_CTX;
|
||||
#ifdef CONFIG_SSL_CERT_VERIFICATION
|
||||
|
||||
#endif
|
||||
|
||||
int x509_new(const uint8_t *cert, int *len, X509_CTX **ctx);
|
||||
void x509_free(X509_CTX *x509_ctx);
|
||||
int x509_verify(const CA_CERT_CTX *ca_cert_ctx, const X509_CTX *cert);
|
||||
|
||||
#ifdef CONFIG_SSL_CERT_VERIFICATION
|
||||
#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
|
364
tool/mbed/mbed-sdk/libraries/net/https/axTLS/ssl/gen_cert.c
Normal file
364
tool/mbed/mbed-sdk/libraries/net/https/axTLS/ssl/gen_cert.c
Normal file
|
@ -0,0 +1,364 @@
|
|||
/*
|
||||
* 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
|
||||
|
480
tool/mbed/mbed-sdk/libraries/net/https/axTLS/ssl/loader.c
Normal file
480
tool/mbed/mbed-sdk/libraries/net/https/axTLS/ssl/loader.c
Normal file
|
@ -0,0 +1,480 @@
|
|||
/*
|
||||
* 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"
|
||||
#include "config.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.buf = data;
|
||||
ssl_obj.len = len;
|
||||
ret = do_obj(ssl_ctx, mem_type, &ssl_obj, password);
|
||||
|
||||
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);
|
||||
ssl_obj->len = 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
|
||||
{
|
||||
ssl_obj->len = pem_size;
|
||||
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;
|
||||
|
||||
}
|
323
tool/mbed/mbed-sdk/libraries/net/https/axTLS/ssl/openssl.c
Normal file
323
tool/mbed/mbed-sdk/libraries/net/https/axTLS/ssl/openssl.c
Normal file
|
@ -0,0 +1,323 @@
|
|||
/*
|
||||
* 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
|
280
tool/mbed/mbed-sdk/libraries/net/https/axTLS/ssl/os_port.c
Normal file
280
tool/mbed/mbed-sdk/libraries/net/https/axTLS/ssl/os_port.c
Normal file
|
@ -0,0 +1,280 @@
|
|||
/*
|
||||
* 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"
|
||||
#include <stdio.h>
|
||||
#include "sockets.h"
|
||||
|
||||
static int memory_buf[400];
|
||||
static char enable = 1;
|
||||
static int nb_entries = 0;
|
||||
static int nb_alloc = 0;
|
||||
|
||||
void disable_memory_buf(void)
|
||||
{
|
||||
enable = 0;
|
||||
}
|
||||
void enable_memory_buf(void)
|
||||
{
|
||||
enable = 1;
|
||||
}
|
||||
void init_memory_buf(void)
|
||||
{
|
||||
for(int i = 0; i < 400; i += 2)
|
||||
{
|
||||
memory_buf[i] = -1;
|
||||
memory_buf[i+1] = 0;
|
||||
}
|
||||
}
|
||||
void print_buf_stats(void)
|
||||
{
|
||||
if(enable)
|
||||
{
|
||||
int used = 0;
|
||||
for(int i = 1; i < 400; i += 2)
|
||||
used += memory_buf[i];
|
||||
printf("%d\n", used);
|
||||
}
|
||||
}
|
||||
|
||||
void print_all_buf_stats(void)
|
||||
{
|
||||
int used = 0;
|
||||
for(int i = 1; i < 400; i += 2)
|
||||
used += memory_buf[i];
|
||||
printf("used: %d bytes\n", used);
|
||||
|
||||
for(int i = 0; i < 400; i += 2)
|
||||
if(memory_buf[i] != -1)
|
||||
printf("ptr:%X, size:%d\n", memory_buf[i], memory_buf[i+1]);
|
||||
}
|
||||
|
||||
static void add_entry(void *x, size_t s, const char* f, const int l)
|
||||
{
|
||||
nb_entries++;
|
||||
for(int i = 0; i < 400; i += 2)
|
||||
{
|
||||
if(memory_buf[i] == -1)
|
||||
{
|
||||
if(enable)
|
||||
printf("new ptr:%X, size:%d at %s:%d\n", x, s, f, l);
|
||||
memory_buf[i] = (int)(x);
|
||||
memory_buf[i+1] = s;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(enable)
|
||||
printf("No space left in buffer\n");
|
||||
}
|
||||
|
||||
static void remove_entry(void *x, const char* f, const int l)
|
||||
{
|
||||
nb_entries--;
|
||||
for(int i = 0; i < 400; i += 2)
|
||||
{
|
||||
if(memory_buf[i] == (int)(x))
|
||||
{
|
||||
if(enable)
|
||||
printf("free ptr:%X, size:%d at %s:%d\n", memory_buf[i], memory_buf[i+1], f, l);
|
||||
memory_buf[i] = -1;
|
||||
memory_buf[i+1] = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(enable)
|
||||
printf("not found\n");
|
||||
}
|
||||
|
||||
#ifdef MBED
|
||||
/**
|
||||
* gettimeofday() not in mbed
|
||||
*/
|
||||
EXP_FUNC void STDCALL gettimeofday(struct timeval* t, void* timezone)
|
||||
{
|
||||
t->tv_sec = time(NULL);
|
||||
t->tv_usec = 0; /* 1sec precision only */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
/**
|
||||
* 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
|
||||
#undef free
|
||||
|
||||
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, const char* f, const int l)
|
||||
{
|
||||
if(enable)
|
||||
printf("malloc\t");
|
||||
|
||||
void *x;
|
||||
|
||||
if ((x = malloc(s)) == NULL)
|
||||
exit_now(out_of_mem_str);
|
||||
add_entry(x,s, f, l);
|
||||
print_buf_stats();
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
EXP_FUNC void * STDCALL ax_realloc(void *y, size_t s, const char* f, const int l)
|
||||
{
|
||||
if(enable)
|
||||
printf("realloc\t");
|
||||
|
||||
void *x;
|
||||
|
||||
if ((x = realloc(y, s)) == NULL)
|
||||
exit_now(out_of_mem_str);
|
||||
remove_entry(y, f, l);
|
||||
add_entry(x,s, f, l);
|
||||
print_buf_stats();
|
||||
return x;
|
||||
}
|
||||
|
||||
EXP_FUNC void * STDCALL ax_calloc(size_t n, size_t s, const char* f, const int l)
|
||||
{
|
||||
if(enable)
|
||||
printf("calloc\t");
|
||||
void *x;
|
||||
|
||||
if ((x = calloc(n, s)) == NULL) {
|
||||
exit_now(out_of_mem_str);
|
||||
}
|
||||
|
||||
add_entry(x,n*s, f, l);
|
||||
print_buf_stats();
|
||||
return x;
|
||||
}
|
||||
|
||||
EXP_FUNC void STDCALL ax_free(void *y, const char* f, const int l)
|
||||
{
|
||||
if(enable)
|
||||
printf("free\t");
|
||||
|
||||
remove_entry(y, f, l);
|
||||
print_buf_stats();
|
||||
free(y);
|
||||
}
|
||||
/*
|
||||
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();
|
||||
}
|
||||
|
45
tool/mbed/mbed-sdk/libraries/net/https/axTLS/ssl/os_port.h
Normal file
45
tool/mbed/mbed-sdk/libraries/net/https/axTLS/ssl/os_port.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
#ifndef HEADER_OS_PORT_H
|
||||
#define HEADER_OS_PORT_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "config.h"
|
||||
|
||||
//#include <Thread.h>
|
||||
#define SSL_CTX_MUTEX_TYPE //Mutex
|
||||
#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)
|
||||
|
||||
#define malloc(A) ax_malloc(A, __FILE__, __LINE__)
|
||||
#ifndef realloc
|
||||
#define realloc(A,B) ax_realloc(A,B, __FILE__, __LINE__)
|
||||
#endif
|
||||
#define calloc(A,B) ax_calloc(A,B, __FILE__, __LINE__)
|
||||
#define free(A) ax_free(A, __FILE__, __LINE__)
|
||||
|
||||
#define STDCALL
|
||||
#define EXP_FUNC
|
||||
void init_memory_buf(void);
|
||||
void disable_memory_buf(void);
|
||||
void enable_memory_buf(void);
|
||||
void print_buf_stats(void);
|
||||
void print_all_buf_stats(void);
|
||||
|
||||
EXP_FUNC void * STDCALL ax_malloc(size_t s, const char* f, const int l);
|
||||
EXP_FUNC void * STDCALL ax_realloc(void *y, size_t s, const char* f, const int l);
|
||||
EXP_FUNC void * STDCALL ax_calloc(size_t n, size_t s, const char* f, const int l);
|
||||
EXP_FUNC void STDCALL ax_free(void *y, const char* f, const int l);
|
||||
|
||||
//EXP_FUNC int STDCALL ax_open(const char *pathname, int flags);
|
||||
|
||||
#define SOCKET_READ(A,B,C) lwip_read(A,B,C)
|
||||
#define SOCKET_WRITE(A,B,C) lwip_write(A,B,C)
|
||||
#define SOCKET_CLOSE(A) closesocket(A)
|
||||
#define TTY_FLUSH()
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
194
tool/mbed/mbed-sdk/libraries/net/https/axTLS/ssl/os_port_old.h
Normal file
194
tool/mbed/mbed-sdk/libraries/net/https/axTLS/ssl/os_port_old.h
Normal file
|
@ -0,0 +1,194 @@
|
|||
/*
|
||||
* 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 "os_int.h"
|
||||
#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.
|
||||
*/
|
||||
#pragma comment(lib, "WS2_32.lib")
|
||||
#pragma comment(lib, "AdvAPI32.lib")
|
||||
|
||||
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 /* Not Win32 */
|
||||
|
||||
//#include <unistd.h>
|
||||
//#include <pwd.h>
|
||||
//#include <netdb.h>
|
||||
//#include <dirent.h>
|
||||
//#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
//#include <sys/stat.h>
|
||||
#include <time.h>
|
||||
#include <socket.h>
|
||||
//#include <sys/wait.h>
|
||||
#include <netinet/in.h>
|
||||
#include <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
|
483
tool/mbed/mbed-sdk/libraries/net/https/axTLS/ssl/p12.c
Normal file
483
tool/mbed/mbed-sdk/libraries/net/https/axTLS/ssl/p12.c
Normal file
|
@ -0,0 +1,483 @@
|
|||
/*
|
||||
* 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
|
|
@ -0,0 +1,54 @@
|
|||
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;
|
499
tool/mbed/mbed-sdk/libraries/net/https/axTLS/ssl/ssl.h
Normal file
499
tool/mbed/mbed-sdk/libraries/net/https/axTLS/ssl/ssl.h
Normal file
|
@ -0,0 +1,499 @@
|
|||
/*
|
||||
* 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(SSL_CTX *ssl_ctx, 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 *ssl, 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
|
2324
tool/mbed/mbed-sdk/libraries/net/https/axTLS/ssl/tls1.c
Normal file
2324
tool/mbed/mbed-sdk/libraries/net/https/axTLS/ssl/tls1.c
Normal file
File diff suppressed because it is too large
Load diff
304
tool/mbed/mbed-sdk/libraries/net/https/axTLS/ssl/tls1.h
Normal file
304
tool/mbed/mbed-sdk/libraries/net/https/axTLS/ssl/tls1.h
Normal file
|
@ -0,0 +1,304 @@
|
|||
/*
|
||||
* 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 "os_int.h"
|
||||
#include "crypto.h"
|
||||
#include "crypto_misc.h"
|
||||
|
||||
#include "config.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 2048//16384
|
||||
#define RT_EXTRA 512//1024
|
||||
#define BM_RECORD_OFFSET 5
|
||||
#define BM_ALL_DATA_SIZE (RT_MAX_PLAIN_LENGTH+RT_EXTRA-BM_RECORD_OFFSET)
|
||||
|
||||
#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[MAX_KEYBLOCK_SIZE];
|
||||
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;
|
||||
void *connection;
|
||||
const cipher_info_t *cipher_info;
|
||||
void *encrypt_ctx;
|
||||
void *decrypt_ctx;
|
||||
uint8_t bm_all_data[RT_MAX_PLAIN_LENGTH];
|
||||
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 *ssl, 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_read2(SSL *ssl, uint8_t *data, uint32_t length);
|
||||
int read_record(SSL *ssl);
|
||||
int basic_decrypt(SSL *ssl, uint8_t *buf, int len);
|
||||
int process_data(SSL* ssl, uint8_t *in_data, int len);
|
||||
int ssl_read(SSL *ssl, uint8_t *in_data, int len);
|
||||
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
|
414
tool/mbed/mbed-sdk/libraries/net/https/axTLS/ssl/tls1_clnt.c
Normal file
414
tool/mbed/mbed-sdk/libraries/net/https/axTLS/ssl/tls1_clnt.c
Normal file
|
@ -0,0 +1,414 @@
|
|||
/*
|
||||
* 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 *ssl, int client_fd, const
|
||||
uint8_t *session_id, uint8_t sess_id_size)
|
||||
{
|
||||
SSL_CTX *ssl_ctx = ssl->ssl_ctx;
|
||||
ssl_new(ssl, 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 = read_record(ssl);
|
||||
if (ret < SSL_OK)
|
||||
break;
|
||||
ret = process_data(ssl, NULL, 0);
|
||||
if (ret < SSL_OK)
|
||||
break;
|
||||
}
|
||||
ssl->hs_status = ret; /* connected? */
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int compute_size_send_client_hello(SSL *ssl)
|
||||
{
|
||||
int size = 6 + SSL_RANDOM_SIZE;
|
||||
size++;
|
||||
if (IS_SET_SSL_FLAG(SSL_SESSION_RESUME))
|
||||
{
|
||||
|
||||
size += ssl->sess_id_size;
|
||||
}
|
||||
size += 2;
|
||||
int i;
|
||||
for (i = 0; i < NUM_PROTOCOLS; i++)
|
||||
size += 2;
|
||||
size += 2;
|
||||
return size+BM_RECORD_OFFSET;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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[0] << 4) + buf[1];
|
||||
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[2], SSL_RANDOM_SIZE);
|
||||
offset = 2 + 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 */
|
478
tool/mbed/mbed-sdk/libraries/net/https/axTLS/ssl/tls1_svr.c
Normal file
478
tool/mbed/mbed-sdk/libraries/net/https/axTLS/ssl/tls1_svr.c
Normal file
|
@ -0,0 +1,478 @@
|
|||
/*
|
||||
* 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 = (buf[4] << 4) + buf[5];
|
||||
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
|
|
@ -0,0 +1 @@
|
|||
#define AXTLS_VERSION "1.4.9"
|
556
tool/mbed/mbed-sdk/libraries/net/https/axTLS/ssl/x509.c
Normal file
556
tool/mbed/mbed-sdk/libraries/net/https/axTLS/ssl/x509.c
Normal file
|
@ -0,0 +1,556 @@
|
|||
/*
|
||||
* 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 <time.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "os_port.h"
|
||||
#include "crypto_misc.h"
|
||||
#include "sockets.h"
|
||||
#include "config.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;
|
||||
*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;
|
||||
#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)
|
||||
{
|
||||
printf("self signed cert\r\n");
|
||||
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\r\n", cert->cert_dn[X509_COMMON_NAME] ?
|
||||
cert->cert_dn[X509_COMMON_NAME] : not_part_of_cert);
|
||||
|
||||
printf("Organization (O):\t\t");
|
||||
printf("%s\r\n", cert->cert_dn[X509_ORGANIZATION] ?
|
||||
cert->cert_dn[X509_ORGANIZATION] : not_part_of_cert);
|
||||
|
||||
printf("Organizational Unit (OU):\t");
|
||||
printf("%s\r\n", cert->cert_dn[X509_ORGANIZATIONAL_UNIT] ?
|
||||
cert->cert_dn[X509_ORGANIZATIONAL_UNIT] : not_part_of_cert);
|
||||
|
||||
printf("=== CERTIFICATE ISSUED BY ===\r\n");
|
||||
printf("Common Name (CN):\t\t");
|
||||
printf("%s\r\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\r\n", cert->ca_cert_dn[X509_ORGANIZATION] ?
|
||||
cert->ca_cert_dn[X509_ORGANIZATION] : not_part_of_cert);
|
||||
|
||||
printf("Organizational Unit (OU):\t");
|
||||
printf("%s\r\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\r\n", ctime(&cert->not_before));
|
||||
printf("Not After:\t\t\t%s\r\n", ctime(&cert->not_after));
|
||||
printf("RSA bitsize:\t\t\t%d\r\n", cert->rsa_ctx->num_octets*8);
|
||||
printf("Sig Type:\t\t\t");
|
||||
switch (cert->sig_type)
|
||||
{
|
||||
case SIG_TYPE_MD5:
|
||||
printf("MD5\r\n");
|
||||
break;
|
||||
case SIG_TYPE_SHA1:
|
||||
printf("SHA1\r\n");
|
||||
break;
|
||||
case SIG_TYPE_MD2:
|
||||
printf("MD2\r\n");
|
||||
break;
|
||||
default:
|
||||
printf("Unrecognized: %d\r\n", cert->sig_type);
|
||||
break;
|
||||
}
|
||||
|
||||
if (ca_cert_ctx)
|
||||
{
|
||||
printf("Verify:\t\t\t\t%s\r\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 */
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue