int NAME_CONSTRAINTS_check_CN(X509 *x, NAME_CONSTRAINTS *nc)
{
    int r, i;
    GENERAL_NAMES *gens = NULL;
    X509_NAME *nm;
    ASN1_STRING stmp;
    GENERAL_NAME gntmp;

    stmp.flags = 0;
    stmp.type = V_ASN1_IA5STRING;
    gntmp.type = GEN_DNS;
    gntmp.d.dNSName = &stmp;

    gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
    if (gens != NULL) {
        for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
            GENERAL_NAME *gen = sk_GENERAL_NAME_value(gens, i);

            if (gen->type == GEN_DNS) {
                GENERAL_NAMES_free(gens);
                return X509_V_OK;
            }
        }
        GENERAL_NAMES_free(gens);
    }

    nm = X509_get_subject_name(x);

    /* Process any commonName attributes in subject name */

    for (i = -1;;) {
        X509_NAME_ENTRY *ne;
        ASN1_STRING *cn;
        unsigned char *idval;
        size_t idlen;

        i = X509_NAME_get_index_by_NID(nm, NID_commonName, i);
        if (i == -1)
            break;
        ne = X509_NAME_get_entry(nm, i);
        cn = X509_NAME_ENTRY_get_data(ne);

        /* Only process attributes that look like host names */
        if ((r = cn2dnsid(cn, &idval, &idlen)) != X509_V_OK)
            return r;
        if (idlen == 0)
            continue;

        stmp.length = idlen;
        stmp.data = idval;
        r = nc_match(&gntmp, nc);
        OPENSSL_free(idval);
        if (r != X509_V_OK)
            return r;
    }
    return X509_V_OK;
}