Tag Archives: ssl

SNI in iOS 4.0

iOS 4.0 supports SNI, which makes it the first mobile OS to support the server_name TLS extension. Hopefully Android, WebOS, WM7, et al follow suit!

(Oh, and I’m not dead. WP 3.0 comes out shortly so expect a major CDN Tools update as well as a brand new plugin!)

SNI Support in Chromium OS X

As of r39934 Chromium now supports the server_name TLS extension (server name indication) in OS X (latest build). This support requires OS X 10.5.7 or later. Hopefully it’ll make its way into a dev/beta/stable release of Google Chrome itself soon.

For those who are more curious than they ought to be about how I wrote this patch… Apple added support in their Secure Transport library for the server_name TLS extension, but has not updated their documentation. As of 10.5.7 (or possibly 10.5.6) the SSLSetPeerDomainName function — which is ostensibly used for OS level certificate verification — causes OS X to send the server_name extension in the TLS client hello. However, since Chromium doesn’t use OS X’s built-in verification it wasn’t passing this data through prior to the patch.

To test you can hit up my IDN SNI site https://☣.ws/ or https://alice.sni.velox.ch/. The former will throw a certificate error if you are on a non-SNI enabled browser and the latter will have text stating that the SNI extension is missing.

SSL VHosting On The Same IP (aka SNI)

Server Name Indication (SNI), an extension to TLS, allows browsers that support it to connect to SSL hosts that do not have dedicated IPs (much like standard http virtual hosting has worked for years). This extension, however, must be supported on both the server and client side. Microsoft has not yet chosen to support it (maybe IIS 8?), but the Apache project did with the 2.2.12 release. Recently, Ubuntu 9.10 Server became the first server distribution to ship with Apache and OpenSSL built with the appropriate flags, so if you’d like to follow along you can use a 9.10 VM.

In the ideal case everything is the same as a regular vhost, but you’ll first need to enable SSL. On Ubuntu this requires you to run a2enmod and type “ssl”. After that you’ll need to add

NameVirtualHost *:443

to the root conf, then make your VirtualHost much like a normal one. A very basic pair of vhosts is seen below.

<VirtualHost *:443>
	ServerAdmin webmaster@localhost
 
	DocumentRoot /my/doc/root
	ServerName mydomain.com
	SSLEngine On
	SSLCertificateFile /path/to/domain.crt 
	SSLCertificateKeyFile /path/to/domain.key
</VirtualHost>
<VirtualHost *:443>
	ServerAdmin webmaster@localhost
 
	DocumentRoot /my/doc/root
	ServerName mydomain2.com
	SSLEngine On
	SSLCertificateFile /path/to/domain2.crt 
	SSLCertificateKeyFile /path/to/domain2.key
</VirtualHost>

These vhosts should be placed in different includes ideally, but it isn’t required. If you just want to test with a self-signed certificate you can create one with

openssl req -new -nodes -keyout mykey.key -out mycert.cer -days 3650 -x509

You’ll need to specify the domain name you want in the “Common Name” section.

Once you’ve got all this done you can restart apache and test it out! If you test on a browser that doesn’t support SNI (IE on XP) you’ll get the SSL cert for the first vhost apache parses. To disable accessing it on non-SNI hosts you can add

SSLStrictSNIVHostCheck on

to the root conf. This will cause a 403 error for those browsers.

If you’d like to see an example implementation of SNI you can check out my IDN domains https://☢.ws/ and https://☣.ws/. These sites are hosted on the same IP with different SSL certificates. I have strict host checking turned on so visiting them with a non-SNI capable browser will result in a 403 error.1

  1. See the Wikipedia article about Server Name Indication for more information on supported browsers.

Firefox Autoenrollment With A Microsoft CA

If you’re running a Microsoft CA and you want to be able to accept enrollment requests from clients supporting keygen (Firefox, Safari, Opera, et cetera) you’ve probably found that the /certsrv/ page allows enrollment, but the requests fail when you attempt to issue the certificate.  This is because the server is not parsing the subject attributes from the request.  To fix this, run the following on your server as administrator on the command line.

certutil -setreg ca\CRLFlags +CRLF_ALLOW_REQUEST_ATTRIBUTE_SUBJECT

You can also set your server to auto-issue on request for certain certificate profiles.  To do this add the CA snap-in and get properties of your CA. Under the policy module tab click properties again and click the “Follow the settings..” radio button.
add-snapinmmc

propertiesrequesthandling

Using OpenSSL s_time

Recently I needed to do some performance testing of an SSL instance on a VM. I considered using JMeter, but decided to use OpenSSL to get a rudimentary picture instead.

To obtain a basic result, we connect to the server and pull the /index.php file. You can specify whatever file you’d like to download, or none at all if you simply want to test connections.1

openssl s_time -www /index.php -new -connect www.trustwave.com:443

Your result will look something like this:

No CIPHER specified
Collecting connection statistics for 30 seconds
ttttttttttttttttttttttttttttttttttttttttttttttttttttttttt
159 connections in 5.82s; 27.32 connections/user sec, bytes read 62328
159 connections in 31 real seconds, 392 bytes read per connection

If you’d like to get more specific with performance testing you can even use the -ciphers parameter to explicitly choose the negotiated cipher. You can obtain a list of available ciphers with “openssl ciphers”.

  1. If you would prefer to reuse connections rather than create a new one for each request replace -new with -reuse.

RSA Encryption and Signing

OpenSSL provides several tools that allow you to RSA encrypt/sign arbitrary data files. Of course, directly RSA encrypting large volumes of data is impractical because the encrypted/signed data cannot exceed the size of the key material. This is one of the reasons why SSL connections typically handshake and then pass an AES (or RC4, et cetera) key to do symmetric encryption thereafter.1

Generate a private key. You can change the last number to the preferred modulus size. Keys greater than 4096-bit will take a long time to generate.2

openssl genrsa -out private.pem 4096

With the private key we can now encrypt the data.

openssl rsautl -encrypt -inkey private.pem -in publicfile -out privatefile

To decrypt just reverse it.

openssl rsautl -decrypt -inkey private.pem -in privatefile -out publicfile

If you would rather sign the data…

openssl rsautl -sign -inkey private.pem -in filetosign -out signed_data

To verify the signature just use -verify.3

openssl rsautl -verify -inkey private.pem -in signed_data
  1. Another big reason is speed. AES is much, much faster than RSA.
  2. If you attempt to encrypt or sign data larger than your key length allows, you will receive an error similar to this: 23465:error:0406D06E:rsa routines:RSA_padding_add_PKCS1_type_2:data too large for key size:rsa_pk1.c:151:
  3. You can also use -hexdump or -raw to view the data in those forms.