示例#1
0
/* based on verify_extract_name from tls_client.c in postfix */
static gboolean irssi_ssl_verify_hostname(X509 *cert, const char *hostname)
{
	int gen_index, gen_count;
	gboolean matched = FALSE, has_dns_name = FALSE;
	const char *cert_dns_name;
	char *cert_subject_cn;
	const GENERAL_NAME *gn;
	STACK_OF(GENERAL_NAME) * gens;
	GString *alt_names;

	alt_names = g_string_new("");

	/* Verify the dNSName(s) in the peer certificate against the hostname. */
	gens = X509_get_ext_d2i(cert, NID_subject_alt_name, 0, 0);
	if (gens) {
		gen_count = sk_GENERAL_NAME_num(gens);
		for (gen_index = 0; gen_index < gen_count && !matched; ++gen_index) {
			gn = sk_GENERAL_NAME_value(gens, gen_index);
			if (gn->type != GEN_DNS)
				continue;

			/* Even if we have an invalid DNS name, we still ultimately
			   ignore the CommonName, because subjectAltName:DNS is
			   present (though malformed). */
			has_dns_name = TRUE;
			cert_dns_name = tls_dns_name(gn);
			if (cert_dns_name && *cert_dns_name) {
				g_string_append_printf(alt_names, " '%s'", cert_dns_name);
				matched = match_hostname(cert_dns_name, hostname);
			}
    	}

	    /* Free stack *and* member GENERAL_NAME objects */
	    sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
	}

	if (has_dns_name) {
		if (! matched) {
			/* The CommonName in the issuer DN is obsolete when SubjectAltName is available. */
			g_warning("None of the Subject Alt Names%s in the certificate match hostname '%s'", alt_names->str, hostname);
		}
		g_string_free(alt_names, TRUE);
		return matched;
	} else { /* No subjectAltNames, look at CommonName */
		g_string_free(alt_names, TRUE);
		cert_subject_cn = tls_text_name(X509_get_subject_name(cert), NID_commonName);
	    if (cert_subject_cn && *cert_subject_cn) {
	    	matched = match_hostname(cert_subject_cn, hostname);
	    	if (! matched) {
				g_warning("SSL certificate common name '%s' doesn't match host name '%s'", cert_subject_cn, hostname);
	    	}
	    } else {
	    	g_warning("No subjectAltNames and no valid common name in certificate");
	    }
	    free(cert_subject_cn);
	}

	return matched;
}
示例#2
0
char   *tls_issuer_CN(X509 *peer, const TLS_SESS_STATE *TLScontext)
{
    X509_NAME *name;
    char   *cn;

    name = X509_get_issuer_name(peer);

    /*
     * If no issuer CN field, use Organization instead. CA certs without a CN
     * are common, so we only complain if the organization is also missing.
     */
    if ((cn = tls_text_name(name, NID_commonName,
			    "issuer CN", TLScontext, DONT_GRIPE)) == 0)
	cn = tls_text_name(name, NID_organizationName,
			   "issuer Organization", TLScontext, DONT_GRIPE);
    return (cn ? cn : mystrdup(""));
}
示例#3
0
char   *tls_peer_CN(X509 *peercert, const TLS_SESS_STATE *TLScontext)
{
    char   *cn;

    cn = tls_text_name(X509_get_subject_name(peercert), NID_commonName,
		       "subject CN", TLScontext, DONT_GRIPE);
    return (cn ? cn : mystrdup(""));
}