diff -up openssl-1.0.2k/crypto/asn1/t_spki.c.read-buff openssl-1.0.2k/crypto/asn1/t_spki.c --- openssl-1.0.2k/crypto/asn1/t_spki.c.read-buff 2017-01-26 14:22:03.000000000 +0100 +++ openssl-1.0.2k/crypto/asn1/t_spki.c 2021-11-19 12:14:17.572630962 +0100 @@ -90,7 +90,7 @@ int NETSCAPE_SPKI_print(BIO *out, NETSCA } 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)); diff -up openssl-1.0.2k/crypto/crypto.h.read-buff openssl-1.0.2k/crypto/crypto.h --- openssl-1.0.2k/crypto/crypto.h.read-buff 2021-11-19 15:10:25.738928196 +0100 +++ openssl-1.0.2k/crypto/crypto.h 2021-11-19 17:51:47.062694785 +0100 @@ -380,6 +380,8 @@ int CRYPTO_is_mem_check_on(void); # 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 @@ int CRYPTO_is_mem_check_on(void); 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_malloc_locked(int num, cons 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, diff -up openssl-1.0.2k/crypto/ec/ec_asn1.c.read-buff openssl-1.0.2k/crypto/ec/ec_asn1.c --- openssl-1.0.2k/crypto/ec/ec_asn1.c.read-buff 2017-01-26 14:22:03.000000000 +0100 +++ openssl-1.0.2k/crypto/ec/ec_asn1.c 2021-11-19 12:14:17.572630962 +0100 @@ -860,7 +860,10 @@ static EC_GROUP *ec_asn1_parameters2grou 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; } diff -up openssl-1.0.2k/crypto/mem.c.read-buff openssl-1.0.2k/crypto/mem.c --- openssl-1.0.2k/crypto/mem.c.read-buff 2021-11-19 15:54:38.937427447 +0100 +++ openssl-1.0.2k/crypto/mem.c 2021-11-19 15:55:21.234906752 +0100 @@ -364,6 +364,24 @@ char *CRYPTO_strdup(const char *str, con 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; diff -up openssl-1.0.2k/crypto/o_str.c.read-buff openssl-1.0.2k/crypto/o_str.c --- openssl-1.0.2k/crypto/o_str.c.read-buff 2021-11-19 15:57:18.812239108 +0100 +++ openssl-1.0.2k/crypto/o_str.c 2021-11-19 15:58:22.704963124 +0100 @@ -114,3 +114,12 @@ int OPENSSL_memcmp(const void *v1, const 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; +} diff -up openssl-1.0.2k/crypto/x509v3/v3_cpols.c.read-buff openssl-1.0.2k/crypto/x509v3/v3_cpols.c --- openssl-1.0.2k/crypto/x509v3/v3_cpols.c.read-buff 2017-01-26 14:22:04.000000000 +0100 +++ openssl-1.0.2k/crypto/x509v3/v3_cpols.c 2021-11-19 12:14:17.572630962 +0100 @@ -423,7 +423,8 @@ static void print_qualifiers(BIO *out, S 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 @@ static void print_notice(BIO *out, USERN 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" : ""); @@ -465,7 +467,8 @@ static void print_notice(BIO *out, USERN 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); } diff -up openssl-1.0.2k/crypto/x509v3/v3_ncons.c.read-buff openssl-1.0.2k/crypto/x509v3/v3_ncons.c --- openssl-1.0.2k/crypto/x509v3/v3_ncons.c.read-buff 2017-01-26 14:22:04.000000000 +0100 +++ openssl-1.0.2k/crypto/x509v3/v3_ncons.c 2021-11-19 12:14:17.573630970 +0100 @@ -107,6 +107,27 @@ ASN1_SEQUENCE(NAME_CONSTRAINTS) = { IMPLEMENT_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE) IMPLEMENT_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS) +#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) { @@ -372,8 +393,12 @@ static int nc_dns(ASN1_IA5STRING *dns, A 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. @@ -384,7 +409,7 @@ static int nc_dns(ASN1_IA5STRING *dns, A return X509_V_ERR_PERMITTED_VIOLATION; } - if (strcasecmp(baseptr, dnsptr)) + if (strncasecmp(baseptr, dnsptr, base->length)) return X509_V_ERR_PERMITTED_VIOLATION; return X509_V_OK; @@ -395,16 +420,17 @@ static int nc_email(ASN1_IA5STRING *eml, { 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 (!strcasecmp(baseptr, emlptr)) + if (!strncasecmp(baseptr, emlptr, base->length)) return X509_V_OK; } return X509_V_ERR_PERMITTED_VIOLATION; @@ -424,8 +450,10 @@ static int nc_email(ASN1_IA5STRING *eml, 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 (strcasecmp(baseptr, emlptr)) + if (basehostlen != emlhostlen || strncasecmp(baseptr, emlptr, emlhostlen)) return X509_V_ERR_PERMITTED_VIOLATION; return X509_V_OK; @@ -436,10 +464,13 @@ static int nc_uri(ASN1_IA5STRING *uri, A { 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; @@ -447,10 +478,10 @@ static int nc_uri(ASN1_IA5STRING *uri, A /* 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); @@ -461,7 +492,7 @@ static int nc_uri(ASN1_IA5STRING *uri, A 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 (!strncasecmp(p, baseptr, base->length)) diff -up openssl-1.0.2k/crypto/x509v3/v3_pci.c.read-buff openssl-1.0.2k/crypto/x509v3/v3_pci.c --- openssl-1.0.2k/crypto/x509v3/v3_pci.c.read-buff 2017-01-26 14:22:04.000000000 +0100 +++ openssl-1.0.2k/crypto/x509v3/v3_pci.c 2021-11-19 12:14:17.572630962 +0100 @@ -68,7 +68,8 @@ static int i2r_pci(X509V3_EXT_METHOD *me 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; } diff -up openssl-1.0.2k/crypto/x509v3/v3_utl.c.read-buff openssl-1.0.2k/crypto/x509v3/v3_utl.c --- openssl-1.0.2k/crypto/x509v3/v3_utl.c.read-buff 2017-01-26 14:22:04.000000000 +0100 +++ openssl-1.0.2k/crypto/x509v3/v3_utl.c 2021-11-19 12:14:17.573630970 +0100 @@ -609,17 +609,26 @@ static int append_ia5(STACK_OF(OPENSSL_S /* 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); X509_email_free(*sk); *sk = NULL; return 0;