diff --git a/src/x509.c b/src/x509.c index cff4175e7..57f79ad20 100644 --- a/src/x509.c +++ b/src/x509.c @@ -1171,7 +1171,8 @@ int wolfSSL_X509V3_EXT_print(WOLFSSL_BIO *out, WOLFSSL_X509_EXTENSION *ext, int nid; const int sz = CTC_NAME_SIZE*2; int rc = WOLFSSL_FAILURE; - char tmp[CTC_NAME_SIZE*2 + 1] = {0}; + char tmp[CTC_NAME_SIZE*2 + 1]; + int tmp_len = 0; WOLFSSL_ENTER("wolfSSL_X509V3_EXT_print"); if ((out == NULL) || (ext == NULL)) { @@ -1198,9 +1199,9 @@ int wolfSSL_X509V3_EXT_print(WOLFSSL_BIO *out, WOLFSSL_X509_EXTENSION *ext, { char isCa[] = "TRUE"; char notCa[] = "FALSE"; - if (XSNPRINTF(tmp, sz, "%*sCA:%s", indent, "", - obj->ca ? isCa : notCa) - >= sz) + if ((tmp_len = XSNPRINTF(tmp, sizeof(tmp), "%*sCA:%s", indent, "", + obj->ca ? isCa : notCa)) + >= (int)sizeof(tmp)) return rc; break; } @@ -1208,8 +1209,8 @@ int wolfSSL_X509V3_EXT_print(WOLFSSL_BIO *out, WOLFSSL_X509_EXTENSION *ext, { WOLFSSL_STACK* sk; char* val; + int val_len; int len; - tmp[0] = '\0'; /* Make sure tmp is null-terminated */ sk = ext->ext_sk; while (sk != NULL) { @@ -1229,17 +1230,22 @@ int wolfSSL_X509V3_EXT_print(WOLFSSL_BIO *out, WOLFSSL_X509_EXTENSION *ext, return rc; } if (sk->next) { - if (XSNPRINTF(val, len, "%*s%s,", - indent, "", str->strData) + if ((val_len = XSNPRINTF(val, len, "%*s%s,", + indent, "", str->strData)) >= len) return rc; } else { - if (XSNPRINTF(val, len, "%*s%s", - indent, "", str->strData) + if ((val_len = XSNPRINTF(val, len, "%*s%s", + indent, "", str->strData)) >= len) return rc; } - XSTRNCAT(tmp, val, len); + if (tmp_len + val_len > (int)sizeof(tmp)) { + XFREE(val, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return rc; + } + XMEMCPY(tmp + tmp_len, val, val_len); + tmp_len += val_len; XFREE(val, NULL, DYNAMIC_TYPE_TMP_BUFFER); } sk = sk->next; @@ -1251,8 +1257,9 @@ int wolfSSL_X509V3_EXT_print(WOLFSSL_BIO *out, WOLFSSL_X509_EXTENSION *ext, { char* asn1str; asn1str = wolfSSL_i2s_ASN1_STRING(NULL, str); - if (XSNPRINTF(tmp, sz, "%*s%s", indent, "", asn1str) - >= sz) + if ((tmp_len = XSNPRINTF( + tmp, sizeof(tmp), "%*s%s", indent, "", asn1str)) + >= (int)sizeof(tmp)) return rc; XFREE(asn1str, NULL, DYNAMIC_TYPE_TMP_BUFFER); break; @@ -1265,12 +1272,13 @@ int wolfSSL_X509V3_EXT_print(WOLFSSL_BIO *out, WOLFSSL_X509_EXTENSION *ext, break; default: - if (XSNPRINTF(tmp, sz, "%*s%s", indent, "", str->strData) - >= sz) + if ((tmp_len = XSNPRINTF( + tmp, sizeof(tmp), "%*s%s", indent, "", str->strData)) + >= (int)sizeof(tmp)) return rc; } - if (wolfSSL_BIO_write(out, tmp, (int)XSTRLEN(tmp)) == (int)XSTRLEN(tmp)) { + if (wolfSSL_BIO_write(out, tmp, tmp_len) == tmp_len) { rc = WOLFSSL_SUCCESS; } (void) flag; @@ -3013,7 +3021,7 @@ unsigned long wolfSSL_X509_NAME_hash(WOLFSSL_X509_NAME* name) char* wolfSSL_X509_get_name_oneline(WOLFSSL_X509_NAME* name, char* in, int sz) { WOLFSSL_X509_NAME_ENTRY* entry; - int nameSz, strSz, count, i; + int nameSz, strSz, str_len, count, i; int totalSz = 0; char *str; char tmpBuf[256]; @@ -3032,7 +3040,6 @@ char* wolfSSL_X509_get_name_oneline(WOLFSSL_X509_NAME* name, char* in, int sz) } #endif - tmpBuf[0] = '\0'; /* Make sure tmpBuf is NULL terminated */ /* Loop through X509 name entries and copy new format to buffer */ count = wolfSSL_X509_NAME_entry_count(name); for (i = 0; i < count; i++) { @@ -3062,14 +3069,16 @@ char* wolfSSL_X509_get_name_oneline(WOLFSSL_X509_NAME* name, char* in, int sz) */ if (i != count - 1) { strSz = (int)XSTRLEN(sn) + nameSz + 4; - totalSz+= strSz; str = (char*)XMALLOC(strSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (str == NULL) { WOLFSSL_MSG("Memory error"); return NULL; } - if (XSNPRINTF(str, strSz, "%s=%s, ", sn, buf) >= strSz) { + if ((str_len = XSNPRINTF(str, strSz, "%s=%s, ", sn, buf)) + >= strSz) + { WOLFSSL_MSG("buffer overrun"); + XFREE(str, NULL, DYNAMIC_TYPE_TMP_BUFFER); return NULL; } } @@ -3078,19 +3087,25 @@ char* wolfSSL_X509_get_name_oneline(WOLFSSL_X509_NAME* name, char* in, int sz) * Add extra strSz for '=' and '\0' characters in XSNPRINTF. */ strSz = (int)XSTRLEN(sn) + nameSz + 2; - totalSz+= strSz; str = (char*)XMALLOC(strSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (str == NULL) { WOLFSSL_MSG("Memory error"); return NULL; } - if (XSNPRINTF(str, strSz, "%s=%s", sn, buf) >= strSz) { + if ((str_len = XSNPRINTF(str, strSz, "%s=%s", sn, buf)) >= strSz) { WOLFSSL_MSG("buffer overrun"); + XFREE(str, NULL, DYNAMIC_TYPE_TMP_BUFFER); return NULL; } } /* Copy string to tmpBuf */ - XSTRNCAT(tmpBuf, str, strSz); + if (totalSz + str_len > (int)sizeof(tmpBuf)) { + WOLFSSL_MSG("buffer overrun"); + XFREE(str, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return NULL; + } + XMEMCPY(tmpBuf + totalSz, str, str_len); + totalSz += str_len; XFREE(str, NULL, DYNAMIC_TYPE_TMP_BUFFER); } @@ -3103,8 +3118,8 @@ char* wolfSSL_X509_get_name_oneline(WOLFSSL_X509_NAME* name, char* in, int sz) } } else { - if (totalSz > sz) { - WOLFSSL_MSG("Memory error"); + if (totalSz + 1 > sz) { + WOLFSSL_MSG("buffer overrun"); return NULL; } } @@ -5258,12 +5273,16 @@ static int X509PrintSubjAltName(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, if (ret == WOLFSSL_SUCCESS && x509->subjAltNameSet && x509->altNames != NULL) { char scratch[MAX_WIDTH]; + int len; - XSNPRINTF(scratch, MAX_WIDTH, "%*s", indent, ""); - if (wolfSSL_BIO_write(bio, scratch, (int)XSTRLEN(scratch)) <= 0) { + len = XSNPRINTF(scratch, MAX_WIDTH, "%*s", indent, ""); + if (len >= MAX_WIDTH) ret = WOLFSSL_FAILURE; + if (ret == WOLFSSL_SUCCESS) { + if (wolfSSL_BIO_write(bio, scratch, (int)XSTRLEN(scratch)) <= 0) { + ret = WOLFSSL_FAILURE; + } } - if (ret == WOLFSSL_SUCCESS) { entry = x509->altNames; while (entry != NULL) { @@ -5276,17 +5295,29 @@ static int X509PrintSubjAltName(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, } if (entry->type == ASN_DNS_TYPE) { - XSNPRINTF(scratch, MAX_WIDTH, "DNS:%s", entry->name); + len = XSNPRINTF(scratch, MAX_WIDTH, "DNS:%s", entry->name); + if (len >= MAX_WIDTH) { + ret = WOLFSSL_FAILURE; + break; + } } #if defined(OPENSSL_ALL) || defined(WOLFSSL_IP_ALT_NAME) else if (entry->type == ASN_IP_TYPE) { - XSNPRINTF(scratch, MAX_WIDTH, "IP Address:%s", + len = XSNPRINTF(scratch, MAX_WIDTH, "IP Address:%s", entry->ipString); + if (len >= MAX_WIDTH) { + ret = WOLFSSL_FAILURE; + break; + } } #endif /* OPENSSL_ALL || WOLFSSL_IP_ALT_NAME */ else if (entry->type == ASN_RFC822_TYPE) { - XSNPRINTF(scratch, MAX_WIDTH, "Email Address:%s", + len = XSNPRINTF(scratch, MAX_WIDTH, "Email Address:%s", entry->name); + if (len >= MAX_WIDTH) { + ret = WOLFSSL_FAILURE; + break; + } } else { WOLFSSL_MSG("Bad alt name type."); @@ -5347,12 +5378,16 @@ static int X509PrintKeyUsage(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int indent) if (ret == WOLFSSL_SUCCESS && x509->keyUsageSet && x509->keyUsage != 0) { char scratch[MAX_WIDTH]; + int len; - XSNPRINTF(scratch, MAX_WIDTH, "%*s", indent, ""); - if (wolfSSL_BIO_write(bio, scratch, (int)XSTRLEN(scratch)) <= 0) { + len = XSNPRINTF(scratch, MAX_WIDTH, "%*s", indent, ""); + if (len >= MAX_WIDTH) ret = WOLFSSL_FAILURE; + if (ret == WOLFSSL_SUCCESS) { + if (wolfSSL_BIO_write(bio, scratch, (int)XSTRLEN(scratch)) <= 0) { + ret = WOLFSSL_FAILURE; + } } - for (; ret == WOLFSSL_SUCCESS && i < sizeof(usages) / sizeof(usages[i]); i++) { if (x509->keyUsage & usages[i]) { @@ -5406,12 +5441,16 @@ static int X509PrintExtendedKeyUsage(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, if (ret == WOLFSSL_SUCCESS && x509->extKeyUsageCount > 0 && x509->extKeyUsage != 0) { char scratch[MAX_WIDTH]; + int len; - XSNPRINTF(scratch, MAX_WIDTH, "%*s", indent, ""); - if (wolfSSL_BIO_write(bio, scratch, (int)XSTRLEN(scratch)) <= 0) { + len = XSNPRINTF(scratch, MAX_WIDTH, "%*s", indent, ""); + if (len >= MAX_WIDTH) ret = WOLFSSL_FAILURE; + if (ret == WOLFSSL_SUCCESS) { + if (wolfSSL_BIO_write(bio, scratch, (int)XSTRLEN(scratch)) <= 0) { + ret = WOLFSSL_FAILURE; + } } - for (; ret == WOLFSSL_SUCCESS && i < sizeof(usages) / sizeof(usages[i]); i++) { if (x509->extKeyUsage & usages[i]) { @@ -5444,63 +5483,62 @@ static int X509PrintSerial(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int indent) unsigned char serial[32]; int sz = sizeof(serial); char scratch[MAX_WIDTH]; + int scratch_len; XMEMSET(serial, 0, sz); if (wolfSSL_X509_get_serial_number(x509, serial, &sz) == WOLFSSL_SUCCESS) { - - XSNPRINTF(scratch, MAX_WIDTH, "%*s%s", indent, "", - "Serial Number:"); - if (wolfSSL_BIO_write(bio, scratch, (int)XSTRLEN(scratch)) <= 0) { + if ((scratch_len = XSNPRINTF(scratch, MAX_WIDTH, "%*sSerial Number:", + indent, "")) >= MAX_WIDTH) + { + WOLFSSL_MSG("buffer overrun"); + return WOLFSSL_FAILURE; + } + if (wolfSSL_BIO_write(bio, scratch, scratch_len) <= 0) { return WOLFSSL_FAILURE; } if (sz > (int)sizeof(byte)) { int i; - char tmp[100]; - int tmpSz = 100; - char val[5]; - int valSz = 5; + int val_len; /* serial is larger than int size so print off hex values */ - XSNPRINTF(scratch, MAX_WIDTH, "\n%*s", indent, ""); - if (wolfSSL_BIO_write(bio, scratch, (int)XSTRLEN(scratch)) - <= 0) { - return WOLFSSL_FAILURE; - } - tmp[0] = '\0'; - for (i = 0; i < sz - 1 && (3 * i) < tmpSz - valSz; i++) { - if (XSNPRINTF(val, sizeof(val), "%02x:", serial[i]) - >= (int)sizeof(val)) - { - WOLFSSL_MSG("buffer overrun"); - return WOLFSSL_FAILURE; - } - val[3] = '\0'; /* make sure is null terminated */ - XSTRNCAT(tmp, val, valSz); - } - if (XSNPRINTF(val, sizeof(val), "%02x\n", serial[i]) - >= (int)sizeof(val)) + if ((scratch_len = XSNPRINTF( + scratch, MAX_WIDTH, "\n%*s", indent, "")) + >= MAX_WIDTH) { WOLFSSL_MSG("buffer overrun"); return WOLFSSL_FAILURE; } - val[3] = '\0'; /* make sure is null terminated */ - XSTRNCAT(tmp, val, valSz); - if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) { + for (i = 0; i < sz; i++) { + if ((val_len = XSNPRINTF( + scratch + scratch_len, sizeof(scratch) - scratch_len, + "%02x%s", serial[i], (i < sz - 1) ? ":" : "\n")) + >= (int)sizeof(scratch) - scratch_len) + { + WOLFSSL_MSG("buffer overrun"); + return WOLFSSL_FAILURE; + } + scratch_len += val_len; + } + if (wolfSSL_BIO_write(bio, scratch, scratch_len) <= 0) { return WOLFSSL_FAILURE; } } - /* if serial can fit into byte than print on the same line */ - else if (sz <= (int)sizeof(byte)) { - XSNPRINTF(scratch, MAX_WIDTH, " %d (0x%x)\n", serial[0], - serial[0]); - if (wolfSSL_BIO_write(bio, scratch, (int)XSTRLEN(scratch)) - <= 0) { + /* if serial can fit into byte then print on the same line */ + else { + if ((scratch_len = XSNPRINTF( + scratch, MAX_WIDTH, " %d (0x%x)\n", serial[0], serial[0])) + >= MAX_WIDTH) + { + WOLFSSL_MSG("buffer overrun"); + return WOLFSSL_FAILURE; + } + if (wolfSSL_BIO_write(bio, scratch, scratch_len) + <= 0) { return WOLFSSL_FAILURE; } } - } return WOLFSSL_SUCCESS; } @@ -5514,150 +5552,225 @@ static int X509PrintExtensions(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int indent) { int ret = WOLFSSL_SUCCESS; char scratch[MAX_WIDTH]; + int scratch_len; int count, i; + char* buf = NULL; count = wolfSSL_X509_get_ext_count(x509); - if (count > 0) { - char* buf = NULL; + if (count <= 0) + return WOLFSSL_SUCCESS; - #ifdef WOLFSSL_CERT_REQ - if (x509->isCSR) { - XSNPRINTF(scratch, MAX_WIDTH, "%*s%s\n", indent, "", - "Requested extensions:"); - } - else - #endif - { - XSNPRINTF(scratch, MAX_WIDTH, "%*s%s\n", indent, "", - "X509v3 extensions:"); - } - if (wolfSSL_BIO_write(bio, scratch, (int)XSTRLEN(scratch)) <= 0) { +#ifdef WOLFSSL_CERT_REQ + if (x509->isCSR) { + if ((scratch_len = XSNPRINTF(scratch, MAX_WIDTH, "%*s%s\n", indent, "", + "Requested extensions:")) >= MAX_WIDTH) { return WOLFSSL_FAILURE; } - - buf = (char*)XMALLOC(MAX_WIDTH-4-indent, x509->heap, - DYNAMIC_TYPE_TMP_BUFFER); - if (buf == NULL) { - return WOLFSSL_FAILURE; - } - - for (i = 0; i < count; i++) { - WOLFSSL_X509_EXTENSION* ext; - - ext = wolfSSL_X509_get_ext(x509, i); - if (ext != NULL) { - WOLFSSL_ASN1_OBJECT* obj; - int nid; - char val[5]; - int valSz = 5; - int len = 0; - word32 j; - - obj = wolfSSL_X509_EXTENSION_get_object(ext); - wolfSSL_OBJ_obj2txt(buf, MAX_WIDTH, obj, 0); - XSNPRINTF(scratch, MAX_WIDTH, "%*s%s%s\n", indent + 4, "", - buf, - (wolfSSL_X509_EXTENSION_get_critical(ext))? ": Critical" : ":"); - - wolfSSL_BIO_write(bio, scratch, (int)XSTRLEN(scratch)); - nid = wolfSSL_OBJ_obj2nid(obj); - switch (nid) { - case NID_subject_alt_name: - ret = X509PrintSubjAltName(bio, x509, indent + 8); - break; - - case NID_subject_key_identifier: - if (!x509->subjKeyIdSet || x509->subjKeyId == NULL || - x509->subjKeyIdSz == 0) { - ret = WOLFSSL_FAILURE; - break; - } - - XSNPRINTF(scratch, sizeof(scratch) - 1, "%*s", - indent + 8, ""); - for (j = 0; j < sizeof(scratch) && j < - (x509->subjKeyIdSz - 1); j++) { - XSNPRINTF(val, valSz - 1, "%02X:", - x509->subjKeyId[j]); - XSTRNCAT(scratch, val, valSz); - } - XSNPRINTF(val, valSz - 1, "%02X\n", x509->subjKeyId[j]); - XSTRNCAT(scratch, val, valSz); - if (wolfSSL_BIO_write(bio, scratch, - (int)XSTRLEN(scratch)) <= 0) { - ret = WOLFSSL_FAILURE; - break; - } - break; - - case NID_authority_key_identifier: - if (!x509->authKeyIdSet || x509->authKeyId == NULL || - x509->authKeyIdSz == 0) { - ret = WOLFSSL_FAILURE; - break; - } - - XSNPRINTF(scratch, sizeof(scratch) - 1, "%*s%s", - indent + 8, "", "keyid"); - for (j = 0; j < x509->authKeyIdSz; j++) { - /* check if buffer is almost full */ - if (XSTRLEN(scratch) >= sizeof(scratch) - valSz) { - if (wolfSSL_BIO_write(bio, scratch, - (int)XSTRLEN(scratch)) <= 0) { - return WOLFSSL_FAILURE; - } - scratch[0] = '\0'; - } - XSNPRINTF(val, valSz - 1, ":%02X", - x509->authKeyId[j]); - XSTRNCAT(scratch, val, valSz); - } - len = (int)XSTRLEN("\n"); - XSTRNCAT(scratch, "\n", len + 1); - if (wolfSSL_BIO_write(bio, scratch, - (int)XSTRLEN(scratch)) <= 0) { - ret = WOLFSSL_FAILURE; - break; - } - break; - - - case NID_basic_constraints: - if (!x509->basicConstSet) { - ret = WOLFSSL_FAILURE; - break; - } - XSNPRINTF(scratch, sizeof(scratch), "%*sCA:%s\n", - indent + 8, "", (x509->isCa)? "TRUE": "FALSE"); - if (wolfSSL_BIO_write(bio, scratch, - (int)XSTRLEN(scratch)) <= 0) { - ret = WOLFSSL_FAILURE; - break; - } - break; - - case NID_key_usage: - ret = X509PrintKeyUsage(bio, x509, indent + 8); - break; - - case NID_ext_key_usage: - ret = X509PrintExtendedKeyUsage(bio, x509, indent + 8); - break; - - default: - /* extension nid not yet supported */ - XSNPRINTF(scratch, MAX_WIDTH, - "%*sNID %d print not yet supported\n", - indent + 8, "", nid); - wolfSSL_BIO_write(bio, scratch, (int)XSTRLEN(scratch)); - } - } - } - - if (buf != NULL) { - XFREE(buf, x509->heap, DYNAMIC_TYPE_TMP_BUFFER); - } } + else +#endif + { + if ((scratch_len = XSNPRINTF(scratch, MAX_WIDTH, "%*s%s\n", indent, "", + "X509v3 extensions:")) >= MAX_WIDTH) { + return WOLFSSL_FAILURE; + } + } + if (wolfSSL_BIO_write(bio, scratch, scratch_len) <= 0) { + return WOLFSSL_FAILURE; + } + + buf = (char*)XMALLOC(MAX_WIDTH-4-indent, x509->heap, + DYNAMIC_TYPE_TMP_BUFFER); + if (buf == NULL) { + return WOLFSSL_FAILURE; + } + + for (i = 0; (i < count) && (ret != WOLFSSL_FAILURE); i++) { + WOLFSSL_X509_EXTENSION* ext; + + ext = wolfSSL_X509_get_ext(x509, i); + if (ext != NULL) { + WOLFSSL_ASN1_OBJECT* obj; + int nid; + char val[6]; + int val_len; + word32 j; + + obj = wolfSSL_X509_EXTENSION_get_object(ext); + if (obj == NULL) { + ret = WOLFSSL_FAILURE; + break; + } + if (wolfSSL_OBJ_obj2txt(buf, MAX_WIDTH, obj, 0) + == WOLFSSL_FAILURE) + { + ret = WOLFSSL_FAILURE; + break; + } + if ((scratch_len = XSNPRINTF( + scratch, MAX_WIDTH, "%*s%s%s\n", indent + 4, "", + buf, + (wolfSSL_X509_EXTENSION_get_critical(ext) + ? ": Critical" + : ":"))) + >= MAX_WIDTH) + { + ret = WOLFSSL_FAILURE; + break; + } + + if (wolfSSL_BIO_write(bio, scratch, scratch_len) <= 0) { + ret = WOLFSSL_FAILURE; + break; + } + nid = wolfSSL_OBJ_obj2nid(obj); + switch (nid) { + case NID_subject_alt_name: + ret = X509PrintSubjAltName(bio, x509, indent + 8); + break; + + case NID_subject_key_identifier: + if (!x509->subjKeyIdSet || x509->subjKeyId == NULL || + x509->subjKeyIdSz == 0) + { + ret = WOLFSSL_FAILURE; + break; + } + + if ((scratch_len = XSNPRINTF( + scratch, sizeof(scratch), + "%*s", indent + 8, "")) >= (int)sizeof(scratch)) + { + ret = WOLFSSL_FAILURE; + break; + } + for (j = 0; j < x509->subjKeyIdSz; j++) { + if ((val_len = XSNPRINTF( + val, sizeof(val), "%02X%s", + x509->subjKeyId[j], + (j < x509->subjKeyIdSz - 1) ? ":" : "\n")) + >= (int)sizeof(val)) + { + ret = WOLFSSL_FAILURE; + break; + } + if (scratch_len + val_len >= (int)sizeof(scratch)) { + if (wolfSSL_BIO_write(bio, scratch, + scratch_len) <= 0) { + ret = WOLFSSL_FAILURE; + break; + } + scratch_len = 0; + } + XMEMCPY(scratch + scratch_len, val, val_len); + scratch_len += val_len; + } + if (ret == WOLFSSL_FAILURE) + break; + if (wolfSSL_BIO_write(bio, scratch, + scratch_len) <= 0) { + ret = WOLFSSL_FAILURE; + break; + } + break; + + case NID_authority_key_identifier: + if (!x509->authKeyIdSet || x509->authKeyId == NULL || + x509->authKeyIdSz == 0) { + ret = WOLFSSL_FAILURE; + break; + } + + if ((scratch_len = XSNPRINTF( + scratch, sizeof(scratch), "%*s%s", + indent + 8, "", "keyid:")) >= (int)sizeof(scratch)) + { + ret = WOLFSSL_FAILURE; + break; + } + for (j = 0; j < x509->authKeyIdSz; j++) { + if ((val_len = XSNPRINTF( + val, sizeof(val), "%02X%s", + x509->authKeyId[j], + (j < x509->authKeyIdSz - 1) ? ":" : "\n")) + >= (int)sizeof(val)) + { + ret = WOLFSSL_FAILURE; + break; + } + if (scratch_len >= (int)sizeof(scratch) - val_len) { + if (wolfSSL_BIO_write(bio, scratch, + scratch_len) <= 0) + { + ret = WOLFSSL_FAILURE; + break; + } + scratch_len = 0; + } + if (scratch_len + val_len >= (int)sizeof(scratch)) { + ret = WOLFSSL_FAILURE; + break; + } + XMEMCPY(scratch + scratch_len, val, val_len); + scratch_len += val_len; + } + if (ret == WOLFSSL_FAILURE) + break; + if (wolfSSL_BIO_write(bio, scratch, + scratch_len) <= 0) { + ret = WOLFSSL_FAILURE; + break; + } + break; + + case NID_basic_constraints: + if (!x509->basicConstSet) { + ret = WOLFSSL_FAILURE; + break; + } + if ((scratch_len = XSNPRINTF( + scratch, sizeof(scratch), + "%*sCA:%s\n", + indent + 8, "", (x509->isCa)? "TRUE": "FALSE")) + >= (int)sizeof(scratch)) + { + ret = WOLFSSL_FAILURE; + break; + } + if (wolfSSL_BIO_write(bio, scratch, + scratch_len) <= 0) { + ret = WOLFSSL_FAILURE; + break; + } + break; + + case NID_key_usage: + ret = X509PrintKeyUsage(bio, x509, indent + 8); + break; + + case NID_ext_key_usage: + ret = X509PrintExtendedKeyUsage(bio, x509, indent + 8); + break; + + default: + /* extension nid not yet supported */ + if ((scratch_len = XSNPRINTF( + scratch, MAX_WIDTH, + "%*sNID %d print not yet supported\n", + indent + 8, "", nid)) >= MAX_WIDTH) + { + ret = WOLFSSL_FAILURE; + break; + } + ret = wolfSSL_BIO_write(bio, scratch, scratch_len); + } + } + } + + if (buf != NULL) { + XFREE(buf, x509->heap, DYNAMIC_TYPE_TMP_BUFFER); + } + return ret; } @@ -5669,76 +5782,137 @@ static int X509PrintExtensions(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int indent) static int X509PrintSignature(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int indent) { char scratch[MAX_WIDTH]; + unsigned char* sig = NULL; int sigSz = 0; + WOLFSSL_ASN1_OBJECT* obj = NULL; + int ret = WOLFSSL_SUCCESS; wolfSSL_X509_get_signature(x509, NULL, &sigSz); - if (sigSz > 0) { - unsigned char* sig; + if (sigSz <= 0) { + return WOLFSSL_SUCCESS; + } + + do { int i; char tmp[100]; + int tmp_len = 0; int sigNid = wolfSSL_X509_get_signature_nid(x509); - WOLFSSL_ASN1_OBJECT* obj; - XSNPRINTF(scratch, MAX_WIDTH, "%*s%s", indent, "", - "Signature Algorithm: "); + if (XSNPRINTF(scratch, MAX_WIDTH, "%*s%s", indent, "", + "Signature Algorithm: ") >= MAX_WIDTH) { + ret = WOLFSSL_FAILURE; + break; + } if (wolfSSL_BIO_write(bio, scratch, (int)XSTRLEN(scratch)) <= 0) { - return WOLFSSL_FAILURE; + ret = WOLFSSL_FAILURE; + break; } obj = wolfSSL_OBJ_nid2obj(sigNid); - wolfSSL_OBJ_obj2txt(scratch, MAX_WIDTH, obj, 0); - wolfSSL_ASN1_OBJECT_free(obj); - XSNPRINTF(tmp, sizeof(tmp) - 1,"%s\n", scratch); - tmp[sizeof(tmp) - 1] = '\0'; - if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) { - return WOLFSSL_FAILURE; + if (obj == NULL) { + ret = WOLFSSL_FAILURE; + break; + } + if (wolfSSL_OBJ_obj2txt(scratch, MAX_WIDTH, obj, 0) + == WOLFSSL_FAILURE) + { + ret = WOLFSSL_FAILURE; + break; + } + if ((tmp_len = XSNPRINTF(tmp, sizeof(tmp),"%s\n", scratch)) + >= (int)sizeof(tmp)) + { + ret = WOLFSSL_FAILURE; + break; + } + if (wolfSSL_BIO_write(bio, tmp, tmp_len) <= 0) { + ret = WOLFSSL_FAILURE; + break; } sig = (unsigned char*)XMALLOC(sigSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (sig == NULL) { - return WOLFSSL_FAILURE; + ret = WOLFSSL_FAILURE; + break; } if (wolfSSL_X509_get_signature(x509, sig, &sigSz) <= 0) { - XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER); - return WOLFSSL_FAILURE; + ret = WOLFSSL_FAILURE; + break; + } + if ((tmp_len = XSNPRINTF(tmp, sizeof(tmp), "%*s", indent + 4, "")) + >= (int)sizeof(tmp)) + { + ret = WOLFSSL_FAILURE; + break; } - XSNPRINTF(tmp, sizeof(tmp) - 1, "%*s", indent + 4, ""); - tmp[sizeof(tmp) - 1] = '\0'; for (i = 0; i < sigSz; i++) { - char val[5]; - int valSz = 5; + char val[6]; + int val_len; if (i == 0) { - XSNPRINTF(val, valSz - 1, "%02x", sig[i]); + if ((val_len = XSNPRINTF(val, sizeof(val), "%02x", sig[i])) + >= (int)sizeof(val)) + { + ret = WOLFSSL_FAILURE; + break; + } } else if (((i % 18) == 0)) { - tmp[sizeof(tmp) - 1] = '\0'; - if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) + if (wolfSSL_BIO_write(bio, tmp, tmp_len) <= 0) { - XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER); - return WOLFSSL_FAILURE; + ret = WOLFSSL_FAILURE; + break; + } + if ((tmp_len = XSNPRINTF(tmp, sizeof(tmp), ":\n%*s", + indent + 4, "")) + >= (int)sizeof(tmp)) + { + ret = WOLFSSL_FAILURE; + break; + } + if ((val_len = XSNPRINTF(val, sizeof(val), "%02x", sig[i])) + >= (int)sizeof(val)) + { + ret = WOLFSSL_FAILURE; + break; } - XSNPRINTF(tmp, sizeof(tmp) - 1, ":\n%*s", indent + 4, ""); - XSNPRINTF(val, valSz - 1, "%02x", sig[i]); } else { - XSNPRINTF(val, valSz - 1, ":%02x", sig[i]); + if ((val_len = XSNPRINTF(val, sizeof(val), ":%02x", sig[i])) + >= (int)sizeof(val)) + { + ret = WOLFSSL_FAILURE; + break; + } } - XSTRNCAT(tmp, val, valSz); + if (val_len >= (int)sizeof(tmp) - tmp_len - 1) { + ret = WOLFSSL_FAILURE; + break; + } + XMEMCPY(tmp + tmp_len, val, val_len); + tmp_len += val_len; + tmp[tmp_len] = 0; } - XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (ret == WOLFSSL_FAILURE) + break; /* print out remaining sig values */ - if ((i > 0) && (((i - 1) % 18) != 0)) { - tmp[sizeof(tmp) - 1] = '\0'; - if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) + if (tmp_len > 0) { + if (wolfSSL_BIO_write(bio, tmp, tmp_len) <= 0) { - return WOLFSSL_FAILURE; + ret = WOLFSSL_FAILURE; + break; } } - } + } while (0); - return WOLFSSL_SUCCESS; + if (obj != NULL) + wolfSSL_ASN1_OBJECT_free(obj); + + if (sig != NULL) + XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER); + + return ret; } @@ -5750,14 +5924,24 @@ static int X509PrintPubKey(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int indent) { char scratch[MAX_WIDTH]; WOLFSSL_EVP_PKEY* pubKey; + int len; + int ret = WOLFSSL_SUCCESS; - XSNPRINTF(scratch, MAX_WIDTH, "%*sPublic Key:\n", indent, ""); - wolfSSL_BIO_write(bio, scratch, (int)XSTRLEN(scratch)); + len = XSNPRINTF(scratch, MAX_WIDTH, "%*sPublic Key:\n", indent, ""); + if (len >= MAX_WIDTH) + return WOLFSSL_FAILURE; + if (wolfSSL_BIO_write(bio, scratch, len) <= 0) + return WOLFSSL_FAILURE; pubKey = wolfSSL_X509_get_pubkey(x509); - wolfSSL_EVP_PKEY_print_public(bio, pubKey, indent + 4, NULL); + if (pubKey == NULL) + return WOLFSSL_FAILURE; + + ret = wolfSSL_EVP_PKEY_print_public(bio, pubKey, indent + 4, NULL); + wolfSSL_EVP_PKEY_free(pubKey); - return WOLFSSL_SUCCESS; + + return ret; } @@ -5770,7 +5954,9 @@ static int X509PrintName(WOLFSSL_BIO* bio, WOLFSSL_X509_NAME* name, { char scratch[MAX_WIDTH]; if (name != NULL) { - XSNPRINTF(scratch, MAX_WIDTH, "%*s%s", indent, "", type); + if (XSNPRINTF(scratch, MAX_WIDTH, "%*s%s", indent, "", type) + >= MAX_WIDTH) + return WOLFSSL_FAILURE; wolfSSL_BIO_write(bio, scratch, (int)XSTRLEN(scratch)); wolfSSL_X509_NAME_print_ex(bio, name, 1, 0); wolfSSL_BIO_write(bio, "\n", (int)XSTRLEN("\n")); @@ -5792,12 +5978,20 @@ static int _wolfSSL_X509_version_print(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, return WOLFSSL_FAILURE; } - XSNPRINTF(scratch, MAX_WIDTH, "%*s%s", indent, "", "Version:"); + if (XSNPRINTF(scratch, MAX_WIDTH, "%*s%s", indent, "", "Version:") + >= MAX_WIDTH) + { + return WOLFSSL_FAILURE; + } if (wolfSSL_BIO_write(bio, scratch, (int)XSTRLEN(scratch)) <= 0) { return WOLFSSL_FAILURE; } - XSNPRINTF(scratch, MAX_WIDTH, " %d (0x%x)\n", version, (byte)version-1); + if (XSNPRINTF(scratch, MAX_WIDTH, " %d (0x%x)\n", version, (byte)version-1) + >= MAX_WIDTH) + { + return WOLFSSL_FAILURE; + } if (wolfSSL_BIO_write(bio, scratch, (int)XSTRLEN(scratch)) <= 0) { return WOLFSSL_FAILURE; } @@ -5816,7 +6010,11 @@ static int X509PrintReqAttributes(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, char scratch[MAX_WIDTH]; int i = 0; - XSNPRINTF(scratch, MAX_WIDTH, "%*s%s", indent, "", "Attributes: \n"); + if (XSNPRINTF(scratch, MAX_WIDTH, "%*s%s", indent, "", "Attributes: \n") + >= MAX_WIDTH) + { + return WOLFSSL_FAILURE; + } if (wolfSSL_BIO_write(bio, scratch, (int)XSTRLEN(scratch)) <= 0) { return WOLFSSL_FAILURE; } @@ -5827,7 +6025,11 @@ static int X509PrintReqAttributes(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int lNameSz = NAME_SZ/4; const byte* data; - wolfSSL_OBJ_obj2txt(lName, lNameSz, attr->object, 0); + if (wolfSSL_OBJ_obj2txt(lName, lNameSz, attr->object, 0) + == WOLFSSL_FAILURE) + { + return WOLFSSL_FAILURE; + } lNameSz = (int)XSTRLEN(lName); data = wolfSSL_ASN1_STRING_get0_data( attr->value->value.asn1_string); @@ -5835,8 +6037,12 @@ static int X509PrintReqAttributes(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, WOLFSSL_MSG("No REQ attribute found when expected"); return WOLFSSL_FAILURE; } - XSNPRINTF(scratch, MAX_WIDTH, "%*s%s%*s:%s\n", indent+4, "", - lName, (NAME_SZ/4)-lNameSz, "", data); + if (XSNPRINTF(scratch, MAX_WIDTH, "%*s%s%*s:%s\n", indent+4, "", + lName, (NAME_SZ/4)-lNameSz, "", data) + >= MAX_WIDTH) + { + return WOLFSSL_FAILURE; + } if (wolfSSL_BIO_write(bio, scratch, (int)XSTRLEN(scratch)) <= 0) { WOLFSSL_MSG("Error writing REQ attribute");