661
662
return proxy->cert_received && proxy->cert_broken;
665
static const char *asn1_string_to_c(ASN1_STRING *asn_str)
670
len = ASN1_STRING_length(asn_str);
671
cstr = t_strndup(ASN1_STRING_data(asn_str), len);
672
if (strlen(cstr) != len) {
673
/* NULs in the name - could be some MITM attack.
680
static const char *get_general_dns_name(const GENERAL_NAME *name)
682
if (ASN1_STRING_type(name->d.ia5) != V_ASN1_IA5STRING)
685
return asn1_string_to_c(name->d.ia5);
688
static const char *get_cname(X509 *cert)
691
X509_NAME_ENTRY *entry;
695
name = X509_get_subject_name(cert);
698
cn_idx = X509_NAME_get_index_by_NID(name, NID_commonName, -1);
701
entry = X509_NAME_get_entry(name, cn_idx);
702
i_assert(entry != NULL);
703
str = X509_NAME_ENTRY_get_data(entry);
704
i_assert(str != NULL);
705
return asn1_string_to_c(str);
708
static int openssl_cert_match_name(SSL *ssl, const char *verify_name)
711
STACK_OF(GENERAL_NAME) *gnames;
712
const GENERAL_NAME *gn;
714
bool dns_names = FALSE;
715
unsigned int i, count;
717
cert = SSL_get_peer_certificate(ssl);
718
i_assert(cert != NULL);
720
/* verify against SubjectAltNames */
721
gnames = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
722
count = gnames == NULL ? 0 : sk_GENERAL_NAME_num(gnames);
723
for (i = 0; i < count; i++) {
724
gn = sk_GENERAL_NAME_value(gnames, i);
725
if (gn->type == GEN_DNS) {
727
dnsname = get_general_dns_name(gn);
728
if (strcmp(dnsname, verify_name) == 0)
732
sk_GENERAL_NAME_pop_free(gnames, GENERAL_NAME_free);
733
/* verify against CommonName only when there wasn't any DNS
736
return i < count ? 0 : -1;
738
return strcmp(get_cname(cert), verify_name) == 0 ? 0 : -1;
741
int ssl_proxy_cert_match_name(struct ssl_proxy *proxy, const char *verify_name)
743
return openssl_cert_match_name(proxy->ssl, verify_name);
664
746
const char *ssl_proxy_get_peer_name(struct ssl_proxy *proxy)