Redemption Steps

When its reasonable to use SSL or TLS, do so, making sure that the following is true:

  • Youre using the most recent version of the protocol (as of this writing, its TLS 1.1).

  • You use a strong cipher suite (particularly not one with RC4 or DES).

  • You validate that the certificate is within its validity period.

  • You ensure that the certificate is endorsed by a trusted source (root CA), either directly or indirectly.

  • You validate that the hostname in the certificate matches the one you expect to see.

Also, you should try to implement one or more revocation mechanisms, particularly basic CRL checking or OCSP.

Choosing a Protocol Version

In most high-level languages, theres no easy way to choose what protocol youre going to use. You simply ask for an encrypted socket, the underlying library connects and returns a result. For example, in Python, theres an ssl() routine in the socket module that takes a socket object and SSL-enables it, but it provides no way to configure the protocol version or cipher suite. The basic APIs for other scripting languages like Perl and PHP have similar problems. Fixing this issue often requires writing native code, or at least digging out a hidden API that is a direct wrapper of an existing native API (such as OpenSSL).

Lower-level languages are more likely to give you the capability to set the protocol version. For example, in Java, while it doesnt support TLS v1.1 (as of version 1.4.2), you can allow only TLS v1.0 with the following code:

 from javax.net.ssl import SSLSocket; SSLSocket s = new SSLSocket("www.example.com", 25); s.setEnabledProtocols({"TLSv1"}); 

The .NET Framework 2.0 also supports TLS v1.0, and the code that follows shows how to enforce using TLS. It also performs date checks, and the last argument to AuthenticateAsClient is true, which performs a CRL check as well.

 RemoteCertificateValidationCallback rcvc = new      RemoteCertificateValidationCallback(OnCertificateValidation); sslStream = new SslStream(client.GetStream(), false, rcvc); sslStream.AuthenticateAsClient("www.example.com", // Server name to check      null, // Cert chain      SslProtocols.Tls, // Use TLS      true); // Perform CRL check  ... // Callback to perform extra checks on server cert (if needed  private static bool OnCertificateValidation(object sender,  X509Certificate certificate,  X509Chain chain,  SslPolicyErrors sslPolicyErrors) {  if (sslPolicyErrors != SslPolicyErrors.None) {  return false;  } else {  return true;  } } 

Of course, both these examples will not let the client code converse with servers speaking only older versions of the protocol.

C libraries such as OpenSSL and the Microsoft Security Support Provider Interface (SSPI) have comparable interfaces, but because they are lower level, more code is needed.

Choosing a Cipher Suite

As with choosing the protocol version, many times when you choose a cipher suite, high- level languages make it difficult. It is possible to do in low-level languages, but the defaults arent what wed necessarily like them to be. For example, the Sun version of the Java Secure Sockets Extension (JSSE) API has, insofar as symmetric encryption algorithms go, RC4, Data Encryption Standard (DES), triple DES (3DES), and the Advanced Encryption Standard (AES) as encryption options. The first two of those you should avoid.

Heres the complete list of the Sun ciphers that can be negotiated by default, in their priority order (the order Java will choose if you dont do anything else):

  • SSL_RSA_WITH_RC4_128_MD5

  • SSL_RSA_WITH_RC4_128_SHA

  • TLS_RSA_WITH_AES_128_CBC_SHA

  • TLS_DHE_RSA_WITH_AES_128_CBC_SHA

  • TLS_DHE_DSS_WITH_AES_128_CBC_SHA

  • SSL_RSA_WITH_3DES_EDE_CBC_SHA

  • SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA

  • SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA

  • SSL_RSA_WITH_DES_CBC_SHA

  • SSL_DHE_RSA_WITH_DES_CBC_SHA

  • SSL_DHE_DSS_WITH_DES_CBC_SHA

  • SSL_RSA_EXPORT_WITH_RC4_40_MD5

  • SSL_RSA_EXPORT_WITH_DES40_CBC_SHA

  • SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA

  • SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA

The first two cipher suites are undesirable for long- term security, but theyre the most likely to be used! Youd much rather use any of the next three cipher suites, as AES is the best of the available cryptographic algorithms. (Public key algorithm selection and message authentication code (MAC) selection do not matter here.) To only accept those three algorithms, you could use the following code:

 private void useSaneCipherSuites(SSLSocket s) {  s.setEnabledCipherSuites({"TLS_RSA_WITH_AES_128_CBC_SHA", "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", "TLS_DHE_DSS_WITH_AES_128_CBC_SHA"}); } 

Ensuring Certificate Validity

APIs have varying support for basic certificate validity. Some perform date checking and trust checking by default, while others have no facilities for supporting either. Most are somewhere in the middle; for example, providing facilities for both, but not doing either by default.

Generally (but not always), to perform validation on an SSL connection, one needs to get a reference to the actual server certificate (often called the clients peer certificate). For example, in Java, one can register a HandShakeCompletedListener with an SSLSocket object before initializing the SSL connection. Your listener must define the following method:

 public void handshakeCompleted(HandShakeCompletedEvent event); 

When you get the event object, you can then call:

 event.getPeerCertificates(); 

This returns an array of java.security.cert.Certificate objects. Certificate is the base typethe actual derived type will generally be java.security.cert.X509Extension, though it may occasionally be an older certificate (java.security.cert.X509Certificate, from which X509Extension inherits).

The first certificate is the peers certificate, and the rest of the certs form a chain back to a root certification authority. When you call this routine, the Java API will perform some basic checking on the certificates to make sure they support the proper cipher suite, but it does not actually validate the chain of trust. When taking this approach, you need to do the validation manually by using the public key of the n+1th certificate to validate the nth certificate, and then, for the root certificate, compare it against a list of known roots. (Java provides other ways to perform certificate validation that are about as complicated.) For example, to check the peer certificate when you already know you have a trusted root certificate second in the array, you can do the following:

 try {  ((X509Extension)(certificate[0])).verify(certificate[1].getPublicKey()); } catch (Exception e) {  /* Certificate validation failed. */ } 

Note that this code doesnt check to make sure the date on each of the certificates is valid. In this instance, you could check the peer certificate with the following:

 try {  ((X509Extension)(certificates[0])).checkValidity(); } catch (Exception e) {  /* Certificate validation failed. */ } .NET offers similar validity techniques: X509Certificate2 cert = new X509Certificate2(@"c:\certs\server.cer"); X509Chain chain = new X509Chain(); chain.Build(cert); if (chain.ChainStatus.Length > 0) {  // Errors occurred } 

Validating the Hostname

The preferred way to check the hostname is to use the subjectAltName extensions dnsName field, when available. Often, though, certificates will actually store the host in the DN field. APIs for checking these fields can vary widely.

To continue our Java JSSE example, here is how to check the subjectAltName extension, assuming we have an X509Extention, while falling back to the DN field, if not:

 private Boolean validateHost(X509Extension cert) {  String s = "";  String EXPECTED_HOST = "www.example.com";  try {  /* 2.5.29.17 is the "OID", a standard numerical representation of the  * extension name. */  s = new String(cert.getExtensionValue("2.5.29.17"));  if (s.equals(EXPECTED_HOST)) {  return true;  }  else { /* If the extension is there, but doesn't match the expected  * value, play it safe by not checking the DN field, which  * SHOULD NOT have a different value. */  return false;  }  } catch(Exception e) {} /* No such extension present, so check the DN. */  if (cert.getSubjectDN().getName().equals(EXPECTED_HOST)) {  return true;  } else {  return false;  } } 

.NET Managed code performs the hostname check automatically when calling SslStream.AuthenticateAsClient.

Checking Certificate Revocation

The most popular way for checking revocation (if any way can be considered popular, considering how infrequently it is done) is still CRL checking. OCSP has a lot to recommend, but CA support has been slow to come. VeriSign is one of the biggest supporters, implementing the protocol to answer for every certificate it has ever issued (including RSA-issued and Thawte-issued certs). Their server is available at http:// ocsp.verisign.com (if your language of choice has a library for talking OCSP).

Lets focus on CRLs. First, when you check CRLs, youll need to get a hold of them. You need to find the CRL distribution point, which, if it exists, may either be via HTTP or LDAP. Sometimes the CRL distribution point is specified in the certificate, and sometimes it isnt. In Table 10-1, we provide a list of common CRL distribution points that have CRLs published by HTTP. You can check this table as a fallback when the certificate does not specify a distribution point.

Table 10-1: CRL Distribution Points for Popular CA Roots

Certification Authority

Certificate Name

Expiration Date (GMT)

CRL Distribution Point

Equifax

Secure Certificate Authority

2018-08-22 16:41:51

http://crl.geotrust.com/crls/secureca.crl

Equifax

Secure eBusiness CA-1

2020-06-21 04:00:00

http://crl.geotrust.com/crls/ebizca1.crl

Equifax

Secure eBusiness CA-2

2019-06-23 12:14:45

http://crl.geotrust.com/crls/ebiz.crl

Equifax

Secure Global eBusiness CA-1

2020-06-21 04:00:00

http://crl.geotrust.com/crls/globalca1.crl

RSA Data Security

Secure Server

2010-01-07 23:59:59

http://crl.verisign.com/RSASecureServer.crl

Thawte

Server

2020-12-31 23:59:59

https ://www.thawte.com/cgi/lifecycle/getcrl.crl?skeyid=%07%15%28mps%AA %B2%8A%7C%0F%86%CE8%93%008%05% 8A%B1

TrustCenter

Class 1

2011-01-01 11:59:59

https:/www.trustcenter.de/cgi-bin/CRL.cgi/TC_Class1.crl?Page=GetCrl&crl=2

TrustCenter

Class 2

2011-01-01 11:59:59

https://www.trustcenter.de/cgi-bin/CRL.cgi/TC_Class1.crl?Page=GetCrl&crl=3

TrustCenter

Class 3

2011-01-01 11:59:59

https://www.trustcenter.de/cgi-bin/CRL.cgi/TC_Class1.crl?Page=GetCrl&crl=4

TrustCenter

Class 4

2011-01-01 11:59:59

https://www.trustcenter.de/cgi-bin/CRL.cgi/TC_Class1.crl?Page=GetCrl&crl=5

USERTrust Network

UTN-USERFirst-Network Applications

2019-07-09 18:57:49

http://crl.usertrust.com/UTN-UserFirst-NetworkApplications.crl

USERTrust Network

UTN-USERFirst-Hardware

2019-07-09 18:19:22

http://crl.usertrust.com/UTN-UserFirst-Hardware.crl

USERTrust Network

UTN-DATACorp SGC

2019-06-24 19:06:30

http://crl.usertrust.com/UTN-DataCorpSGC.crl

ValiCert

Class 1 Policy Validation Authority

2019-06-25 22:23:48

http://www.valicert.com/repository/ValiCert%20Class%201%20Policy%20Validation %20Authority.crl

VeriSign

Class 3 Public Primary CA (PCA)

2028-08-01 23:59:59

http://crl.verisign.com/pca3.1.1.crl

VeriSign

Class 3 Public PCA (2nd Generation)

2018-05-18 23:59:59

http://crl.verisign.com/ pca3-g2.crl

Second, you must decide on the frequency for downloading CRLs. Generally, CAs update their revocation lists on a regular basis, whether or not there are any new revoked certificates. The best practice here is to check exactly once per update period, generally within 24 hours of the update.

Third, you must validate the downloaded CRLs to make sure they are properly endorsed (digitally signed) by the CA.

And last, you must validate all certificates in a trust chain against available CRLs, and you must refuse to connect if the certificate is found in the revocation list.

In actuality, a CRL consists simply of a list of certificate IDs. To check a certificate against the CRL, extract the certificate ID from the certificate and check it against the list.



19 Deadly Sins of Software Security. Programming Flaws and How to Fix Them
Writing Secure Code
ISBN: 71626751
EAN: 2147483647
Year: 2003
Pages: 239

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net