Move ASN.1 APIs out to separate file: ssl_asn1.c

Implementations of ASN.1 APIs reworked.

Added tests.

Added wolfssl_bn_set_neg for ASN.1 code.
Added wolfssl_sk_new_type() and wolfssl_sk_pop_type() to generically
handle creating and popping a stack of elements of a type.

No longer freeing pathlen field of ASN1 OBJECT in
wolfSSL_X509_EXTENSION_free(). This is happening in
wolfSSL_ASN1_OBJECT_free().
Stop wolfSSL_i2d_X509_NAME_canon from double freeing ASN.1 STRING's data
field.

Fixed up GetFormattedTime() to be better code.
Added ASN_CLASS_MASK to mask off the class part of an ASN.1 tag.
NO_ASN_TIME means no implementation to get the current time. Disable
features that won'r work without time.
This commit is contained in:
Sean Parkinson
2023-03-22 15:46:50 +10:00
parent 6bed0c5757
commit 8489095057
12 changed files with 6650 additions and 4108 deletions

View File

@ -19,6 +19,7 @@ MAINTAINERCLEANFILES+= $(FIPS_FILES)
EXTRA_DIST += src/bio.c
EXTRA_DIST += src/conf.c
EXTRA_DIST += src/pk.c
EXTRA_DIST += src/ssl_asn1.c
EXTRA_DIST += src/ssl_bn.c
EXTRA_DIST += src/ssl_misc.c
EXTRA_DIST += src/x509.c

2870
src/ssl.c

File diff suppressed because it is too large Load Diff

4026
src/ssl_asn1.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -50,6 +50,35 @@
* Constructor/Destructor/Initializer APIs
******************************************************************************/
#if defined(OPENSSL_EXTRA) && !defined(NO_ASN)
/* Set big number to be negative.
*
* @param [in, out] bn Big number to make negative.
* @param [in] neg Whether number is negative.
* @return 1 on success.
* @return -1 when bn or internal representation of bn is NULL.
*/
static int wolfssl_bn_set_neg(WOLFSSL_BIGNUM* bn, int neg)
{
int ret = 1;
if (BN_IS_NULL(bn)) {
WOLFSSL_MSG("bn NULL error");
ret = -1;
}
#if !defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_SP_INT_NEGATIVE)
else if (neg) {
mp_setneg((mp_int*)bn->internal);
}
else {
((mp_int*)bn->internal)->sign = MP_ZPOS;
}
#endif
return ret;
}
#endif /* OPENSSL_EXTRA && !NO_ASN */
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
/* Get the internal representation value into an MP integer.
*

View File

@ -231,10 +231,6 @@ void wolfSSL_X509_EXTENSION_free(WOLFSSL_X509_EXTENSION* x)
return;
if (x->obj != NULL) {
if (x->obj->pathlen != NULL) {
wolfSSL_ASN1_INTEGER_free(x->obj->pathlen);
x->obj->pathlen = NULL;
}
wolfSSL_ASN1_OBJECT_free(x->obj);
}
@ -10078,7 +10074,6 @@ int wolfSSL_i2d_X509_NAME_canon(WOLFSSL_X509_NAME* name, unsigned char** out)
return WOLFSSL_FATAL_ERROR;
}
totalBytes += ret;
wolfSSL_OPENSSL_free(cano_data->data);
wolfSSL_ASN1_STRING_free(cano_data);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -13657,31 +13657,27 @@ int GetFormattedTime(void* currTime, byte* buf, word32 len)
if (ts->tm_year >= 50 && ts->tm_year < 100) {
year = ts->tm_year;
}
else if (ts->tm_year >= 100 && ts->tm_year < 150) {
year = ts->tm_year - 100;
}
else {
WOLFSSL_MSG("unsupported year range");
return BAD_FUNC_ARG;
year = ts->tm_year - 100;
}
mon = ts->tm_mon + 1;
day = ts->tm_mday;
hour = ts->tm_hour;
mini = ts->tm_min;
sec = ts->tm_sec;
#if defined(WOLF_C89)
if (len < 14) {
WOLFSSL_MSG("buffer for GetFormattedTime is too short.");
return BUFFER_E;
}
ret = XSPRINTF((char*)buf,
#if defined(WOLF_C89)
if (len < ASN_UTC_TIME_SIZE) {
WOLFSSL_MSG("buffer for GetFormattedTime is too short.");
return BUFFER_E;
}
ret = XSPRINTF((char*)buf,
"%02d%02d%02d%02d%02d%02dZ", year, mon, day,
hour, mini, sec);
#else
ret = XSNPRINTF((char*)buf, len,
#else
ret = XSNPRINTF((char*)buf, len,
"%02d%02d%02d%02d%02d%02dZ", year, mon, day,
hour, mini, sec);
#endif
#endif
}
else {
/* GeneralizedTime */
@ -13691,19 +13687,19 @@ int GetFormattedTime(void* currTime, byte* buf, word32 len)
hour = ts->tm_hour;
mini = ts->tm_min;
sec = ts->tm_sec;
#if defined(WOLF_C89)
if (len < 16) {
WOLFSSL_MSG("buffer for GetFormattedTime is too short.");
return BUFFER_E;
}
ret = XSPRINTF((char*)buf,
#if defined(WOLF_C89)
if (len < ASN_GENERALIZED_TIME_SIZE) {
WOLFSSL_MSG("buffer for GetFormattedTime is too short.");
return BUFFER_E;
}
ret = XSPRINTF((char*)buf,
"%4d%02d%02d%02d%02d%02dZ", year, mon, day,
hour, mini, sec);
#else
ret = XSNPRINTF((char*)buf, len,
#else
ret = XSNPRINTF((char*)buf, len,
"%4d%02d%02d%02d%02d%02dZ", year, mon, day,
hour, mini, sec);
#endif
#endif
}
return ret;
@ -14630,48 +14626,58 @@ word32 SetAlgoID(int algoOID, byte* output, int type, int curveSz)
int sz;
int ret = 0;
int o = 0;
const byte* algoName = 0;
word32 algoSz = 0;
CALLOC_ASNSETDATA(dataASN, algoIdASN_Length, ret, NULL);
/* Set the OID and OID type to encode. */
SetASN_OID(&dataASN[ALGOIDASN_IDX_OID], algoOID, type);
/* Hashes, signatures not ECC and keys not RSA put put NULL tag. */
if (!(type == oidHashType ||
(type == oidSigType && !IsSigAlgoECC(algoOID)) ||
(type == oidKeyType && algoOID == RSAk))) {
/* Don't put out NULL DER item. */
dataASN[ALGOIDASN_IDX_NULL].noOut = 1;
}
if (algoOID == DSAk) {
/* Don't include SEQUENCE for DSA keys. */
o = 1;
}
else if (curveSz > 0) {
/* Don't put out NULL DER item. */
dataASN[ALGOIDASN_IDX_NULL].noOut = 0;
/* Include space for extra data of length curveSz.
* Subtract 1 for sequence and 1 for length encoding. */
SetASN_Buffer(&dataASN[ALGOIDASN_IDX_NULL], NULL, curveSz - 2);
}
/* Calculate size of encoding. */
ret = SizeASN_Items(algoIdASN + o, dataASN + o, algoIdASN_Length - o, &sz);
if (ret == 0 && output != NULL) {
/* Encode into buffer. */
SetASN_Items(algoIdASN + o, dataASN + o, algoIdASN_Length - o, output);
if (curveSz > 0) {
/* Return size excluding curve data. */
sz = dataASN[o].offset - dataASN[ALGOIDASN_IDX_NULL].offset;
}
}
if (ret == 0) {
/* Return encoded size. */
ret = sz;
algoName = OidFromId(algoOID, type, &algoSz);
if (algoName == NULL) {
WOLFSSL_MSG("Unknown Algorithm");
}
else {
/* Unsigned return type so 0 indicates error. */
ret = 0;
/* Set the OID and OID type to encode. */
SetASN_OID(&dataASN[ALGOIDASN_IDX_OID], algoOID, type);
/* Hashes, signatures not ECC and keys not RSA output NULL tag. */
if (!(type == oidHashType ||
(type == oidSigType && !IsSigAlgoECC(algoOID)) ||
(type == oidKeyType && algoOID == RSAk))) {
/* Don't put out NULL DER item. */
dataASN[ALGOIDASN_IDX_NULL].noOut = 1;
}
if (algoOID == DSAk) {
/* Don't include SEQUENCE for DSA keys. */
o = 1;
}
else if (curveSz > 0) {
/* Don't put out NULL DER item. */
dataASN[ALGOIDASN_IDX_NULL].noOut = 0;
/* Include space for extra data of length curveSz.
* Subtract 1 for sequence and 1 for length encoding. */
SetASN_Buffer(&dataASN[ALGOIDASN_IDX_NULL], NULL, curveSz - 2);
}
/* Calculate size of encoding. */
ret = SizeASN_Items(algoIdASN + o, dataASN + o, algoIdASN_Length - o,
&sz);
if (ret == 0 && output != NULL) {
/* Encode into buffer. */
SetASN_Items(algoIdASN + o, dataASN + o, algoIdASN_Length - o,
output);
if (curveSz > 0) {
/* Return size excluding curve data. */
sz = dataASN[o].offset - dataASN[ALGOIDASN_IDX_NULL].offset;
}
}
if (ret == 0) {
/* Return encoded size. */
ret = sz;
}
else {
/* Unsigned return type so 0 indicates error. */
ret = 0;
}
}
FREE_ASNSETDATA(dataASN, NULL);
@ -35913,6 +35919,9 @@ end:
word32 lastDateSz = MAX_DATE_SIZE;
word32 nextDateSz = MAX_DATE_SIZE;
/* When NO_ASN_TIME is defined, verify not used. */
(void)verify;
WOLFSSL_MSG("ParseCRL");
CALLOC_ASNGETDATA(dataASN, crlASN_Length, ret, dcrl->heap);

View File

@ -6249,6 +6249,11 @@ WOLFSSL_LOCAL int CreateCookieExt(const WOLFSSL* ssl, byte* hash,
WOLFSSL_LOCAL int TranslateErrorToAlert(int err);
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
void* wolfssl_sk_pop_type(WOLFSSL_STACK* sk, WOLF_STACK_TYPE type);
WOLFSSL_STACK* wolfssl_sk_new_type(WOLF_STACK_TYPE type);
#endif
#ifdef __cplusplus
} /* extern "C" */
#endif

View File

@ -228,7 +228,7 @@ typedef struct WOLFSSL_DIST_POINT WOLFSSL_DIST_POINT;
typedef struct WOLFSSL_CONF_CTX WOLFSSL_CONF_CTX;
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
#if defined(OPENSSL_EXTRA)
struct WOLFSSL_OBJ_NAME {
int type;
@ -245,7 +245,7 @@ struct WOLFSSL_BASIC_CONSTRAINTS {
WOLFSSL_ASN1_INTEGER *pathlen;
};
#endif /* OPENSSL_ALL || OPENSSL_EXTRA*/
#endif /* OPENSSL_EXTRA*/
#define WOLFSSL_ASN1_UTCTIME WOLFSSL_ASN1_TIME
#define WOLFSSL_ASN1_GENERALIZEDTIME WOLFSSL_ASN1_TIME
@ -326,8 +326,7 @@ struct WOLFSSL_ASN1_OBJECT {
int grp; /* type of OID, i.e. oidCertPolicyType */
int nid;
unsigned int objSz;
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) || defined(WOLFSSL_QT) || \
defined(WOLFSSL_APACHE_HTTPD)
#if defined(OPENSSL_EXTRA)
int ca;
WOLFSSL_ASN1_INTEGER *pathlen;
#endif
@ -342,7 +341,7 @@ struct WOLFSSL_ASN1_OBJECT {
WOLFSSL_ASN1_STRING* dNSName;
WOLFSSL_ASN1_STRING ia5_internal;
WOLFSSL_ASN1_STRING* ia5; /* points to ia5_internal */
#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
#if defined(OPENSSL_ALL)
WOLFSSL_ASN1_STRING* uniformResourceIdentifier;
WOLFSSL_ASN1_STRING iPAddress_internal;
WOLFSSL_ASN1_OTHERNAME* otherName; /* added for Apache httpd */
@ -5032,8 +5031,8 @@ WOLFSSL_API void wolfSSL_EC_POINT_dump(const char *msg, const WOLFSSL_EC_POINT *
WOLFSSL_API const char *wolfSSL_ASN1_tag2str(int tag);
WOLFSSL_API int wolfSSL_ASN1_STRING_print_ex(WOLFSSL_BIO *out, WOLFSSL_ASN1_STRING *str, unsigned long flags);
WOLFSSL_API int wolfSSL_ASN1_STRING_print(WOLFSSL_BIO *out, WOLFSSL_ASN1_STRING *str);
WOLFSSL_API int wolfSSL_ASN1_TIME_get_length(WOLFSSL_ASN1_TIME *t);
WOLFSSL_API unsigned char* wolfSSL_ASN1_TIME_get_data(WOLFSSL_ASN1_TIME *t);
WOLFSSL_API int wolfSSL_ASN1_TIME_get_length(const WOLFSSL_ASN1_TIME *t);
WOLFSSL_API unsigned char* wolfSSL_ASN1_TIME_get_data(const WOLFSSL_ASN1_TIME *t);
WOLFSSL_API WOLFSSL_ASN1_TIME *wolfSSL_ASN1_TIME_to_generalizedtime(WOLFSSL_ASN1_TIME *t,
WOLFSSL_ASN1_TIME **out);
WOLFSSL_API int wolfSSL_i2c_ASN1_INTEGER(WOLFSSL_ASN1_INTEGER *a, unsigned char **pp);

View File

@ -116,6 +116,7 @@ enum ASN_Tags {
ASN_APPLICATION = 0x40,
ASN_CONTEXT_SPECIFIC = 0x80,
ASN_PRIVATE = 0xC0,
ASN_CLASS_MASK = 0xC0,
CRL_EXTENSIONS = 0xa0,
ASN_EXTENSIONS = 0xa3,

View File

@ -315,8 +315,8 @@ typedef struct WOLFSSL_ASN1_INTEGER {
unsigned int dataMax; /* max size of data buffer */
unsigned int isDynamic:1; /* flag for if data pointer dynamic (1 is yes 0 is no) */
int length;
int type;
int length; /* Length of DER encoding. */
int type; /* ASN.1 type. Includes negative flag. */
} WOLFSSL_ASN1_INTEGER;

View File

@ -2700,6 +2700,13 @@ extern void uITRON4_free(void *p) ;
#define NO_SESSION_CACHE
#endif
#if defined(NO_ASN_TIME) && !defined(WOLFSSL_NO_DEF_TICKET_ENC_CB)
#define WOLFSSL_NO_DEF_TICKET_ENC_CB
#endif
#if defined(NO_ASN_TIME) && defined(HAVE_SESSION_TICKET)
#undef HAVE_SESSION_TICKET
#endif
/* Use static ECC structs for Position Independent Code (PIC) */
#if defined(__IAR_SYSTEMS_ICC__) && defined(__ROPI__)
#define WOLFSSL_ECC_CURVE_STATIC