From Fedora Project Wiki

< User:Hkario

Revision as of 14:08, 31 July 2015 by Hkario (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Enforce certificate hostname checks

Since Fedora 21 (http://fedoraproject.org/wiki/Changes/CryptoPolicy) there are policies for the usage of SSL and TLS cryptographic protocols that are enforced system-wide. To make those changes more effective, the applications need to actually check if the certificates presented by servers match the expected hostname. rpmlint will warn if it detects that some application seems to be using SSL/TLS certificate checks without performing necessary calls to check if the hostanme in certificate matches the expected one. That detection is based on heuristics and limited to C programs, so manual inspection is recommended. Note however, that there are applications which intentionally don't perform such checks or perform custom checks on purpose (e.g., postfix); those need not adhere to the policy. When in doubt, discuss with the Fedora security team.

C/C++ applications

  • OpenSSL applications:
    • The application should either be calling X509_check_host() (for now OpenSSL 1.0.2 specific) or performing the verification according to information on OpenSSL wiki.
Idea.png
Note
The check needs to include both Subject Alternative Names, extracted with
X509_get_ext_d2i((X509 *) server_cert, NID_subject_alt_name, NULL, NULL);

and a fallback to a check for Common Name (CN)

X509_NAME_get_index_by_NID(X509_get_subject_name((X509 *) server_cert), NID_commonName, -1);
as checks for Common Name alone are deprecated
  • GnuTLS applications:
    • The application should either be calling gnutls_certificate_verify_peers() with one of the data fields set to GNUTLS_DT_DNS_HOSTNAME or gnutls_certificate_verify_peers3(), as described in GnuTLS documentation
Idea.png
Example
A certificate verification callback should use the following example code to set the hostname to check
gnutls_typed_vdata_st data[2];

memset(data, 0, sizeof(data));

data[0].type = GNUTLS_DT_DNS_HOSTNAME;
data[0].data = (void*)hostname;

data[1].type = GNUTLS_DT_KEY_PURPOSE_OID;
data[1].data = (void*)GNUTLS_KP_TLS_WWW_SERVER;

ret = gnutls_certificate_verify_peers(session, data, 2,
                 		      &status);
Alternatively, if support or gnutls 2.x is necessary, a valid alternative is to use gnutls_certificate_verify_peers2() with gnutls_x509_crt_check_hostname()
  • NSS applications:
    • The application should either be calling SSL_SetURL() or, if it overrides the default certificate verification handler by calling SSL_AuthCertificateHook() and not calling SSL_AuthCertificate() inside the hook, then it should be using CERT_VerifyCertName() as described in NSS documentation.