+ecore_con_ssl_server_verify_name_set/get

SVN revision: 66002
This commit is contained in:
Mike Blumenkrantz 2011-12-08 01:14:55 +00:00
parent f0e4cb8e79
commit b40fa86b4a
6 changed files with 87 additions and 9 deletions

View File

@ -388,3 +388,4 @@
2011-12-07 Mike Blumenkrantz
* Allow SSL certificates to be loaded for STARTTLS
* Added functions to set/get the hostname used for SSL certificate verification

View File

@ -8,6 +8,7 @@ Additions:
- ecore_timer_reset()
* ecore_con
- ecore_con_socks api
- ecore_con_ssl_server_verify_name_set/get
* ecore_x:
- ecore_x_randr_output_backlight_available()

View File

@ -707,6 +707,8 @@ EAPI Eina_Bool ecore_con_ssl_server_crl_add(Ecore_Con_Server *svr, const
EAPI Eina_Bool ecore_con_ssl_server_cafile_add(Ecore_Con_Server *svr, const char *ca_file);
EAPI void ecore_con_ssl_server_verify(Ecore_Con_Server *svr);
EAPI void ecore_con_ssl_server_verify_basic(Ecore_Con_Server *svr);
EAPI void ecore_con_ssl_server_verify_name_set(Ecore_Con_Server *svr, const char *name);
EAPI const char *ecore_con_ssl_server_verify_name_get(Ecore_Con_Server *svr);
EAPI Eina_Bool ecore_con_ssl_server_upgrade(Ecore_Con_Server *svr, Ecore_Con_Type compl_type);
EAPI Eina_Bool ecore_con_ssl_client_upgrade(Ecore_Con_Client *cl, Ecore_Con_Type compl_type);

View File

@ -1264,6 +1264,7 @@ _ecore_con_server_free(Ecore_Con_Server *svr)
free(svr->path);
eina_stringshare_del(svr->ip);
eina_stringshare_del(svr->verify_name);
if (svr->ecs_buf) eina_binbuf_free(svr->ecs_buf);
if (svr->ecs_recvbuf) eina_binbuf_free(svr->ecs_recvbuf);

View File

@ -150,6 +150,7 @@ struct _Ecore_Con_Server
const char *proxyip;
int proxyport;
/* endsocks */
const char *verify_name;
#if USE_GNUTLS
gnutls_session_t session;
gnutls_anon_client_credentials_t anoncred_c;

View File

@ -355,6 +355,51 @@ ecore_con_ssl_server_verify_basic(Ecore_Con_Server *svr)
svr->verify_basic = EINA_TRUE;
}
/**
* @brief Set the hostname to verify against in certificate verification
*
* Sometimes the certificate hostname will not match the hostname that you are
* connecting to, and will instead match a different name. An example of this is
* that if you connect to talk.google.com to use Google Talk, you receive Google's
* certificate for gmail.com. This certificate should be trusted, and so you must call
* this function with "gmail.com" as @p name.
* See RFC2818 for more details.
* @param svr The server object
* @param name The hostname to verify against
* @since 1.2
*/
EAPI void
ecore_con_ssl_server_verify_name_set(Ecore_Con_Server *svr, const char *name)
{
if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
{
ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, __func__);
return;
}
eina_stringshare_replace(&svr->verify_name, name);
}
/**
* @brief Get the hostname to verify against in certificate verification
*
* This function returns the name which will be used to validate the SSL certificate
* common name (CN) or alt name (subjectAltName). It will default to the @p name
* param in ecore_con_server_connect(), but can be changed with ecore_con_ssl_server_verify_name_set().
* @param svr The server object
* @return The hostname which will be used
* @since 1.2
*/
EAPI const char *
ecore_con_ssl_server_verify_name_get(Ecore_Con_Server *svr)
{
if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
{
ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, __func__);
return NULL;
}
return svr->verify_name ?: svr->name;
}
/**
* @brief Add an ssl certificate for use in ecore_con functions.
*
@ -764,8 +809,28 @@ _ecore_con_ssl_server_init_gnutls(Ecore_Con_Server *svr)
SSL_ERROR_CHECK_GOTO_ERROR(gnutls_x509_crt_init(&cert));
SSL_ERROR_CHECK_GOTO_ERROR(gnutls_x509_crt_import(cert, &cert_list[0], GNUTLS_X509_FMT_DER));
#ifdef ISCOMFITOR
{
size_t clen = 0;
char *c;
gnutls_x509_crt_get_subject_alt_name(cert, 0, NULL, &clen, NULL);
if (clen++)
{
c = alloca(clen);
gnutls_x509_crt_get_subject_alt_name(cert, 0, c, &clen, NULL);
}
else
{
gnutls_x509_crt_get_dn_by_oid(cert, GNUTLS_OID_X520_COMMON_NAME, 0, 0, NULL, &clen);
SSL_ERROR_CHECK_GOTO_ERROR(!clen);
c = alloca(++clen);
gnutls_x509_crt_get_dn_by_oid(cert, GNUTLS_OID_X520_COMMON_NAME, 0, 0, c, &clen);
}
INF("CERT NAME: %s\n", c);
}
#endif
SSL_ERROR_CHECK_GOTO_ERROR(!gnutls_x509_crt_check_hostname(cert, svr->name));
SSL_ERROR_CHECK_GOTO_ERROR(!gnutls_x509_crt_check_hostname(cert, svr->verify_name ?: svr->name));
gnutls_x509_crt_deinit(cert);
DBG("SSL certificate verification succeeded!");
return ECORE_CON_SSL_ERROR_NONE;
@ -1344,17 +1409,24 @@ _ecore_con_ssl_server_init_openssl(Ecore_Con_Server *svr)
cert = SSL_get_peer_certificate(svr->ssl);
if (cert)
{
char buf[256] = {0};
char *c;
size_t clen;
ASN1_OBJECT *obj = NULL;
if (svr->verify)
SSL_ERROR_CHECK_GOTO_ERROR(SSL_get_verify_result(svr->ssl));
X509_NAME_get_text_by_NID(X509_get_subject_name(cert), NID_subject_alt_name, buf, sizeof(buf));
if (buf[0])
SSL_ERROR_CHECK_GOTO_ERROR(!_openssl_name_verify(buf, svr->name));
clen = X509_NAME_get_text_by_NID(X509_get_subject_name(cert), NID_subject_alt_name, NULL, 0);
if (clen)
obj = NID_subject_alt_name;
else
{
X509_NAME_get_text_by_NID(X509_get_subject_name(cert), NID_commonName, buf, sizeof(buf));
SSL_ERROR_CHECK_GOTO_ERROR(!_openssl_name_verify(buf, svr->name));
}
clen = X509_NAME_get_text_by_NID(X509_get_subject_name(cert), NID_commonName, NULL, 0);
SSL_ERROR_CHECK_GOTO_ERROR(!clen);
if (!obj) obj = NID_commonName;
c = alloca(++clen);
X509_NAME_get_text_by_NID(X509_get_subject_name(cert), obj, c, clen);
INF("CERT NAME: %s\n", c);
SSL_ERROR_CHECK_GOTO_ERROR(!_openssl_name_verify(buf, svr->verify_name ?: svr->name));
SSL_ERROR_CHECK_GOTO_ERROR(!_openssl_name_verify(buf, svr->verify_name ?: svr->name));
}
}