Skip to content

Commit

Permalink
axtls: updates library to v2.1.5
Browse files Browse the repository at this point in the history
  • Loading branch information
flsobral committed Apr 23, 2021
1 parent 080bb94 commit abad4e9
Show file tree
Hide file tree
Showing 40 changed files with 1,877 additions and 728 deletions.
1 change: 1 addition & 0 deletions TotalCrossVM/src/axtls/aes.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
*/

#include <string.h>
#include "os_port.h"
#include "crypto.h"

#define rot1(x) (((x) << 24) | ((x) >> 8))
Expand Down
200 changes: 162 additions & 38 deletions TotalCrossVM/src/axtls/asn1.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2007-2015, Cameron Rich
* Copyright (c) 2007-2019, Cameron Rich
*
* All rights reserved.
*
Expand Down Expand Up @@ -38,7 +38,9 @@
#if !defined(_WIN32_WCE)
#include <time.h>
#endif
#include "ssl.h"
#include "os_port.h"
#include "crypto.h"
#include "crypto_misc.h"

/* 1.2.840.113549.1.1 OID prefix - handle the following */
/* md5WithRSAEncryption(4) */
Expand Down Expand Up @@ -80,8 +82,18 @@ static const uint8_t sig_subject_alt_name[] =
0x55, 0x1d, 0x11
};

/* CN, O, OU */
static const uint8_t g_dn_types[] = { 3, 10, 11 };
static const uint8_t sig_basic_constraints[] =
{
0x55, 0x1d, 0x13
};

static const uint8_t sig_key_usage[] =
{
0x55, 0x1d, 0x0f
};

/* CN, O, OU, L, C, ST */
static const uint8_t g_dn_types[] = { 3, 10, 11, 7, 6, 8 };

uint32_t get_asn1_length(const uint8_t *buf, int *offset)
{
Expand Down Expand Up @@ -117,6 +129,7 @@ int asn1_next_obj(const uint8_t *buf, int *offset, int obj_type)
{
if (buf[*offset] != obj_type)
return X509_NOT_OK;

(*offset)++;
return get_asn1_length(buf, offset);
}
Expand All @@ -141,12 +154,12 @@ int asn1_skip_obj(const uint8_t *buf, int *offset, int obj_type)
* 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 asn1_get_big_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;
goto end_big_int;

if (len > 1 && buf[*offset] == 0x00) /* ignore the negative byte */
{
Expand All @@ -158,10 +171,91 @@ int asn1_get_int(const uint8_t *buf, int *offset, uint8_t **object)
memcpy(*object, &buf[*offset], len);
*offset += len;

end_int_array:
end_big_int:
return len;
}

/**
* Read an integer value for ASN.1 data
*/
int asn1_get_int(const uint8_t *buf, int *offset, int32_t *val)
{
int res = X509_OK;
int len;
int i;

if ((len = asn1_next_obj(buf, offset, ASN1_INTEGER)) < 0 ||
len > sizeof(int32_t))
{
res = X509_NOT_OK;
goto end_int;
}

*val = 0;
for (i = 0; i < len; i++)
{
*val <<= 8;
*val |= buf[(*offset)++];
}

end_int:
return res;
}

/**
* Read an boolean value for ASN.1 data
*/
int asn1_get_bool(const uint8_t *buf, int *offset, bool *val)
{
int res = X509_OK;

if (asn1_next_obj(buf, offset, ASN1_BOOLEAN) != 1)
{
res = X509_NOT_OK;
goto end_bool;
}

/* DER demands that "If the encoding represents the boolean value TRUE,
its single contents octet shall have all eight bits set to one."
Thus only 0 and 255 are valid encoded values. */
*val = buf[(*offset)++] == 0xFF;

end_bool:
return res;
}

/**
* Convert an ASN.1 bit string into a 32 bit integer. Used for key usage
*/
int asn1_get_bit_string_as_int(const uint8_t *buf, int *offset, uint32_t *val)
{
int res = X509_OK;
int len, i;

if ((len = asn1_next_obj(buf, offset, ASN1_BIT_STRING)) < 0 || len > 5)
{
res = X509_NOT_OK;
goto end_bit_string_as_int;
}

/* number of bits left unused in the final byte of content */
(*offset)++;
len--;
*val = 0;

/* not sure why key usage doesn't used proper DER spec version */
for (i = len-1; i >= 0; --i)
{
*val <<= 8;
*val |= buf[(*offset) + i];
}

*offset += len;

end_bit_string_as_int:
return res;
}

/**
* Get all the RSA private key specifics from an ASN.1 encoded file
*/
Expand All @@ -187,19 +281,19 @@ int asn1_get_private_key(const uint8_t *buf, int len, RSA_CTX **rsa_ctx)
/* 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);
mod_len = asn1_get_big_int(buf, &offset, &modulus);
pub_len = asn1_get_big_int(buf, &offset, &pub_exp);
priv_len = asn1_get_big_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);
p_len = asn1_get_big_int(buf, &offset, &p);
q_len = asn1_get_big_int(buf, &offset, &q);
dP_len = asn1_get_big_int(buf, &offset, &dP);
dQ_len = asn1_get_big_int(buf, &offset, &dQ);
qInv_len = asn1_get_big_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;
Expand All @@ -225,14 +319,14 @@ int asn1_get_private_key(const uint8_t *buf, int len, RSA_CTX **rsa_ctx)
}

/**
* Get the time of a certificate. Ignore hours/minutes/seconds.
* Get the time of a certificate.
*/
static int asn1_get_utc_time(const uint8_t *buf, int *offset, time_t *t)
{
int ret = X509_NOT_OK, len, t_offset, abs_year;
struct tm tm;

/* see http://tools.ietf.org/html/rfc5280#section-4.1.2.5 */
/* see http://tools.ietf.org/html/rfc5280#section-4.1.2.5.1 */
if (buf[*offset] == ASN1_UTC_TIME)
{
(*offset)++;
Expand All @@ -243,13 +337,16 @@ static int asn1_get_utc_time(const uint8_t *buf, int *offset, time_t *t)
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 */
/*if (tm.tm_year < 50) */ /* ignore 1951-2050 part of spec */
{
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');
tm.tm_hour = (buf[t_offset+6] - '0')*10 + (buf[t_offset+7] - '0');
tm.tm_min = (buf[t_offset+8] - '0')*10 + (buf[t_offset+9] - '0');
tm.tm_sec = (buf[t_offset+10] - '0')*10 + (buf[t_offset+11] - '0');
*t = mktime(&tm);
*offset += len;
ret = X509_OK;
Expand All @@ -274,13 +371,14 @@ static int asn1_get_utc_time(const uint8_t *buf, int *offset, time_t *t)
}
else
{
tm.tm_year = abs_year - 1900;
tm.tm_mon = (buf[t_offset+4] - '0')*10 + (buf[t_offset+5] - '0') - 1;
tm.tm_mday = (buf[t_offset+6] - '0')*10 + (buf[t_offset+7] - '0');
tm.tm_hour = (buf[t_offset+8] - '0')*10 + (buf[t_offset+9] - '0');
tm.tm_min = (buf[t_offset+10] - '0')*10 + (buf[t_offset+11] - '0');
tm.tm_sec = (buf[t_offset+12] - '0')*10 + (buf[t_offset+13] - '0');
*t = mktime(&tm);
tm.tm_year = abs_year - 1900;
tm.tm_mon = (buf[t_offset+4] - '0')*10 +
(buf[t_offset+5] - '0') - 1;
tm.tm_mday = (buf[t_offset+6] - '0')*10 + (buf[t_offset+7] - '0');
tm.tm_hour = (buf[t_offset+8] - '0')*10 + (buf[t_offset+9] - '0');
tm.tm_min = (buf[t_offset+10] - '0')*10 + (buf[t_offset+11] - '0');
tm.tm_sec = (buf[t_offset+12] - '0')*10 + (buf[t_offset+13] - '0');
*t = mktime(&tm);
}

*offset += len;
Expand All @@ -291,19 +389,12 @@ static int asn1_get_utc_time(const uint8_t *buf, int *offset, time_t *t)
}

/**
* Get the version type of a certificate (which we don't actually care about)
* Get the version type of a certificate
*/
int asn1_version(const uint8_t *cert, int *offset, X509_CTX *x509_ctx)
int asn1_version(const uint8_t *cert, int *offset, int *val)
{
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;
return asn1_get_int(cert, offset, val);
}

/**
Expand Down Expand Up @@ -453,8 +544,8 @@ int asn1_public_key(const uint8_t *cert, int *offset, X509_CTX *x509_ctx)
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);
mod_len = asn1_get_big_int(cert, offset, &modulus);
pub_len = asn1_get_big_int(cert, offset, &pub_exp);

RSA_pub_key_new(&x509_ctx->rsa_ctx, modulus, mod_len, pub_exp, pub_len);

Expand Down Expand Up @@ -574,7 +665,7 @@ int asn1_find_oid(const uint8_t* cert, int* offset,
return 0;
}

int asn1_find_subjectaltname(const uint8_t* cert, int offset)
int asn1_is_subject_alt_name(const uint8_t *cert, int offset)
{
if (asn1_find_oid(cert, &offset, sig_subject_alt_name,
sizeof(sig_subject_alt_name)))
Expand All @@ -585,6 +676,39 @@ int asn1_find_subjectaltname(const uint8_t* cert, int offset)
return 0;
}

int asn1_is_basic_constraints(const uint8_t *cert, int offset)
{
if (asn1_find_oid(cert, &offset, sig_basic_constraints,
sizeof(sig_basic_constraints)))
{
return offset;
}

return 0;
}

int asn1_is_key_usage(const uint8_t *cert, int offset)
{
if (asn1_find_oid(cert, &offset, sig_key_usage,
sizeof(sig_key_usage)))
{
return offset;
}

return 0;
}

bool asn1_is_critical_ext(const uint8_t *buf, int *offset)
{
/* critical is optional */
bool res = false;

if (asn1_next_obj(buf, offset, ASN1_BOOLEAN) == 1)
res = buf[(*offset)++] == 0xFF;

return res;
}

#endif /* CONFIG_SSL_CERT_VERIFICATION */

/**
Expand Down
8 changes: 8 additions & 0 deletions TotalCrossVM/src/axtls/axtls.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#ifndef HEADER_AXTLS_H
#define HEADER_AXTLS_H

#include "axssl_config.h"
#include "os_port.h"
#include "crypto.h"

#endif
Loading

0 comments on commit abad4e9

Please sign in to comment.