--- openssl-1.0.2u/crypto/asn1/t_spki.c.cve-2021-3712 2019-12-20 14:02:41.000000000 +0000 +++ openssl-1.0.2u/crypto/asn1/t_spki.c 2022-04-04 20:59:04.817330000 +0000 @@ -90,7 +90,7 @@ } chal = spki->spkac->challenge; if (chal->length) - BIO_printf(out, " Challenge String: %s\n", chal->data); + BIO_printf(out, " Challenge String: %.*s\n", chal->length, chal->data); i = OBJ_obj2nid(spki->sig_algor->algorithm); BIO_printf(out, " Signature Algorithm: %s", (i == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(i)); --- openssl-1.0.2u/crypto/ec/ec_asn1.c.cve-2021-3712 2019-12-20 14:02:41.000000000 +0000 +++ openssl-1.0.2u/crypto/ec/ec_asn1.c 2022-04-04 20:59:04.967334000 +0000 @@ -867,7 +867,10 @@ ret->seed_len = params->curve->seed->length; } - if (!params->order || !params->base || !params->base->data) { + if (params->order == NULL + || params->base == NULL + || params->base->data == NULL + || params->base->length == 0) { ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); goto err; } --- openssl-1.0.2u/crypto/x509v3/v3_cpols.c.cve-2021-3712 2019-12-20 14:02:41.000000000 +0000 +++ openssl-1.0.2u/crypto/x509v3/v3_cpols.c 2022-04-04 20:59:05.187339000 +0000 @@ -423,7 +423,8 @@ qualinfo = sk_POLICYQUALINFO_value(quals, i); switch (OBJ_obj2nid(qualinfo->pqualid)) { case NID_id_qt_cps: - BIO_printf(out, "%*sCPS: %s\n", indent, "", + BIO_printf(out, "%*sCPS: %.*s\n", indent, "", + qualinfo->d.cpsuri->length, qualinfo->d.cpsuri->data); break; @@ -448,7 +449,8 @@ if (notice->noticeref) { NOTICEREF *ref; ref = notice->noticeref; - BIO_printf(out, "%*sOrganization: %s\n", indent, "", + BIO_printf(out, "%*sOrganization: %.*s\n", indent, "", + ref->organization->length, ref->organization->data); BIO_printf(out, "%*sNumber%s: ", indent, "", sk_ASN1_INTEGER_num(ref->noticenos) > 1 ? "s" : ""); @@ -471,7 +473,8 @@ BIO_puts(out, "\n"); } if (notice->exptext) - BIO_printf(out, "%*sExplicit Text: %s\n", indent, "", + BIO_printf(out, "%*sExplicit Text: %.*s\n", indent, "", + notice->exptext->length, notice->exptext->data); } --- openssl-1.0.2u/crypto/x509v3/v3_ncons.c.cve-2021-3712 2019-12-20 14:02:41.000000000 +0000 +++ openssl-1.0.2u/crypto/x509v3/v3_ncons.c 2022-04-04 21:09:06.382040000 +0000 @@ -148,6 +148,27 @@ return ia5ncasecmp(s1, s2, (size_t)(-1)); } +#define IA5_OFFSET_LEN(ia5base, offset) \ + ((ia5base)->length - ((unsigned char *)(offset) - (ia5base)->data)) + +/* Like memchr but for ASN1_IA5STRING. Additionally you can specify the + * starting point to search from + */ +# define ia5memchr(str, start, c) memchr(start, c, IA5_OFFSET_LEN(str, start)) + +/* Like memrrchr but for ASN1_IA5STRING */ +static char *ia5memrchr(ASN1_IA5STRING *str, int c) +{ + int i; + + for (i = str->length; i > 0 && str->data[i - 1] != c; i--); + + if (i == 0) + return NULL; + + return (char *)&str->data[i - 1]; +} + static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) { @@ -413,8 +434,12 @@ char *baseptr = (char *)base->data; char *dnsptr = (char *)dns->data; /* Empty matches everything */ - if (!*baseptr) + if (base->length == 0) return X509_V_OK; + + if (dns->length < base->length) + return X509_V_ERR_PERMITTED_VIOLATION; + /* * Otherwise can add zero or more components on the left so compare RHS * and if dns is longer and expect '.' as preceding character. @@ -425,7 +450,7 @@ return X509_V_ERR_PERMITTED_VIOLATION; } - if (ia5casecmp(baseptr, dnsptr)) + if (ia5ncasecmp(baseptr, dnsptr, base->length)) return X509_V_ERR_PERMITTED_VIOLATION; return X509_V_OK; @@ -436,16 +461,17 @@ { const char *baseptr = (char *)base->data; const char *emlptr = (char *)eml->data; + const char *baseat = ia5memrchr(base, '@'); + const char *emlat = ia5memrchr(eml, '@'); + size_t basehostlen, emlhostlen; - const char *baseat = strchr(baseptr, '@'); - const char *emlat = strchr(emlptr, '@'); if (!emlat) return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; /* Special case: inital '.' is RHS match */ - if (!baseat && (*baseptr == '.')) { + if (!baseat && base->length > 0 && (*baseptr == '.')) { if (eml->length > base->length) { emlptr += eml->length - base->length; - if (ia5casecmp(baseptr, emlptr) == 0) + if (ia5ncasecmp(baseptr, emlptr, base->length) == 0) return X509_V_OK; } return X509_V_ERR_PERMITTED_VIOLATION; @@ -465,8 +491,10 @@ baseptr = baseat + 1; } emlptr = emlat + 1; + basehostlen = IA5_OFFSET_LEN(base, baseptr); + emlhostlen = IA5_OFFSET_LEN(eml, emlptr); /* Just have hostname left to match: case insensitive */ - if (ia5casecmp(baseptr, emlptr)) + if (basehostlen != emlhostlen || ia5ncasecmp(baseptr, emlptr, emlhostlen)) return X509_V_ERR_PERMITTED_VIOLATION; return X509_V_OK; @@ -477,10 +505,13 @@ { const char *baseptr = (char *)base->data; const char *hostptr = (char *)uri->data; - const char *p = strchr(hostptr, ':'); + const char *p = ia5memchr(uri, (char *)uri->data, ':'); int hostlen; /* Check for foo:// and skip past it */ - if (!p || (p[1] != '/') || (p[2] != '/')) + if (p == NULL + || IA5_OFFSET_LEN(uri, p) < 3 + || p[1] != '/' + || p[2] != '/') return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; hostptr = p + 3; @@ -488,10 +519,10 @@ /* Look for a port indicator as end of hostname first */ - p = strchr(hostptr, ':'); + p = ia5memchr(uri, hostptr, ':'); /* Otherwise look for trailing slash */ - if (!p) - p = strchr(hostptr, '/'); + if (p == NULL) + p = ia5memchr(uri, hostptr, '/'); if (!p) hostlen = strlen(hostptr); @@ -502,7 +533,7 @@ return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; /* Special case: inital '.' is RHS match */ - if (*baseptr == '.') { + if (base->length > 0 && *baseptr == '.') { if (hostlen > base->length) { p = hostptr + hostlen - base->length; if (ia5ncasecmp(p, baseptr, base->length) == 0) --- openssl-1.0.2u/crypto/x509v3/v3_pci.c.cve-2021-3712 2019-12-20 14:02:41.000000000 +0000 +++ openssl-1.0.2u/crypto/x509v3/v3_pci.c 2022-04-04 20:59:05.377335000 +0000 @@ -68,7 +68,8 @@ i2a_ASN1_OBJECT(out, pci->proxyPolicy->policyLanguage); BIO_puts(out, "\n"); if (pci->proxyPolicy->policy && pci->proxyPolicy->policy->data) - BIO_printf(out, "%*sPolicy Text: %s\n", indent, "", + BIO_printf(out, "%*sPolicy Text: %.*s\n", indent, "", + pci->proxyPolicy->policy->length, pci->proxyPolicy->policy->data); return 1; } --- openssl-1.0.2u/crypto/x509v3/v3_utl.c.cve-2021-3712 2019-12-20 14:02:41.000000000 +0000 +++ openssl-1.0.2u/crypto/x509v3/v3_utl.c 2022-04-04 20:59:05.447340000 +0000 @@ -609,17 +609,26 @@ /* First some sanity checks */ if (email->type != V_ASN1_IA5STRING) return 1; - if (!email->data || !email->length) + if (email->data == NULL || email->length == 0) + return 1; + if (memchr(email->data, 0, email->length) != NULL) return 1; if (!*sk) *sk = sk_OPENSSL_STRING_new(sk_strcmp); if (!*sk) return 0; + + emtmp = OPENSSL_strndup((char *)email->data, email->length); + if (emtmp == NULL) + return 0; + /* Don't add duplicates */ - if (sk_OPENSSL_STRING_find(*sk, (char *)email->data) != -1) + if (sk_OPENSSL_STRING_find(*sk, emtmp) != -1) { + OPENSSL_free(emtmp); return 1; - emtmp = BUF_strdup((char *)email->data); - if (!emtmp || !sk_OPENSSL_STRING_push(*sk, emtmp)) { + } + if (!sk_OPENSSL_STRING_push(*sk, emtmp)) { + OPENSSL_free(emtmp); /* free on push failure */ X509_email_free(*sk); *sk = NULL; return 0; --- openssl-1.0.2u/crypto/crypto.h.cve-2021-3712 2019-12-20 14:02:41.000000000 +0000 +++ openssl-1.0.2u/crypto/crypto.h 2022-04-04 20:59:04.887339000 +0000 @@ -380,6 +380,8 @@ # define OPENSSL_malloc(num) CRYPTO_malloc((int)num,__FILE__,__LINE__) # define OPENSSL_strdup(str) CRYPTO_strdup((str),__FILE__,__LINE__) +# define OPENSSL_strndup(str, n) \ + CRYPTO_strndup((str), n, __FILE__, __LINE__) # define OPENSSL_realloc(addr,num) \ CRYPTO_realloc((char *)addr,(int)num,__FILE__,__LINE__) # define OPENSSL_realloc_clean(addr,old_num,num) \ @@ -393,6 +395,8 @@ CRYPTO_malloc_locked((int)num,__FILE__,__LINE__) # define OPENSSL_free_locked(addr) CRYPTO_free_locked(addr) +size_t OPENSSL_strnlen(const char *str, size_t maxlen); + const char *SSLeay_version(int type); unsigned long SSLeay(void); @@ -533,6 +537,7 @@ void CRYPTO_free_locked(void *ptr); void *CRYPTO_malloc(int num, const char *file, int line); char *CRYPTO_strdup(const char *str, const char *file, int line); +char *CRYPTO_strndup(const char *str, size_t s, const char *file, int line); void CRYPTO_free(void *ptr); void *CRYPTO_realloc(void *addr, int num, const char *file, int line); void *CRYPTO_realloc_clean(void *addr, int old_num, int num, const char *file, --- openssl-1.0.2u/crypto/mem.c.cve-2021-3712 2019-12-20 14:02:41.000000000 +0000 +++ openssl-1.0.2u/crypto/mem.c 2022-04-04 20:59:05.037333000 +0000 @@ -364,6 +364,24 @@ return ret; } +char *CRYPTO_strndup(const char *str, size_t s, const char* file, int line) +{ + size_t maxlen; + char *ret; + + if (str == NULL) + return NULL; + + maxlen = OPENSSL_strnlen(str, s); + + ret = CRYPTO_malloc(maxlen + 1, file, line); + if (ret) { + memcpy(ret, str, maxlen); + ret[maxlen] = '\0'; + } + return ret; +} + void *CRYPTO_realloc(void *str, int num, const char *file, int line) { void *ret = NULL; --- openssl-1.0.2u/crypto/o_str.c.cve-2021-3712 2019-12-20 14:02:41.000000000 +0000 +++ openssl-1.0.2u/crypto/o_str.c 2022-04-04 20:59:05.107331000 +0000 @@ -114,3 +114,12 @@ return ret; } + +size_t OPENSSL_strnlen(const char *str, size_t maxlen) +{ + const char *p; + + for (p = str; maxlen-- != 0 && *p != '\0'; ++p) ; + + return p - str; +}