From fea1f1d6e57d149ca3fe1ad479d6cd278589b5cd Mon Sep 17 00:00:00 2001 From: John Safranek Date: Mon, 18 Nov 2019 17:02:19 -0800 Subject: [PATCH 1/8] Maintenance: ASN.1 1. Reject as an error any ASN.1 length value that is multibyte of length 0. --- wolfcrypt/src/asn.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index fe1635a70..de59cdeca 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -179,7 +179,11 @@ WOLFSSL_LOCAL int GetLength_ex(const byte* input, word32* inOutIdx, int* len, } b = input[idx++]; - if (b >= ASN_LONG_LENGTH) { + if (b == ASN_LONG_LENGTH) { + WOLFSSL_MSG("GetLength bad length length"); + return ASN_PARSE_E; + } + else if (b > ASN_LONG_LENGTH) { word32 bytes = b & 0x7F; if ((idx + bytes) > maxIdx) { /* for reading bytes */ From 9753bf627b735368b2077e8dbbcc24cc129ed3b9 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Thu, 21 Nov 2019 13:23:27 -0800 Subject: [PATCH 2/8] Maintenance: ASN.1 1. Remove the function Word32ToString and replace with calls to XSNPRINTF(). 2. Simplify DecodePolicyOID(), which converts an ASN.1 OID to a text string in the form a.b.ccccc.d... Return an error if it gets too long. --- wolfcrypt/src/asn.c | 97 ++++++++++++++------------------------------- 1 file changed, 29 insertions(+), 68 deletions(-) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index de59cdeca..2a3d15dd8 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -7616,88 +7616,49 @@ static int DecodeNameConstraints(const byte* input, int sz, DecodedCert* cert) #if (defined(WOLFSSL_CERT_EXT) && !defined(WOLFSSL_SEP)) || defined(OPENSSL_EXTRA) -static int Word32ToString(char* d, word32 number) -{ - int i = 0; - - if (d != NULL) { - word32 order = 1000000000; - word32 digit; - - if (number == 0) { - d[i++] = '0'; - } - else { - while (order) { - digit = number / order; - if (i > 0 || digit != 0) { - d[i++] = (char)digit + '0'; - } - if (digit != 0) - number %= digit * order; - if (order > 1) - order /= 10; - else - order = 0; - } - } - d[i] = 0; - } - - return i; -} - - /* Decode ITU-T X.690 OID format to a string representation * return string length */ int DecodePolicyOID(char *out, word32 outSz, const byte *in, word32 inSz) { - word32 val, idx = 0, nb_bytes; - size_t w_bytes = 0; + word32 val, inIdx = 0, outIdx = 0; + int w = 0; if (out == NULL || in == NULL || outSz < 4 || inSz < 2) return BAD_FUNC_ARG; - /* first two byte must be interpreted as : 40 * int1 + int2 */ - val = (word16)in[idx++]; + /* The first byte expands into b/40 dot b%40. */ + val = in[inIdx++]; - w_bytes = Word32ToString(out, val / 40); - out[w_bytes++] = '.'; - w_bytes += Word32ToString(out+w_bytes, val % 40); - - while (idx < inSz) { - /* init value */ - val = 0; - nb_bytes = 0; - - /* check that output size is ok */ - if (w_bytes > (outSz - 3)) - return BUFFER_E; + w = XSNPRINTF(out, outSz, "%u.%u", val / 40, val % 40); + if (w < 0) + goto exit; + outIdx += w; + val = 0; + do { + /* extract the next OID digit from in to val */ /* first bit is used to set if value is coded on 1 or multiple bytes */ - while ((in[idx+nb_bytes] & 0x80)) - nb_bytes++; - - if (!nb_bytes) - val = (word32)(in[idx++] & 0x7f); - else { - word32 base = 1, tmp = nb_bytes; - - while (tmp != 0) { - val += (word32)(in[idx+tmp] & 0x7f) * base; - base *= 128; - tmp--; - } - val += (word32)(in[idx++] & 0x7f) * base; - - idx += nb_bytes; + if (in[inIdx] & 0x80) { + val += in[inIdx] & 0x7F; + val *= 128; } + else { + /* write val as text into out */ + val += in[inIdx]; + w = XSNPRINTF(out + outIdx, outSz - outIdx, ".%u", val); + if (w < 0) + goto exit; + outIdx += w; + val = 0; + } + inIdx++; + } while (inIdx < inSz); + out[outIdx] = 0; - out[w_bytes++] = '.'; - w_bytes += Word32ToString(out+w_bytes, val); - } + w = (int)outIdx; - return (int)w_bytes; +exit: + return w; } #endif /* WOLFSSL_CERT_EXT && !WOLFSSL_SEP */ From d389133f336d707f3498718ef50767e91865325e Mon Sep 17 00:00:00 2001 From: John Safranek Date: Fri, 22 Nov 2019 16:01:55 -0800 Subject: [PATCH 3/8] Maintenance: ASN.1 1. Update the ParseCRL function to always obey the length value of a tag. --- wolfcrypt/src/asn.c | 101 +++++++++++++++++++++++++++----------------- 1 file changed, 63 insertions(+), 38 deletions(-) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 2a3d15dd8..e511d5f6b 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -15726,52 +15726,39 @@ int VerifyCRL_Signature(SignatureCtx* sigCtx, const byte* toBeSigned, return 0; } -/* prase crl buffer into decoded state, 0 on success */ -int ParseCRL(DecodedCRL* dcrl, const byte* buff, word32 sz, void* cm) + +static int ParseCRL_CertList(DecodedCRL* dcrl, const byte* buf, + word32* inOutIdx, int sz) { - int version, len, doNextDate = 1; - word32 oid, idx = 0, dateIdx, localIdx; - Signer* ca = NULL; - SignatureCtx sigCtx; - byte tag; + word32 oid, dateIdx, idx, checkIdx; + int version, doNextDate = 1; + byte tag; - WOLFSSL_MSG("ParseCRL"); - - /* raw crl hash */ - /* hash here if needed for optimized comparisons - * wc_Sha sha; - * wc_InitSha(&sha); - * wc_ShaUpdate(&sha, buff, sz); - * wc_ShaFinal(&sha, dcrl->crlHash); */ - - if (GetSequence(buff, &idx, &len, sz) < 0) - return ASN_PARSE_E; - - dcrl->certBegin = idx; - - if (GetSequence(buff, &idx, &len, sz) < 0) - return ASN_PARSE_E; - dcrl->sigIndex = len + idx; + if (dcrl == NULL || inOutIdx == NULL || buf == NULL) { + return BAD_FUNC_ARG; + } /* may have version */ - localIdx = idx; - if (GetASNTag(buff, &localIdx, &tag, sz) == 0 && tag == ASN_INTEGER) { - if (GetMyVersion(buff, &idx, &version, sz) < 0) + idx = *inOutIdx; + + checkIdx = idx; + if (GetASNTag(buf, &checkIdx, &tag, sz) == 0 && tag == ASN_INTEGER) { + if (GetMyVersion(buf, &idx, &version, sz) < 0) return ASN_PARSE_E; } - if (GetAlgoId(buff, &idx, &oid, oidIgnoreType, sz) < 0) + if (GetAlgoId(buf, &idx, &oid, oidIgnoreType, sz) < 0) return ASN_PARSE_E; - if (GetNameHash(buff, &idx, dcrl->issuerHash, sz) < 0) + if (GetNameHash(buf, &idx, dcrl->issuerHash, sz) < 0) return ASN_PARSE_E; - if (GetBasicDate(buff, &idx, dcrl->lastDate, &dcrl->lastDateFormat, sz) < 0) + if (GetBasicDate(buf, &idx, dcrl->lastDate, &dcrl->lastDateFormat, sz) < 0) return ASN_PARSE_E; dateIdx = idx; - if (GetBasicDate(buff, &idx, dcrl->nextDate, &dcrl->nextDateFormat, sz) < 0) + if (GetBasicDate(buf, &idx, dcrl->nextDate, &dcrl->nextDateFormat, sz) < 0) { #ifndef WOLFSSL_NO_CRL_NEXT_DATE (void)dateIdx; @@ -15792,22 +15779,60 @@ int ParseCRL(DecodedCRL* dcrl, const byte* buff, word32 sz, void* cm) #endif } - localIdx = idx; + checkIdx = idx; if (idx != dcrl->sigIndex && - GetASNTag(buff, &localIdx, &tag, sz) == 0 && tag != CRL_EXTENSIONS) { - if (GetSequence(buff, &idx, &len, sz) < 0) - return ASN_PARSE_E; + GetASNTag(buf, &checkIdx, &tag, sz) == 0 && tag != CRL_EXTENSIONS) { + int len; + + if (GetSequence(buf, &idx, &len, sz) < 0) + return ASN_PARSE_E; len += idx; while (idx < (word32)len) { - if (GetRevoked(buff, &idx, dcrl, sz) < 0) + if (GetRevoked(buf, &idx, dcrl, len) < 0) return ASN_PARSE_E; } } - if (idx != dcrl->sigIndex) - idx = dcrl->sigIndex; /* skip extensions */ + *inOutIdx = idx; + + return 0; +} + + +/* prase crl buffer into decoded state, 0 on success */ +int ParseCRL(DecodedCRL* dcrl, const byte* buff, word32 sz, void* cm) +{ + int len; + word32 idx = 0; + Signer* ca = NULL; + SignatureCtx sigCtx; + + WOLFSSL_MSG("ParseCRL"); + + /* raw crl hash */ + /* hash here if needed for optimized comparisons + * wc_Sha sha; + * wc_InitSha(&sha); + * wc_ShaUpdate(&sha, buff, sz); + * wc_ShaFinal(&sha, dcrl->crlHash); */ + + if (GetSequence(buff, &idx, &len, sz) < 0) + return ASN_PARSE_E; + + dcrl->certBegin = idx; + /* Normalize sz for the length inside the outer sequence. */ + sz = len + idx; + + if (GetSequence(buff, &idx, &len, sz) < 0) + return ASN_PARSE_E; + dcrl->sigIndex = len + idx; + + if (ParseCRL_CertList(dcrl, buff, &idx, idx + len) < 0) + return ASN_PARSE_E; + + idx = dcrl->sigIndex; if (GetAlgoId(buff, &idx, &dcrl->signatureOID, oidSigType, sz) < 0) return ASN_PARSE_E; From 5e0ca866dfe3fa5a9c0b17ec84eac27a431c9409 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Mon, 25 Nov 2019 14:17:24 -0800 Subject: [PATCH 4/8] Maintenance: ASN.1 1. For certificates, when copying a member of a container, one shouldn't read beyond the enclosing context. --- wolfcrypt/src/asn.c | 54 +++++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index e511d5f6b..60e789008 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -4551,6 +4551,8 @@ static int GetCertHeader(DecodedCert* cert) if (GetSequence(cert->source, &cert->srcIdx, &len, cert->maxIdx) < 0) return ASN_PARSE_E; + /* Reset the max index for the size indicated in the outer wrapper. */ + cert->maxIdx = len + cert->srcIdx; cert->certBegin = cert->srcIdx; if (GetSequence(cert->source, &cert->srcIdx, &len, cert->maxIdx) < 0) @@ -4558,11 +4560,11 @@ static int GetCertHeader(DecodedCert* cert) cert->sigIndex = len + cert->srcIdx; if (GetExplicitVersion(cert->source, &cert->srcIdx, &cert->version, - cert->maxIdx) < 0) + cert->sigIndex) < 0) return ASN_PARSE_E; if (GetSerialNumber(cert->source, &cert->srcIdx, cert->serial, - &cert->serialSz, cert->maxIdx) < 0) + &cert->serialSz, cert->sigIndex) < 0) return ASN_PARSE_E; return ret; @@ -4868,7 +4870,7 @@ int CalcHashId(const byte* data, word32 len, byte* hash) } /* process NAME, either issuer or subject */ -static int GetName(DecodedCert* cert, int nameType) +static int GetName(DecodedCert* cert, int nameType, int maxIdx) { int length; /* length of all distinguished names */ int dummy; @@ -4897,19 +4899,19 @@ static int GetName(DecodedCert* cert, int nameType) hash = cert->subjectHash; } - if (cert->srcIdx >= cert->maxIdx) { + if (cert->srcIdx >= (word32)maxIdx) { return BUFFER_E; } localIdx = cert->srcIdx; - if (GetASNTag(cert->source, &localIdx, &tag, cert->maxIdx) < 0) { + if (GetASNTag(cert->source, &localIdx, &tag, maxIdx) < 0) { return ASN_PARSE_E; } if (tag == ASN_OBJECT_ID) { WOLFSSL_MSG("Trying optional prefix..."); - if (SkipObjectId(cert->source, &cert->srcIdx, cert->maxIdx) < 0) + if (SkipObjectId(cert->source, &cert->srcIdx, maxIdx) < 0) return ASN_PARSE_E; WOLFSSL_MSG("Got optional prefix"); } @@ -4918,7 +4920,7 @@ static int GetName(DecodedCert* cert, int nameType) * calculated over the entire DER encoding of the Name field, including * the tag and length. */ idx = cert->srcIdx; - if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0) + if (GetSequence(cert->source, &cert->srcIdx, &length, maxIdx) < 0) return ASN_PARSE_E; ret = CalcHashId(&cert->source[idx], length + cert->srcIdx - idx, hash); @@ -4952,19 +4954,19 @@ static int GetName(DecodedCert* cert, int nameType) int strLen = 0; byte id = 0; - if (GetSet(cert->source, &cert->srcIdx, &dummy, cert->maxIdx) < 0) { + if (GetSet(cert->source, &cert->srcIdx, &dummy, maxIdx) < 0) { WOLFSSL_MSG("Cert name lacks set header, trying sequence"); } - if (GetSequence(cert->source, &cert->srcIdx, &dummy, cert->maxIdx) <= 0) + if (GetSequence(cert->source, &cert->srcIdx, &dummy, maxIdx) <= 0) return ASN_PARSE_E; - ret = GetASNObjectId(cert->source, &cert->srcIdx, &oidSz, cert->maxIdx); + ret = GetASNObjectId(cert->source, &cert->srcIdx, &oidSz, maxIdx); if (ret != 0) return ret; /* make sure there is room for joint */ - if ((cert->srcIdx + sizeof(joint)) > cert->maxIdx) + if ((cert->srcIdx + sizeof(joint)) > (word32)maxIdx) return ASN_PARSE_E; XMEMCPY(joint, &cert->source[cert->srcIdx], sizeof(joint)); @@ -4974,7 +4976,7 @@ static int GetName(DecodedCert* cert, int nameType) cert->srcIdx += 3; id = joint[2]; if (GetHeader(cert->source, &b, &cert->srcIdx, &strLen, - cert->maxIdx, 1) < 0) { + maxIdx, 1) < 0) { return ASN_PARSE_E; } @@ -5128,7 +5130,7 @@ static int GetName(DecodedCert* cert, int nameType) b = cert->source[cert->srcIdx++]; /* encoding */ if (GetLength(cert->source, &cert->srcIdx, &strLen, - cert->maxIdx) < 0) + maxIdx) < 0) return ASN_PARSE_E; /* Check for jurisdiction of incorporation country name */ @@ -5190,7 +5192,7 @@ static int GetName(DecodedCert* cert, int nameType) cert->srcIdx += oidSz + 1; if (GetLength(cert->source, &cert->srcIdx, &strLen, - cert->maxIdx) < 0) + maxIdx) < 0) return ASN_PARSE_E; if (strLen > (int)(ASN_NAME_MAX - idx)) { @@ -5808,7 +5810,7 @@ static int GetDateInfo(const byte* source, word32* idx, const byte** pDate, return 0; } -static int GetDate(DecodedCert* cert, int dateType, int verify) +static int GetDate(DecodedCert* cert, int dateType, int verify, int maxIdx) { int ret, length; const byte *datePtr = NULL; @@ -5823,7 +5825,7 @@ static int GetDate(DecodedCert* cert, int dateType, int verify) startIdx = cert->srcIdx; ret = GetDateInfo(cert->source, &cert->srcIdx, &datePtr, &format, - &length, cert->maxIdx); + &length, maxIdx); if (ret < 0) return ret; @@ -5850,18 +5852,20 @@ static int GetDate(DecodedCert* cert, int dateType, int verify) return 0; } -static int GetValidity(DecodedCert* cert, int verify) +static int GetValidity(DecodedCert* cert, int verify, int maxIdx) { int length; int badDate = 0; - if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0) + if (GetSequence(cert->source, &cert->srcIdx, &length, maxIdx) < 0) return ASN_PARSE_E; - if (GetDate(cert, BEFORE, verify) < 0) + maxIdx = cert->srcIdx + length; + + if (GetDate(cert, BEFORE, verify, maxIdx) < 0) badDate = ASN_BEFORE_DATE_E; /* continue parsing */ - if (GetDate(cert, AFTER, verify) < 0) + if (GetDate(cert, AFTER, verify, maxIdx) < 0) return ASN_AFTER_DATE_E; if (badDate != 0) @@ -5943,19 +5947,21 @@ int wc_GetPubX509(DecodedCert* cert, int verify, int* badDate) WOLFSSL_MSG("Got Cert Header"); + /* Using the sigIndex as the upper bound because that's where the + * actual certificate data ends. */ if ( (ret = GetAlgoId(cert->source, &cert->srcIdx, &cert->signatureOID, - oidSigType, cert->maxIdx)) < 0) + oidSigType, cert->sigIndex)) < 0) return ret; WOLFSSL_MSG("Got Algo ID"); - if ( (ret = GetName(cert, ISSUER)) < 0) + if ( (ret = GetName(cert, ISSUER, cert->sigIndex)) < 0) return ret; - if ( (ret = GetValidity(cert, verify)) < 0) + if ( (ret = GetValidity(cert, verify, cert->sigIndex)) < 0) *badDate = ret; - if ( (ret = GetName(cert, SUBJECT)) < 0) + if ( (ret = GetName(cert, SUBJECT, cert->sigIndex)) < 0) return ret; WOLFSSL_MSG("Got Subject Name"); From 1ac0b1fc0be035acb6b0b6a8bec4b93641913f17 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Mon, 25 Nov 2019 15:09:08 -0800 Subject: [PATCH 5/8] Maintenance: ASN.1 1. Undo an earlier change with respect to parsing a long length with length zero. If BerToDer is disabled, this will be treated as a zero length. With BerToDer enabled, the conversion will do the right thing. --- wolfcrypt/src/asn.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 60e789008..a5c2ccac6 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -179,11 +179,7 @@ WOLFSSL_LOCAL int GetLength_ex(const byte* input, word32* inOutIdx, int* len, } b = input[idx++]; - if (b == ASN_LONG_LENGTH) { - WOLFSSL_MSG("GetLength bad length length"); - return ASN_PARSE_E; - } - else if (b > ASN_LONG_LENGTH) { + if (b >= ASN_LONG_LENGTH) { word32 bytes = b & 0x7F; if ((idx + bytes) > maxIdx) { /* for reading bytes */ From 55540c6bd3966479a67f2fe5314b4ddcb3bff7e7 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Mon, 25 Nov 2019 16:13:01 -0800 Subject: [PATCH 6/8] Replace a compile option check around some filenames for certificate testing. --- wolfcrypt/test/test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index a64f07ed9..347ea3fb9 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -9247,7 +9247,7 @@ byte GetEntropy(ENTROPY_CMD cmd, byte* out) #endif /* HAVE_ECC */ #ifndef NO_RSA - #ifdef WOLFSSL_CERT_GEN + #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT) static const char* otherCertDerFile = CERT_PREFIX "othercert.der"; static const char* certDerFile = CERT_PREFIX "cert.der"; #endif From cc722468be359a6386a87dd1bd44f0b4997ce3fc Mon Sep 17 00:00:00 2001 From: John Safranek Date: Wed, 27 Nov 2019 10:43:51 -0800 Subject: [PATCH 7/8] Maintenance: ASN.1 1. Add an additional check in GetCertHeader() to see that sigIndex is bounded by maxIdx. --- wolfcrypt/src/asn.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index a5c2ccac6..c2f12a10b 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -4553,7 +4553,10 @@ static int GetCertHeader(DecodedCert* cert) if (GetSequence(cert->source, &cert->srcIdx, &len, cert->maxIdx) < 0) return ASN_PARSE_E; + cert->sigIndex = len + cert->srcIdx; + if (cert->sigIndex > cert->maxIdx) + return ASN_PARSE_E; if (GetExplicitVersion(cert->source, &cert->srcIdx, &cert->version, cert->sigIndex) < 0) From 44fc3e14b113fbb2d78b1434c364b31d8a3aed2d Mon Sep 17 00:00:00 2001 From: John Safranek Date: Wed, 4 Dec 2019 10:26:37 -0800 Subject: [PATCH 8/8] Maintenance: ASN.1 1. Fix some preprocessor flag checking for function EncodePolicyOID. It also needs to be available for OpenSSL Compatibility. 2. Fix for a name string for a test that can get left in or out incorrectly. --- wolfcrypt/src/asn.c | 165 ++++++++++++++++++----------------- wolfcrypt/test/test.c | 3 +- wolfssl/wolfcrypt/settings.h | 3 +- wolfssl/wolfcrypt/types.h | 3 +- 4 files changed, 90 insertions(+), 84 deletions(-) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index c2f12a10b..7f4993c48 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -11414,87 +11414,6 @@ static int SetExtKeyUsage(Cert* cert, byte* output, word32 outSz, byte input) return idx; } -/* Encode OID string representation to ITU-T X.690 format */ -int EncodePolicyOID(byte *out, word32 *outSz, const char *in, void* heap) -{ - word32 val, idx = 0, nb_val; - char *token, *str, *ptr; - word32 len; - - (void)heap; - - if (out == NULL || outSz == NULL || *outSz < 2 || in == NULL) - return BAD_FUNC_ARG; - - /* duplicate string (including terminator) */ - len = (word32)XSTRLEN(in); - str = (char *)XMALLOC(len+1, heap, DYNAMIC_TYPE_TMP_BUFFER); - if (str == NULL) - return MEMORY_E; - XMEMCPY(str, in, len+1); - - nb_val = 0; - - /* parse value, and set corresponding Policy OID value */ - token = XSTRTOK(str, ".", &ptr); - while (token != NULL) - { - val = (word32)XATOI(token); - - if (nb_val == 0) { - if (val > 2) { - XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER); - return ASN_OBJECT_ID_E; - } - - out[idx] = (byte)(40 * val); - } - else if (nb_val == 1) { - if (val > 127) { - XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER); - return ASN_OBJECT_ID_E; - } - - if (idx > *outSz) { - XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER); - return BUFFER_E; - } - - out[idx++] += (byte)val; - } - else { - word32 tb = 0, x; - int i = 0; - byte oid[MAX_OID_SZ]; - - while (val >= 128) { - x = val % 128; - val /= 128; - oid[i++] = (byte) (((tb++) ? 0x80 : 0) | x); - } - - if ((idx+(word32)i) > *outSz) { - XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER); - return BUFFER_E; - } - - oid[i] = (byte) (((tb++) ? 0x80 : 0) | val); - - /* push value in the right order */ - while (i >= 0) - out[idx++] = oid[i--]; - } - - token = XSTRTOK(NULL, ".", &ptr); - nb_val++; - } - - *outSz = idx; - - XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER); - return 0; -} - /* encode Certificate Policies, return total bytes written * each input value must be ITU-T X.690 formatted : a.b.c... * input must be an array of values with a NULL terminated for the latest @@ -13914,6 +13833,90 @@ int wc_SetDatesBuffer(Cert* cert, const byte* der, int derSz) #endif /* WOLFSSL_CERT_GEN */ +#if (defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_EXT)) \ + || defined(OPENSSL_EXTRA) +/* Encode OID string representation to ITU-T X.690 format */ +int EncodePolicyOID(byte *out, word32 *outSz, const char *in, void* heap) +{ + word32 val, idx = 0, nb_val; + char *token, *str, *ptr; + word32 len; + + (void)heap; + + if (out == NULL || outSz == NULL || *outSz < 2 || in == NULL) + return BAD_FUNC_ARG; + + /* duplicate string (including terminator) */ + len = (word32)XSTRLEN(in); + str = (char *)XMALLOC(len+1, heap, DYNAMIC_TYPE_TMP_BUFFER); + if (str == NULL) + return MEMORY_E; + XMEMCPY(str, in, len+1); + + nb_val = 0; + + /* parse value, and set corresponding Policy OID value */ + token = XSTRTOK(str, ".", &ptr); + while (token != NULL) + { + val = (word32)XATOI(token); + + if (nb_val == 0) { + if (val > 2) { + XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER); + return ASN_OBJECT_ID_E; + } + + out[idx] = (byte)(40 * val); + } + else if (nb_val == 1) { + if (val > 127) { + XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER); + return ASN_OBJECT_ID_E; + } + + if (idx > *outSz) { + XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER); + return BUFFER_E; + } + + out[idx++] += (byte)val; + } + else { + word32 tb = 0, x; + int i = 0; + byte oid[MAX_OID_SZ]; + + while (val >= 128) { + x = val % 128; + val /= 128; + oid[i++] = (byte) (((tb++) ? 0x80 : 0) | x); + } + + if ((idx+(word32)i) > *outSz) { + XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER); + return BUFFER_E; + } + + oid[i] = (byte) (((tb++) ? 0x80 : 0) | val); + + /* push value in the right order */ + while (i >= 0) + out[idx++] = oid[i--]; + } + + token = XSTRTOK(NULL, ".", &ptr); + nb_val++; + } + + *outSz = idx; + + XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER); + return 0; +} +#endif /* WOLFSSL_CERT_EXT || OPENSSL_EXTRA */ + #endif /* !NO_CERTS */ #ifdef HAVE_ECC diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 347ea3fb9..e03b4f99b 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -9247,7 +9247,8 @@ byte GetEntropy(ENTROPY_CMD cmd, byte* out) #endif /* HAVE_ECC */ #ifndef NO_RSA - #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT) + #if defined(WOLFSSL_CERT_GEN) || \ + (defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_TEST_CERT)) static const char* otherCertDerFile = CERT_PREFIX "othercert.der"; static const char* certDerFile = CERT_PREFIX "cert.der"; #endif diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index 7fc294862..cc4f7c835 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -528,7 +528,8 @@ #define XSTRNCMP(s1,s2,n) strncmp((s1),(s2),(n)) #define XSTRNCAT(s1,s2,n) strncat((s1),(s2),(n)) #define XSTRNCASECMP(s1,s2,n) _strnicmp((s1),(s2),(n)) - #if defined(WOLFSSL_CERT_EXT) || defined(HAVE_ALPN) + #if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA) \ + || defined(HAVE_ALPN) #define XSTRTOK strtok_r #endif #endif diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index 16d7bb01e..709894e44 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -493,7 +493,8 @@ #endif /* _MSC_VER || __CYGWIN__ || __MINGW32__ */ #endif /* USE_WINDOWS_API */ - #if defined(WOLFSSL_CERT_EXT) || defined(HAVE_ALPN) + #if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA) \ + || defined(HAVE_ALPN) /* use only Thread Safe version of strtok */ #if defined(USE_WOLF_STRTOK) #define XSTRTOK(s1,d,ptr) wc_strtok((s1),(d),(ptr))