/*
- * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
int tag, xclass, inf;
long max = omax;
- if (!max)
- goto err;
+ if (omax <= 0) {
+ ERR_raise(ERR_LIB_ASN1, ASN1_R_TOO_SMALL);
+ return 0x80;
+ }
ret = (*p & V_ASN1_CONSTRUCTED);
xclass = (*p & V_ASN1_PRIVATE);
i = *p & V_ASN1_PRIMITIVE_TAG;
}
/*
- * class 0 is constructed constructed == 2 for indefinite length constructed
+ * constructed == 2 for indefinite length constructed
*/
void ASN1_put_object(unsigned char **pp, int constructed, int length, int tag,
int xclass)
return ret + length;
}
+void ossl_asn1_string_set_bits_left(ASN1_STRING *str, unsigned int num)
+{
+ str->flags &= ~0x07;
+ str->flags |= ASN1_STRING_FLAG_BITS_LEFT | (num & 0x07);
+}
+
int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str)
{
if (str == NULL)
}
if ((size_t)str->length <= len || str->data == NULL) {
c = str->data;
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+ /* No NUL terminator in fuzzing builds */
+ str->data = OPENSSL_realloc(c, len != 0 ? len : 1);
+#else
str->data = OPENSSL_realloc(c, len + 1);
+#endif
if (str->data == NULL) {
- ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
str->data = c;
return 0;
}
str->length = len;
if (data != NULL) {
memcpy(str->data, data, len);
- /* an allowance for strings :-) */
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+ /* Set the unused byte to something non NUL and printable. */
+ if (len == 0)
+ str->data[len] = '~';
+#else
+ /*
+ * Add a NUL terminator. This should not be necessary - but we add it as
+ * a safety precaution
+ */
str->data[len] = '\0';
+#endif
}
return 1;
}
ASN1_STRING *ret;
ret = OPENSSL_zalloc(sizeof(*ret));
- if (ret == NULL) {
- ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+ if (ret == NULL)
return NULL;
- }
ret->type = type;
return ret;
}
-void asn1_string_embed_free(ASN1_STRING *a, int embed)
+void ossl_asn1_string_embed_free(ASN1_STRING *a, int embed)
{
if (a == NULL)
return;
{
if (a == NULL)
return;
- asn1_string_embed_free(a, a->flags & ASN1_STRING_FLAG_EMBED);
+ ossl_asn1_string_embed_free(a, a->flags & ASN1_STRING_FLAG_EMBED);
}
void ASN1_STRING_clear_free(ASN1_STRING *a)
i = (a->length - b->length);
if (i == 0) {
- i = memcmp(a->data, b->data, a->length);
+ if (a->length != 0)
+ i = memcmp(a->data, b->data, a->length);
if (i == 0)
return a->type - b->type;
else
}
#endif
-char *sk_ASN1_UTF8STRING2text(STACK_OF(ASN1_UTF8STRING) *text, const char *sep,
- size_t max_len /* excluding NUL terminator */)
+/* |max_len| excludes NUL terminator and may be 0 to indicate no restriction */
+char *ossl_sk_ASN1_UTF8STRING2text(STACK_OF(ASN1_UTF8STRING) *text,
+ const char *sep, size_t max_len)
{
int i;
ASN1_UTF8STRING *current;
char *result = NULL;
char *p;
- if (!ossl_assert(sep != NULL))
- return NULL;
+ if (sep == NULL)
+ sep = "";
sep_len = strlen(sep);
- for (i = 0; i < sk_ASN1_UTF8STRING_num(text); ++i) {
+ for (i = 0; i < sk_ASN1_UTF8STRING_num(text); i++) {
current = sk_ASN1_UTF8STRING_value(text, i);
if (i > 0)
length += sep_len;
length += ASN1_STRING_length(current);
- if (length > max_len)
+ if (max_len != 0 && length > max_len)
return NULL;
}
if ((result = OPENSSL_malloc(length + 1)) == NULL)
return NULL;
- for (i = 0, p = result; i < sk_ASN1_UTF8STRING_num(text); ++i) {
+ p = result;
+ for (i = 0; i < sk_ASN1_UTF8STRING_num(text); i++) {
current = sk_ASN1_UTF8STRING_value(text, i);
length = ASN1_STRING_length(current);
if (i > 0 && sep_len > 0) {
- strncpy(p, sep, sep_len + 1);
+ strncpy(p, sep, sep_len + 1); /* using + 1 to silence gcc warning */
p += sep_len;
}
strncpy(p, (const char *)ASN1_STRING_get0_data(current), length);