Example #1
0
ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out,
                                    const unsigned char *in, int inlen,
                                    int inform, int nid)
{
    ASN1_STRING_TABLE *tbl;
    ASN1_STRING *str = NULL;
    unsigned long mask;
    int ret;
    if (!out)
        out = &str;
    tbl = ASN1_STRING_TABLE_get(nid);
    if (tbl) {
        mask = tbl->mask;
        if (!(tbl->flags & STABLE_NO_MASK))
            mask &= global_mask;
        ret = ASN1_mbstring_ncopy(out, in, inlen, inform, mask,
                                  tbl->minsize, tbl->maxsize);
    } else
        ret =
            ASN1_mbstring_copy(out, in, inlen, inform,
                               DIRSTRING_TYPE & global_mask);
    if (ret <= 0)
        return NULL;
    return *out;
}
Example #2
0
int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len,
                       int inform, unsigned long mask)
{
    return ASN1_mbstring_ncopy(out, in, len, inform, mask, 0, 0);
}
Example #3
0
static int
tls_parse_asn1string(struct tls *ctx, ASN1_STRING *a1str, const char **dst_p, int minchars, int maxchars, const char *desc)
{
	int format, len, ret = -1;
	unsigned char *data;
	ASN1_STRING *a1utf = NULL;
	int ascii_only = 0;
	char *cstr = NULL;
	int mbres, mbconvert = -1;

	*dst_p = NULL;

	format = ASN1_STRING_type(a1str);
	data = ASN1_STRING_data(a1str);
	len = ASN1_STRING_length(a1str);
	if (len < minchars) {
		tls_set_errorx(ctx, "invalid %s: string too short", desc);
		goto failed;
	}

	switch (format) {
	case V_ASN1_NUMERICSTRING:
	case V_ASN1_VISIBLESTRING:
	case V_ASN1_PRINTABLESTRING:
	case V_ASN1_IA5STRING:
		/* Ascii */
		if (len > maxchars) {
			tls_set_errorx(ctx, "invalid %s: string too long", desc);
			goto failed;
		}
		ascii_only = 1;
		break;
	case V_ASN1_T61STRING:
		/* Latin1 */
		mbconvert = MBSTRING_ASC;
		break;
	case V_ASN1_BMPSTRING:
		/* UCS-2 big-endian */
		mbconvert = MBSTRING_BMP;
		break;
	case V_ASN1_UNIVERSALSTRING:
		/* UCS-4 big-endian */
		mbconvert = MBSTRING_UNIV;
		break;
	case V_ASN1_UTF8STRING:
		/*
		 * UTF-8 - could be used directly if OpenSSL has already
		 * validated the data.  ATM be safe and validate here.
		 */
		mbconvert = MBSTRING_UTF8;
		break;
	default:
		tls_set_errorx(ctx, "invalid %s: unexpected string type", desc);
		goto failed;
	}

	/* Convert to UTF-8 */
	if (mbconvert != -1) {
		mbres = ASN1_mbstring_ncopy(&a1utf, data, len, mbconvert, B_ASN1_UTF8STRING, minchars, maxchars);
		if (mbres < 0) {
			tls_set_error_libssl(ctx, "invalid %s", desc);
			goto failed;
		}
		if (mbres != V_ASN1_UTF8STRING) {
			tls_set_errorx(ctx, "multibyte conversion failed: expected UTF8 result");
			goto failed;
		}
		data = ASN1_STRING_data(a1utf);
		len = ASN1_STRING_length(a1utf);
	}

	/* must not allow \0 */
	if (memchr(data, 0, len) != NULL) {
		tls_set_errorx(ctx, "invalid %s: contains NUL", desc);
		goto failed;
	}

	/* no escape codes please */
	if (check_invalid_bytes(ctx, data, len, ascii_only, desc) < 0)
		goto failed;

	/* copy to new string */
	cstr = malloc(len + 1);
	if (!cstr) {
		tls_set_error(ctx, "malloc");
		goto failed;
	}
	memcpy(cstr, data, len);
	cstr[len] = 0;
	*dst_p = cstr;
	ret = len;
failed:
	ASN1_STRING_free(a1utf);
	return ret;
}