Certificates and iOS

The Most Dangerous Code in the World: Validating SSL Certiļ¬cates in Non-Browser Software

http://www.slideshare.net/iphonepentest/ios-application-insecurity

http://labs.mwrinfosecurity.com/blog/2012/04/16/adventures-with-ios-uiwebviews/

http://developer.apple.com/library/ios/#technotes/tn2232/_index.html

http://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/NetworkingTopics/Articles/OverridingSSLChainValidationCorrectly.html#//apple_ref/doc/uid/TP40012544-SW1

http://www.sslshopper.com/article-most-common-openssl-commands.html

http://help.globalscape.com/help/secureserver3/Generating_a_PKCS_12_private_key_public_certificate.htm

 

Bah humbug – David Cameron cracks down on online pornography

He’s missing or hiding an important piece of information. What’s correlated with the massive increase in access to pornography? A massive decrease in rape and other sexual assaults. We can’t say that pornography prevents rape. But we have a lot of evidence now that an increase in pornography does not lead to an increase in rape – 20 years’ worth of evidence.

However, governments need causes like this to distract attention from actual problems – oh, like the budget (a disaster), and spying on ordinary people (1984 springs to mind).

David Cameron cracks down on online pornography

 

Ciphers (for SSL)

http://www.thesprawl.org/research/tls-and-ssl-cipher-suites/

http://en.wikipedia.org/wiki/Cipher_suite

http://net.educause.edu/ir/library/pdf/PKI0505.pdf

http://www.ecrypt.eu.org/stvl/sasc/slides21.pdf

https://devcentral.f5.com/blogs/us/which-tls-algorithm-should-i-use#.UencH41zKk8

http://en.wikipedia.org/wiki/Transport_Layer_Security

http://en.wikipedia.org/wiki/GnuTLS

http://tools.ietf.org/html/draft-ietf-tls-ctr-00

http://tools.ietf.org/html/draft-ietf-tls-ctr-01

https://www.imperialviolet.org/2012/06/08/tlsversions.html

TLS_RSA_WITH_RC4_128_SHA

TLS_RSA_WITH_AES_256_CBC_SHA

http://stackoverflow.com/questions/1220751/how-to-choose-an-aes-encryption-mode-cbc-ecb-ctr-ocb-cfb

http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation

http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf

http://blog.cryptographyengineering.com/2013/03/attack-of-week-rc4-is-kind-of-broken-in.html

http://crypto.stackexchange.com/questions/853/google-is-using-rc4-but-isnt-rc4-considered-unsafe

http://security.stackexchange.com/questions/27776/block-chaining-modes-to-avoid/27780#27780

http://people.seas.harvard.edu/~salil/cs120/docs/lec13.pdf

 

A full SSL handshake

Details are always good. Here’s what an SSL handshake looks like.

The client was just issued SSL_connect (nonblocking) and the server SSL_accept (nonblocking).

ClientHello

The first thing the client does is to create a ClientHello record and send it.

client->remote_read:
    0000:  16 03 01 00 CD 01 00 00 C9 03 01 51 E7 05 20 57
    0010:  11 02 67 B1 41 20 80 E1 EC F4 74 72 47 FD 06 76
    0020:  71 C9 3E 7A C2 2E 66 AF CA 29 52 00 00 5C C0 14
    0030:  C0 0A 00 39 00 38 00 88 00 87 C0 0F C0 05 00 35
    0040:  00 84 C0 12 C0 08 00 16 00 13 C0 0D C0 03 00 0A
    0050:  C0 13 C0 09 00 33 00 32 00 9A 00 99 00 45 00 44
    0060:  C0 0E C0 04 00 2F 00 96 00 41 00 07 C0 11 C0 07
    0070:  C0 0C C0 02 00 05 00 04 00 15 00 12 00 09 00 14
    0080:  00 11 00 08 00 06 00 03 00 FF 01 00 00 44 00 0B
    0090:  00 04 03 00 01 02 00 0A 00 34 00 32 00 01 00 02
    00A0:  00 03 00 04 00 05 00 06 00 07 00 08 00 09 00 0A
    00B0:  00 0B 00 0C 00 0D 00 0E 00 0F 00 10 00 11 00 12
    00C0:  00 13 00 14 00 15 00 16 00 17 00 18 00 19 00 23
    00D0:  00 00

Completely disassembled, it looks like this.

0000:  16          ; recordType=handshake
0001:  03 01       ; sslVersion=3.1 TLS 1.0
0003:  00 CD       ; recordLength = 205
0005:  01          ; handshake.msg_type = ClientHello
0006:  00 00 C9    ; handshake.length = 201
0009:  03 01       ; handshake.client_version = 3.1 TLS 1.0
000B:  51 E8 35 03 ; handshake.random.gmt_unix_time (2013-07-18 18:33:39)
000F:  C9 6B 5C 9D 8D 92 BA 5D EC 1B 1A C2 B4 7A 6A 2F ; handshake.random.bytes
       20 5C 8D 0E 6E 3E 28 49 9A 89 2F F0 
002B:  00          ; handshake.session_id (0 for no re-used session)
002C:  00 5C       ; cipher_suites (46)
           C0 14   ; TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA
           C0 0A   ; TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
           00 39   ; TLS1_CK_DHE_RSA_WITH_AES_256_SHA
           00 38   ; TLS1_CK_DHE_DSS_WITH_AES_256_SHA
           00 88   ; TLS1_CK_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
           00 87   ; TLS1_CK_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA
           C0 0F   ; TLS1_CK_ECDH_RSA_WITH_AES_256_CBC_SHA
           C0 05   ; TLS1_CK_ECDH_ECDSA_WITH_AES_256_CBC_SHA
           00 35   ; TLS1_CK_RSA_WITH_AES_256_SHA
           00 84   ; TLS1_CK_RSA_WITH_CAMELLIA_256_CBC_SHA
           C0 12   ; TLS1_CK_ECDHE_RSA_WITH_DES_192_CBC3_SHA
           C0 08   ; TLS1_CK_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA
           00 16   ; SSL3_CK_EDH_RSA_DES_192_CBC3_SHA
           00 13   ; SSL3_CK_EDH_DSS_DES_192_CBC3_SHA
           C0 0D   ; TLS1_CK_ECDH_RSA_WITH_DES_192_CBC3_SHA
           C0 03   ; TLS1_CK_ECDH_ECDSA_WITH_DES_192_CBC3_SHA
           00 0A   ; SSL3_CK_RSA_DES_192_CBC3_SHA
           C0 13   ; TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA
           C0 09   ; TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
           00 33   ; TLS1_CK_DHE_RSA_WITH_AES_128_SHA
           00 32   ; TLS1_CK_DHE_DSS_WITH_AES_128_SHA
           00 9A   ; TLS1_CK_DHE_RSA_WITH_SEED_SHA
           00 99   ; TLS1_CK_DHE_DSS_WITH_SEED_SHA
           00 45   ; TLS1_CK_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
           00 44   ; TLS1_CK_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA
           C0 0E   ; TLS1_CK_ECDH_RSA_WITH_AES_128_CBC_SHA
           C0 04   ; TLS1_CK_ECDH_ECDSA_WITH_AES_128_CBC_SHA
           00 2F   ; TLS1_CK_RSA_WITH_AES_128_SHA
           00 96   ; TLS1_CK_RSA_WITH_SEED_SHA
           00 41   ; TLS1_CK_RSA_WITH_CAMELLIA_128_CBC_SHA00 07 C0 11
           C0 07   ; TLS1_CK_ECDHE_ECDSA_WITH_RC4_128_SHA
           C0 0C   ; TLS1_CK_ECDH_RSA_WITH_RC4_128_SHA
           C0 02   ; TLS1_CK_ECDH_ECDSA_WITH_RC4_128_SHA
           00 05   ; SSL3_CK_RSA_RC4_128_SHA
           00 04   ; SSL3_CK_RSA_RC4_128_MD5
           00 15   ; SSL3_CK_EDH_RSA_DES_64_CBC_SHA
           00 12   ; SSL3_CK_EDH_DSS_DES_64_CBC_SHA
           00 09   ; SSL3_CK_RSA_DES_64_CBC_SHA
           00 14   ; SSL3_CK_EDH_RSA_DES_40_CBC_SHA
           00 11   ; SSL3_CK_EDH_DSS_DES_40_CBC_SHA
           00 08   ; SSL3_CK_RSA_DES_40_CBC_SHA
           00 06   ; SSL3_CK_RSA_RC2_40_MD5
           00 03   ; SSL3_CK_RSA_RC4_40_MD5
           00 FF   ; SSL3_CK_SCSV
008A:  01 00 ; compressionMethod 00=NULL
008C:  00 44 ; hello_extension_list
008E:  00 0B ; extension 11 = ec_point_formats rfc4492, rfc5246
       00 04
       03 00 01 02
0096:  00 0A ; extension 10 = elliptic_curves rfc4492, rfc5246
       00 34
       00 32 00 01 00 02
       00 03 00 04 00 05 00 06 00 07 00 08 00 09 00 0A
       00 0B 00 0C 00 0D 00 0E 00 0F 00 10 00 11 00 12
       00 13 00 14 00 15 00 16 00 17 00 18 00 19
00CE:  00 23 ; extension 35 = SessionTicket TLS rfc4507
       00 00

Let’s look at it bit by bit. Here is the record header definition as a C struct

struct SSLRecordHeader
{
  uint8  recordType;
  uint8  majorVersion;
  uint8  minorVersion;
  uint16 length;

The record type enum looks like this

enum SSLRecordType
{
  change_cipher_spec = 20,
  alert = 21,
  handshake = 22,
  application_data = 23
};

Almost ever record we send will be an application_data record, except for the first few which are handshake type.

The record header in this first record is

    0000:  16 03 01 00 CD

We know that this is not SSLv2 because the first byte of the first packet in SSLv2 would have the high bit set, because the first record is ClientHello, and that record has no padding. We also see that the client is sending in version 3.1, which is TLS 1.0 (3.0 would be SSL 3.0), and that the record is 205 bytes long – the 2-byte length field is in network order, which is big-endian.

Since we see that this is a handshake, we refer to the handshake structure. Yes, there aren’t really 24-bit int types, but we’ll pretend.

struct SSLHandshake
{
  uint8 msg_type;
  uint24 length;
  union
  {
    HelloRequest helloRequest;
    ClientHello clientHello;
    ServerHello serverHello;
    Certificate certificate;
    ...
  } u;
};

enum SSLHandShakeType
{
  hello_request = 0,
  client_hello = 1,
  server_hello = 2,
  certificate = 11,
  ...
};

<More bits here about cipher suites and extensions>

ServerHello, Certificate, ServerHelloDone

When the server receives a ClientHello message, it responds back with three records – a ServerHello, a Certificate, and a ServerHelloDone. The reason these are three separate records is that in some cases more than three records can be sent, so the server sends a start (ServerHello) and an end (ServerHelloDone) to bracket the rest of the data. However, in most cases a single Certificate record is sent.

The ServerHello record looks like this (specifics may vary, of course):

0000:  16          ; recordType=handshake
0001:  03 01       ; sslVersion=3.1 TLS 1.0
0003:  00 35       ; recordLength = 53
0005:  02          ; handshake.msg_type = server_hello
0006:  00 00 31    ; handshake.length = 49
0009:  03 01       ; handshake.server_version = 3.1 TLS 1.0
000B:  51 E8 8C 23 ; handshake.random.gmt_unix_time (2013-07-10 00:45:23 GMT)
000F:  66 3E BA B7 92 EE 96 AC 7F 19 CA 3F 51 7B 82 13
       2E AB 3F 0D 19 7A F8 5C 51 DB 5B 7C
002B:  00          ; handshake.session_id (0 for no session resumption)
       00 35       ; selected cipher suite = TLS_RSA_WITH_AES_256_CBC_SHA
       // this is in OpenSSL as TLS1_CK_RSA_WITH_AES_256_SHA or just AES256-SHA
       00          ; compressionMethod 00=NULL
       00 09       ; server_hello_extension_list
0030:  FF 01       ; extension 65281 = renegotiation_info rfc5746
       00 01 00    ; 00 - null string?
       00 23       ; extension 35 = SessionTicket TLS rfc4507
       00 00       ; no SessionTicket

The Certificate record looks like this.

0000:  16          ; recordType=handshake
0001:  03 01       ; sslVersion=3.1 TLS 1.0
0003:  03 BE       ; recordLength = 958
0005:  0B          ; handshake.msg_type = certificate
0006:  00 03 BA    ; handshake.length = 49
0009:  00 03 B7    ; certificate length = 951
       00 03 B4 30 82 03 B0 30 82 02
       98 02 09 00 90 22 C1 87 A3 82 00 88 30 0D 06 09
       2A 86 48 86 F7 0D 01 01 05 05 00 30 81 99 31 0B
       30 09 06 03 55 04 06 13 02 55 53 31 0B 30 09 06
       03 55 04 08 13 02 43 41 31 0F 30 0D 06 03 55 04
       07 13 06 49 72 76 69 6E 65 31 1F 30 1D 06 03 55
       04 0A 13 16 42 6C 69 7A 7A 61 72 64 20 45 6E 74
       65 72 74 61 69 6E 6D 65 6E 74 31 13 30 11 06 03
       55 04 0B 13 0A 42 61 74 74 6C 65 2E 6E 65 74 31
       13 30 11 06 03 55 04 03 13 0A 62 61 74 74 6C 65
       2E 6E 65 74 31 21 30 1F 06 09 2A 86 48 86 F7 0D
       01 09 01 16 12 73 75 70 70 6F 72 74 40 62 61 74
       74 6C 65 2E 6E 65 74 30 1E 17 0D 31 33 30 37 31
       31 32 30 34 30 31 33 5A 17 0D 32 33 30 37 30 39
       32 30 34 30 31 33 5A 30 81 99 31 0B 30 09 06 03
       55 04 06 13 02 55 53 31 0B 30 09 06 03 55 04 08
       13 02 43 41 31 0F 30 0D 06 03 55 04 07 13 06 49
       72 76 69 6E 65 31 1F 30 1D 06 03 55 04 0A 13 16
       42 6C 69 7A 7A 61 72 64 20 45 6E 74 65 72 74 61
       69 6E 6D 65 6E 74 31 13 30 11 06 03 55 04 0B 13
       0A 42 61 74 74 6C 65 2E 6E 65 74 31 13 30 11 06
       03 55 04 03 13 0A 62 61 74 74 6C 65 2E 6E 65 74
       31 21 30 1F 06 09 2A 86 48 86 F7 0D 01 09 01 16
       12 73 75 70 70 6F 72 74 40 62 61 74 74 6C 65 2E
       6E 65 74 30 82 01 22 30 0D 06 09 2A 86 48 86 F7
       0D 01 01 01 05 00 03 82 01 0F 00 30 82 01 0A 02
       82 01 01 00 E1 A9 D5 0A EA 0B A4 8D 9F CE A8 9A
       95 5A A5 E8 CC 51 C1 A7 97 F7 B9 8A FA 90 B8 FD
       DA B6 26 A6 D4 2A DA D1 51 F6 C7 CE 81 CC 70 EB
       27 88 B4 07 CC A3 98 0B 96 74 BD 2C E9 BF DA 6D
       C1 D4 1F FC 4C 5D 7B 5D 71 3B E1 A0 2D FC B5 80
       54 71 F2 BD A4 59 FB 87 87 A1 27 67 AB C2 77 32
       AF 4F 6C B1 2D 60 14 40 35 89 DA B5 29 CD 54 D1
       2A C3 C3 DA 62 14 D9 90 1A 2E A9 E9 1A 0E 22 6A
       B8 1A 41 9A C9 42 82 6B 86 75 82 96 28 E1 AF D2
       DA B4 FE 28 F1 9E BB 62 0A 8D 18 05 04 5F D4 4D
       4B E2 D5 DA 01 C8 62 D4 9A CA 05 03 0F 84 63 A6
       C1 99 3D 24 3E EE FC 78 70 FF D8 9D 46 69 71 A2
       85 66 9D DD 0F 9F E2 2D EC D1 8F F3 76 3D 41 BF
       80 34 9C E2 D3 AC EB 2B 23 21 14 93 E9 57 D4 10
       74 AC AC 1E 5E 11 28 C6 1E 48 BE 13 09 9F 8D CC
       FB B0 59 14 29 A2 28 A7 2E 9C 8C E9 67 66 06 7E
       3B 3E 62 79 02 03 01 00 01 30 0D 06 09 2A 86 48
       86 F7 0D 01 01 05 05 00 03 82 01 01 00 B9 B2 76
       F6 C8 BF EF C1 16 0F 5A 93 D5 1D EE 41 0C 4C 8D
       36 F0 88 E2 0F 85 5D EA 8B 20 E6 43 68 6A 43 A4
       2B FC B2 E9 25 4B 63 CA 98 46 F6 55 8B FC 0A E3
       64 9C BF 6B 23 7B AB B5 4F 5C 8B 60 8C AC 01 3A
       E2 8? 71 8A 0D 5B 7E 96 06 A0 98 88 59 5F 18 CE
       0E 40 2C A1 30 FD 59 D0 72 5E 2E 06 06 48 9E 0A
       EA 74 C5 9E A4 1F 76 AC D2 D8 84 1C BD 63 9E 36
       BD 65 9A 8B 3C 13 C8 66 A2 5E 6C 51 74 9E B4 14
       2C 8B 62 3C D5 22 28 10 E9 C8 F6 8B 0A 3D 4B A2
       11 08 38 99 B3 2B 26 C7 ED F6 D8 48 94 47 DA ED
       C0 10 5C D9 53 BA 41 E8 9F 28 5E F4 C9 AE 9C 66
       96 17 3E 17 07 E6 43 4C 01 77 43 B4 65 3F 7A A4
       ED 1E BD 72 A4 C9 DD 4C 0A 77 22 78 DF F9 0D D9
       19 F3 F6 9B 36 22 20 D8 6C 89 35 46 4D AA CB FB
       CE 21 1B 8F 7C 06 C5 8D BD F2 7D A4 2D 95 2A A8
       76 5D 9D 4F 17 C2 35 7D F5 3C 3D 7F 68

Note that on your hard disk, a certificate is typically stored in base-64, a holdover from when certificates might be needed to be transmitted over 7-bit ASCII channels, whereas in the SSL packet, it’s stored in DER format (because it needs to be part of the overall hash to establish the session keys). I’ll disassemble the certificate later in all its forms.

The ServerHello is very simple and looks like this

// ServerHelloDone
0000:  16          ; recordType=handshake
0001:  03 01       ; sslVersion=3.1 TLS 1.0
0003:  00 04       ; recordLength = 4
       0E          ; handshake.msg_type = server_hello_done
       00 00 00    ; handshake.length = 0

Everything to this point has been transmitted in plaintext, because the client and the server haven’t yet exchanged enough information to start encrypting.

ClientKeyExchange, ChangeCipherSpec, Finished

When the client receives the server’s information, it response with a ClientKeyExchange packet that contains the last of the information needed to start an encrypted channel.

0000:  16          ; recordType=handshake
0001:  03 01       ; sslVersion=3.1 TLS 1.0
0003:  01 06       ; recordLength = 262
0005:  10          ; handshake.msg_type = client_key_exchange
0006:  00 01 02    ; handshake.length = 258
0009:  01 00       ; public_key_encrypted.length = 256
000B:  AA AD 56 74 56
0010:  48 6E 08 86 3E CF 40 EB A4 8E FA 8C 5D 06 4E DF
0020:  2B 22 14 D5 FA 0B A4 DE 44 11 EF 75 E3 09 DA F8
0030:  EC 97 82 28 9D 48 78 B6 94 90 67 24 60 C3 50 61
0040:  87 DE 30 C3 4E 74 7F 4A DD D4 0C BD 90 FB 54 6E
0050:  87 85 1A 2A EE BD D7 F3 E6 5E BB 58 72 A4 3F 0E
0060:  59 7F 66 6C E6 DF B0 1F 13 14 E0 AA 53 A7 B6 67
0070:  B6 28 54 9B F2 CC 92 FF FB 45 5E 71 93 1F FF C2
0080:  27 37 84 8F 50 E9 42 CC 48 35 59 28 52 C7 19 19
0090:  49 80 BC 53 77 A7 6A 1E A0 35 68 95 CF E2 46 45
00A0:  3A E7 D4 6A 43 C4 7B C5 CA E2 16 05 B2 7A 28 96
00B0:  3E 5B C8 25 67 8E 96 68 A5 16 27 27 87 A7 23 7D
00C0:  FC 02 23 A9 C8 67 5E DA E3 20 DE 96 D7 DA 36 96
00D0:  6B F6 E1 26 13 F3 81 A0 5C CF D5 B5 4E EB 97 38
00E0:  E4 B3 B4 A4 83 AE 0A F8 98 DB 9D EA E8 83 4F 89
00F0:  C6 F9 45 4B 49 F6 D9 51 72 0F F3 C5 CA 9F 12 57
0100:  B3 95 A4 5D C5 DE 7E B8 6F 16 6D

There’s one last bit that the client sends before records are encrypted, and that is the acknowledgement of the cipher spec selected. The reason this is a separate type is to force the message to be sent in a separate record. It’s possible to send multiple handshake messages in the same record. Since ChangeCipherSpec must not be encrypted, and Finished must be encrypted, Netscape had the Finished message be a different type. However, in reality, most SSL implementations send each handshake message in its own record, and put multiple SSL records in the same TCP segment.

ChangeCipherSpec looks like this:

// ChangeCipherSpec
0000:  14          ; recordType=change_cipher_spec
0001:  03 01       ; sslVersion=3.1 TLS 1.0
0003:  00 01       ; recordLength = 1
0005:  01          ; change_cipher_spec

Finally, the client sends a Finished record. This is sent encrypted, to prove to both sides that encryption is valid before it is used to actually start sending data.

// Finished (encrypted)
0000:  16          ; recordType=handshake
0001:  03 01       ; sslVersion=3.1 TLS 1.0
0003:  00 30       ; recordLength = 48
0005:  C0 20 65 AC F3 3C 91 54 E8 5D FB 97 DE 2E C7 B0
       D8 62 CB 49 B2 FA 13 EF 2F 4D 46 F4 81 E3 2E DC
       99 EE 1B C6 82 CD F2 03 F8 1A 13 CF 5D 11 C5 32

This is encrypted with AES-256 and using a SHA-1 for the HMAC – but we can’t see even the handshake type because it’s part of the encrypted record. As such, the Finished message is obfuscated from us. As a comparison, here’s a Finished message from a session that is using NULL-SHA, which uses a null encryption algorithm and SHA-1 for the HMAC.

0000:  16          ; recordType=handshake
0001:  03 01       ; sslVersion=3.1 TLS 1.0
0003:  00 24       ; recordLength = 36
0005:  14          ; handshake.msg_type = finished
0006:  00 00 0C    ; handshake.length = 12
       55 4E D2 B5 51 21 59 0F D7 81 16 57 ; 12-byte TLS verify_data
0015:  02 FA 45 D0 79 98 A5 56 80 0D 21 E2 C4 A5 51 92 ; SHA-1 HMAC
       03 81 3E FD

Note that the AES-encoded packet is 12 bytes larger – this is because AES in CBC mode is encrypting in blocks of 16 bytes, and so we have to pad the data to a block multiple before encrypting. Our plaintext is 4 bytes of header, 12 bytes of nonce, and 20 bytes of HMAC, for a total of 36 bytes, and we add 12 bytes of padding to get to 48 bytes, which is 3 segments of 16 bytes each. Technically, we add a 1-byte pad length and then 11 more bytes of padding – this technicality is important, because if our data was already at a 16-byte bounds, we’re forced to add another 16 bytes of padding, because the 1-byte pad length would take us over the 16-byte bound.

ChangeCipherSpec, Finished

At this point, the client has generated the master_secret from the pre_master_secret. The server still has to do a little work. This work is done in between the server receiving KeyClientExchange and ChangeCipherSpec.