static int nc_ip(ASN1_OCTET_STRING *ip, ASN1_OCTET_STRING *base)
{
    int hostlen, baselen, i;
    unsigned char *hostptr, *baseptr, *maskptr;
    hostptr = ip->data;
    hostlen = ip->length;
    baseptr = base->data;
    baselen = base->length;
    if (!((hostlen == 4) || (hostlen == 16)))
        return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
    if (!((baselen == 8) || (baselen == 32)))
        return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
    if (hostlen * 2 != baselen)
        return X509_V_ERR_PERMITTED_VIOLATION;
    maskptr = base->data + hostlen;
    for (i = 0; i < hostlen; i++)
        if ((hostptr[i] & maskptr[i]) != (baseptr[i] & maskptr[i]))
            return X509_V_ERR_PERMITTED_VIOLATION;
    return X509_V_OK;
}
['int NAME_CONSTRAINTS_check_CN(X509 *x, NAME_CONSTRAINTS *nc)\n{\n    int r, i;\n    GENERAL_NAMES *gens = NULL;\n    X509_NAME *nm;\n    ASN1_STRING stmp;\n    GENERAL_NAME gntmp;\n    stmp.flags = 0;\n    stmp.type = V_ASN1_IA5STRING;\n    gntmp.type = GEN_DNS;\n    gntmp.d.dNSName = &stmp;\n    gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);\n    if (gens != NULL) {\n        for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {\n            GENERAL_NAME *gen = sk_GENERAL_NAME_value(gens, i);\n            if (gen->type == GEN_DNS) {\n                GENERAL_NAMES_free(gens);\n                return X509_V_OK;\n            }\n        }\n        GENERAL_NAMES_free(gens);\n    }\n    nm = X509_get_subject_name(x);\n    for (i = -1;;) {\n        X509_NAME_ENTRY *ne;\n        ASN1_STRING *cn;\n        unsigned char *idval;\n        size_t idlen;\n        i = X509_NAME_get_index_by_NID(nm, NID_commonName, i);\n        if (i == -1)\n            break;\n        ne = X509_NAME_get_entry(nm, i);\n        cn = X509_NAME_ENTRY_get_data(ne);\n        if ((r = cn2dnsid(cn, &idval, &idlen)) != X509_V_OK)\n            return r;\n        if (idlen == 0)\n            continue;\n        stmp.length = idlen;\n        stmp.data = idval;\n        r = nc_match(&gntmp, nc);\n        OPENSSL_free(idval);\n        if (r != X509_V_OK)\n            return r;\n    }\n    return X509_V_OK;\n}', "static int cn2dnsid(ASN1_STRING *cn, unsigned char **dnsid, size_t *idlen)\n{\n    int utf8_length;\n    int i;\n    unsigned char *utf8_value;\n    int isdnsname = 0;\n    *dnsid = NULL;\n    *idlen = 0;\n    if ((utf8_length = ASN1_STRING_to_UTF8(&utf8_value, cn)) < 0)\n        return X509_V_ERR_OUT_OF_MEM;\n    while (utf8_length > 0 && utf8_value[utf8_length - 1] == '\\0')\n        --utf8_length;\n    if ((size_t)utf8_length != strlen((char *)utf8_value))\n        return X509_V_ERR_UNSPECIFIED;\n    for (i = 0; i < utf8_length; ++i) {\n        unsigned char c = utf8_value[i];\n        if ((c >= 'a' && c <= 'z')\n            || (c >= 'A' && c <= 'Z')\n            || (c >= '0' && c <= '9')\n            || c == '_')\n            continue;\n        if (i > 0 && i < utf8_length - 1) {\n            if (c == '-')\n                continue;\n            if (c == '.'\n                && utf8_value[i + 1] != '.'\n                && utf8_value[i - 1] != '-'\n                && utf8_value[i + 1] != '-') {\n                isdnsname = 1;\n                continue;\n            }\n        }\n        isdnsname = 0;\n        break;\n    }\n    if (isdnsname) {\n        *dnsid = utf8_value;\n        *idlen = (size_t)utf8_length;\n        return X509_V_OK;\n    }\n    OPENSSL_free(utf8_value);\n    return X509_V_OK;\n}", 'int ASN1_STRING_to_UTF8(unsigned char **out, const ASN1_STRING *in)\n{\n    ASN1_STRING stmp, *str = &stmp;\n    int mbflag, type, ret;\n    if (!in)\n        return -1;\n    type = in->type;\n    if ((type < 0) || (type > 30))\n        return -1;\n    mbflag = tag2nbyte[type];\n    if (mbflag == -1)\n        return -1;\n    mbflag |= MBSTRING_FLAG;\n    stmp.data = NULL;\n    stmp.length = 0;\n    stmp.flags = 0;\n    ret =\n        ASN1_mbstring_copy(&str, in->data, in->length, mbflag,\n                           B_ASN1_UTF8STRING);\n    if (ret < 0)\n        return ret;\n    *out = stmp.data;\n    return stmp.length;\n}', 'int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len,\n                       int inform, unsigned long mask)\n{\n    return ASN1_mbstring_ncopy(out, in, len, inform, mask, 0, 0);\n}', 'int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,\n                        int inform, unsigned long mask,\n                        long minsize, long maxsize)\n{\n    int str_type;\n    int ret;\n    char free_out;\n    int outform, outlen = 0;\n    ASN1_STRING *dest;\n    unsigned char *p;\n    int nchar;\n    char strbuf[32];\n    int (*cpyfunc) (unsigned long, void *) = NULL;\n    if (len == -1)\n        len = strlen((const char *)in);\n    if (!mask)\n        mask = DIRSTRING_TYPE;\n    switch (inform) {\n    case MBSTRING_BMP:\n        if (len & 1) {\n            ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,\n                    ASN1_R_INVALID_BMPSTRING_LENGTH);\n            return -1;\n        }\n        nchar = len >> 1;\n        break;\n    case MBSTRING_UNIV:\n        if (len & 3) {\n            ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,\n                    ASN1_R_INVALID_UNIVERSALSTRING_LENGTH);\n            return -1;\n        }\n        nchar = len >> 2;\n        break;\n    case MBSTRING_UTF8:\n        nchar = 0;\n        ret = traverse_string(in, len, MBSTRING_UTF8, in_utf8, &nchar);\n        if (ret < 0) {\n            ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_INVALID_UTF8STRING);\n            return -1;\n        }\n        break;\n    case MBSTRING_ASC:\n        nchar = len;\n        break;\n    default:\n        ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_UNKNOWN_FORMAT);\n        return -1;\n    }\n    if ((minsize > 0) && (nchar < minsize)) {\n        ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_STRING_TOO_SHORT);\n        BIO_snprintf(strbuf, sizeof(strbuf), "%ld", minsize);\n        ERR_add_error_data(2, "minsize=", strbuf);\n        return -1;\n    }\n    if ((maxsize > 0) && (nchar > maxsize)) {\n        ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_STRING_TOO_LONG);\n        BIO_snprintf(strbuf, sizeof(strbuf), "%ld", maxsize);\n        ERR_add_error_data(2, "maxsize=", strbuf);\n        return -1;\n    }\n    if (traverse_string(in, len, inform, type_str, &mask) < 0) {\n        ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_ILLEGAL_CHARACTERS);\n        return -1;\n    }\n    outform = MBSTRING_ASC;\n    if (mask & B_ASN1_NUMERICSTRING)\n        str_type = V_ASN1_NUMERICSTRING;\n    else if (mask & B_ASN1_PRINTABLESTRING)\n        str_type = V_ASN1_PRINTABLESTRING;\n    else if (mask & B_ASN1_IA5STRING)\n        str_type = V_ASN1_IA5STRING;\n    else if (mask & B_ASN1_T61STRING)\n        str_type = V_ASN1_T61STRING;\n    else if (mask & B_ASN1_BMPSTRING) {\n        str_type = V_ASN1_BMPSTRING;\n        outform = MBSTRING_BMP;\n    } else if (mask & B_ASN1_UNIVERSALSTRING) {\n        str_type = V_ASN1_UNIVERSALSTRING;\n        outform = MBSTRING_UNIV;\n    } else {\n        str_type = V_ASN1_UTF8STRING;\n        outform = MBSTRING_UTF8;\n    }\n    if (!out)\n        return str_type;\n    if (*out) {\n        free_out = 0;\n        dest = *out;\n        OPENSSL_free(dest->data);\n        dest->data = NULL;\n        dest->length = 0;\n        dest->type = str_type;\n    } else {\n        free_out = 1;\n        dest = ASN1_STRING_type_new(str_type);\n        if (dest == NULL) {\n            ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ERR_R_MALLOC_FAILURE);\n            return -1;\n        }\n        *out = dest;\n    }\n    if (inform == outform) {\n        if (!ASN1_STRING_set(dest, in, len)) {\n            ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ERR_R_MALLOC_FAILURE);\n            return -1;\n        }\n        return str_type;\n    }\n    switch (outform) {\n    case MBSTRING_ASC:\n        outlen = nchar;\n        cpyfunc = cpy_asc;\n        break;\n    case MBSTRING_BMP:\n        outlen = nchar << 1;\n        cpyfunc = cpy_bmp;\n        break;\n    case MBSTRING_UNIV:\n        outlen = nchar << 2;\n        cpyfunc = cpy_univ;\n        break;\n    case MBSTRING_UTF8:\n        outlen = 0;\n        traverse_string(in, len, inform, out_utf8, &outlen);\n        cpyfunc = cpy_utf8;\n        break;\n    }\n    if ((p = OPENSSL_malloc(outlen + 1)) == NULL) {\n        if (free_out)\n            ASN1_STRING_free(dest);\n        ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ERR_R_MALLOC_FAILURE);\n        return -1;\n    }\n    dest->length = outlen;\n    dest->data = p;\n    p[outlen] = 0;\n    traverse_string(in, len, inform, cpyfunc, &p);\n    return str_type;\n}', 'static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc)\n{\n    GENERAL_SUBTREE *sub;\n    int i, r, match = 0;\n    for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->permittedSubtrees); i++) {\n        sub = sk_GENERAL_SUBTREE_value(nc->permittedSubtrees, i);\n        if (gen->type != sub->base->type)\n            continue;\n        if (sub->minimum || sub->maximum)\n            return X509_V_ERR_SUBTREE_MINMAX;\n        if (match == 2)\n            continue;\n        if (match == 0)\n            match = 1;\n        r = nc_match_single(gen, sub->base);\n        if (r == X509_V_OK)\n            match = 2;\n        else if (r != X509_V_ERR_PERMITTED_VIOLATION)\n            return r;\n    }\n    if (match == 1)\n        return X509_V_ERR_PERMITTED_VIOLATION;\n    for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->excludedSubtrees); i++) {\n        sub = sk_GENERAL_SUBTREE_value(nc->excludedSubtrees, i);\n        if (gen->type != sub->base->type)\n            continue;\n        if (sub->minimum || sub->maximum)\n            return X509_V_ERR_SUBTREE_MINMAX;\n        r = nc_match_single(gen, sub->base);\n        if (r == X509_V_OK)\n            return X509_V_ERR_EXCLUDED_VIOLATION;\n        else if (r != X509_V_ERR_PERMITTED_VIOLATION)\n            return r;\n    }\n    return X509_V_OK;\n}', 'static int nc_match_single(GENERAL_NAME *gen, GENERAL_NAME *base)\n{\n    switch (base->type) {\n    case GEN_DIRNAME:\n        return nc_dn(gen->d.directoryName, base->d.directoryName);\n    case GEN_DNS:\n        return nc_dns(gen->d.dNSName, base->d.dNSName);\n    case GEN_EMAIL:\n        return nc_email(gen->d.rfc822Name, base->d.rfc822Name);\n    case GEN_URI:\n        return nc_uri(gen->d.uniformResourceIdentifier,\n                      base->d.uniformResourceIdentifier);\n    case GEN_IPADD:\n        return nc_ip(gen->d.iPAddress, base->d.iPAddress);\n    default:\n        return X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE;\n    }\n}', 'static int nc_ip(ASN1_OCTET_STRING *ip, ASN1_OCTET_STRING *base)\n{\n    int hostlen, baselen, i;\n    unsigned char *hostptr, *baseptr, *maskptr;\n    hostptr = ip->data;\n    hostlen = ip->length;\n    baseptr = base->data;\n    baselen = base->length;\n    if (!((hostlen == 4) || (hostlen == 16)))\n        return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;\n    if (!((baselen == 8) || (baselen == 32)))\n        return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;\n    if (hostlen * 2 != baselen)\n        return X509_V_ERR_PERMITTED_VIOLATION;\n    maskptr = base->data + hostlen;\n    for (i = 0; i < hostlen; i++)\n        if ((hostptr[i] & maskptr[i]) != (baseptr[i] & maskptr[i]))\n            return X509_V_ERR_PERMITTED_VIOLATION;\n    return X509_V_OK;\n}']