static const char * openssl_iostream_get_peer_name(struct ssl_iostream *ssl_io) { X509 *x509; char *name; int len; if (!ssl_iostream_has_valid_client_cert(ssl_io)) return NULL; x509 = SSL_get_peer_certificate(ssl_io->ssl); i_assert(x509 != NULL); len = X509_NAME_get_text_by_NID(X509_get_subject_name(x509), ssl_io->username_nid, NULL, 0); if (len < 0) name = ""; else { name = t_malloc(len + 1); if (X509_NAME_get_text_by_NID(X509_get_subject_name(x509), ssl_io->username_nid, name, len + 1) < 0) name = ""; else if (strlen(name) != (size_t)len) { /* NUL characters in name. Someone's trying to fake being another user? Don't allow it. */ name = ""; } } X509_free(x509); return *name == '\0' ? NULL : name; }
static int openssl_iostream_cert_match_name(struct ssl_iostream *ssl_io, const char *verify_name) { if (!ssl_iostream_has_valid_client_cert(ssl_io)) return -1; return openssl_cert_match_name(ssl_io->ssl, verify_name); }
int ssl_iostream_check_cert_validity(struct ssl_iostream *ssl_io, const char *host, const char **error_r) { if (!ssl_iostream_has_valid_client_cert(ssl_io)) { if (!ssl_iostream_has_broken_client_cert(ssl_io)) *error_r = "SSL certificate not received"; else { *error_r = t_strdup(ssl_iostream_get_last_error(ssl_io)); if (*error_r == NULL) *error_r = "Received invalid SSL certificate"; } return -1; } else if (ssl_iostream_cert_match_name(ssl_io, host) < 0) { *error_r = t_strdup_printf( "SSL certificate doesn't match expected host name %s", host); return -1; } return 0; }