SSL Certificate Exchange

A while back, I got the idea to write a blog post where I captured an entire SSL handshake in tcpdump and walked through what each byte was for and what purpose it served. So, I fired up Chrome and tcpdump, pointed Chrome at Wikipedia's home page for this purpose, and logged the SSL portion of the download, expecting to write up the whole thing in a single post. Well, it turns out that I was wildly ambitious in thinking that I could cover an entire SSL handshake in one post, especially since I only have a few hours a week to dedicate to writing this. Instead, I ended up dedicating one post to the TCP three-way handshake itself, the next to the first half of an SSL handshake, and the following post to the second half. As I tend to do when I start these sorts of things, I ended up going down lots of (hopefully interesting) rabbit trails, but I sort of glossed over two parts of the SSL handshake: the certificate exchange and the OCSP status request.

Rather than just leave these hanging, I figured I should go ahead and round out what was originally going to be a single post but grew into a multi-part series by doing more justice to these two parts of the SSL handshake. Although I've already dedicated a post to delving into the certificate signature process and don't plan to repeat all of that here, Wikipedia's SSL certificate includes a few interesting topics that I didn't cover before. Figure 1, below, shows the tcpdump output of the part of the SSL handshake that does the actual certificate exchange between me and Wikipedia.

Jump to bottom
  0x00b0:    16 0303 0bd3 0b00 0bcf 000b cc00 0760
  0x00c0:  3082 075c 3082 0644 a003 0201 0202 0c10
  0x00d0:  e6fc 62b7 418a d500 5e45 b630 0d06 092a
  0x00e0:  8648 86f7 0d01 010b 0500 3066 310b 3009
  0x00f0:  0603 5504 0613 0242 4531 1930 1706 0355
  0x0100:  040a 1310 476c 6f62 616c 5369 676e 206e
  0x0110:  762d 7361 313c 303a 0603 5504 0313 3347
  0x0120:  6c6f 6261 6c53 6967 6e20 4f72 6761 6e69
  0x0130:  7a61 7469 6f6e 2056 616c 6964 6174 696f
  0x0140:  6e20 4341 202d 2053 4841 3235 3620 2d20
  0x0150:  4732 301e 170d 3136 3131 3231 3038 3030
  0x0160:  3030 5a17 0d31 3731 3132 3230 3735 3935
  0x0170:  395a 3079 310b 3009 0603 5504 0613 0255
  0x0180:  5331 1330 1106 0355 0408 130a 4361 6c69
  0x0190:  666f 726e 6961 3116 3014 0603 5504 0713
  0x01a0:  0d53 616e 2046 7261 6e63 6973 636f 3123
  0x01b0:  3021 0603 5504 0a13 1a57 696b 696d 6564
  0x01c0:  6961 2046 6f75 6e64 6174 696f 6e2c 2049
  0x01d0:  6e63 2e31 1830 1606 0355 0403 0c0f 2a2e
  0x01e0:  7769 6b69 7065 6469 612e 6f72 6730 5930
  0x01f0:  1306 072a 8648 ce3d 0201 0608 2a86 48ce
  0x0200:  3d03 0107 0342 0004 c922 6931 8ad6 6cea
  0x0210:  dac3 7f2c aca5 afc0 02ea 81cb 65b9 fd0c
  0x0220:  6d46 5bc9 1eed b2ac 2a1b 4aec 807b e71a
  0x0230:  51e0 dff7 c74a 207b 914b 2007 21ce cf68
  0x0240:  658c c69d 3bef d5c1 a382 04c0 3082 04bc
  0x0250:  300e 0603 551d 0f01 01ff 0404 0302 0388
  0x0260:  3081 a006 082b 0601 0505 0701 0104 8193
  0x0270:  3081 9030 4d06 082b 0601 0505 0730 0286
  0x0280:  4168 7474 703a 2f2f 7365 6375 7265 2e67
  0x0290:  6c6f 6261 6c73 6967 6e2e 636f 6d2f 6361
  0x02a0:  6365 7274 2f67 736f 7267 616e 697a 6174
  0x02b0:  696f 6e76 616c 7368 6132 6732 7231 2e63
  0x02c0:  7274 303f 0608 2b06 0105 0507 3001 8633
  0x02d0:  6874 7470 3a2f 2f6f 6373 7032 2e67 6c6f
  0x02e0:  6261 6c73 6967 6e2e 636f 6d2f 6773 6f72
  0x02f0:  6761 6e69 7a61 7469 6f6e 7661 6c73 6861
  0x0300:  3267 3230 5606 0355 1d20 044f 304d 3041
  0x0310:  0609 2b06 0104 01a0 3201 1430 3430 3206
  0x0320:  082b 0601 0505 0702 0116 2668 7474 7073
  0x0330:  3a2f 2f77 7777 2e67 6c6f 6261 6c73 6967
  0x0340:  6e2e 636f 6d2f 7265 706f 7369 746f 7279
  0x0350:  2f30 0806 0667 810c 0102 0230 0906 0355
  0x0360:  1d13 0402 3000 3049 0603 551d 1f04 4230
  0x0370:  4030 3ea0 3ca0 3a86 3868 7474 703a 2f2f
  0x0380:  6372 6c2e 676c 6f62 616c 7369 676e 2e63
  0x0390:  6f6d 2f67 732f 6773 6f72 6761 6e69 7a61
  0x03a0:  7469 6f6e 7661 6c73 6861 3267 322e 6372
  0x03b0:  6c30 8202 f806 0355 1d11 0482 02ef 3082
  0x03c0:  02eb 820f 2a2e 7769 6b69 7065 6469 612e
  0x03d0:  6f72 6782 112a 2e6d 2e6d 6564 6961 7769
  0x03e0:  6b69 2e6f 7267 8211 2a2e 6d2e 7769 6b69
  0x03f0:  626f 6f6b 732e 6f72 6782 102a 2e6d 2e77
  0x0400:  696b 6964 6174 612e 6f72 6782 112a 2e6d
  0x0410:  2e77 696b 696d 6564 6961 2e6f 7267 821b
  0x0420:  2a2e 6d2e 7769 6b69 6d65 6469 6166 6f75
  0x0430:  6e64 6174 696f 6e2e 6f72 6782 102a 2e6d
  0x0440:  2e77 696b 696e 6577 732e 6f72 6782 112a
  0x0450:  2e6d 2e77 696b 6970 6564 6961 2e6f 7267
  0x0460:  8211 2a2e 6d2e 7769 6b69 7175 6f74 652e
  0x0470:  6f72 6782 122a 2e6d 2e77 696b 6973 6f75
  0x0480:  7263 652e 6f72 6782 132a 2e6d 2e77 696b
  0x0490:  6976 6572 7369 7479 2e6f 7267 8212 2a2e
  0x04a0:  6d2e 7769 6b69 766f 7961 6765 2e6f 7267
  0x04b0:  8212 2a2e 6d2e 7769 6b74 696f 6e61 7279
  0x04c0:  2e6f 7267 820f 2a2e 6d65 6469 6177 696b
  0x04d0:  692e 6f72 6782 162a 2e70 6c61 6e65 742e
  0x04e0:  7769 6b69 6d65 6469 612e 6f72 6782 0f2a
  0x04f0:  2e77 696b 6962 6f6f 6b73 2e6f 7267 820e
  0x0500:  2a2e 7769 6b69 6461 7461 2e6f 7267 820f
  0x0510:  2a2e 7769 6b69 6d65 6469 612e 6f72 6782
  0x0520:  192a 2e77 696b 696d 6564 6961 666f 756e
  0x0530:  6461 7469 6f6e 2e6f 7267 820e 2a2e 7769
  0x0540:  6b69 6e65 7773 2e6f 7267 820f 2a2e 7769
  0x0550:  6b69 7175 6f74 652e 6f72 6782 102a 2e77
  0x0560:  696b 6973 6f75 7263 652e 6f72 6782 112a
  0x0570:  2e77 696b 6976 6572 7369 7479 2e6f 7267
  0x0580:  8210 2a2e 7769 6b69 766f 7961 6765 2e6f
  0x0590:  7267 8210 2a2e 7769 6b74 696f 6e61 7279
  0x05a0:  2e6f 7267 8214 2a2e 776d 6675 7365 7263
  0x05b0:  6f6e 7465 6e74 2e6f 7267 8214 2a2e 7a65
  0x05c0:  726f 2e77 696b 6970 6564 6961 2e6f 7267
  0x05d0:  820d 6d65 6469 6177 696b 692e 6f72 6782
  0x05e0:  0677 2e77 696b 6982 0d77
11:00:59.005142 IP > Flags [.], 
seq 1449:2897, ack 206, win 59, options [nop,nop,TS val 46043123 ecr 337164135], length 1448
  0x0040:       696b 6962 6f6f 6b73 2e6f 7267 820c
  0x0050:  7769 6b69 6461 7461 2e6f 7267 820d 7769
  0x0060:  6b69 6d65 6469 612e 6f72 6782 1777 696b
  0x0070:  696d 6564 6961 666f 756e 6461 7469 6f6e
  0x0080:  2e6f 7267 820c 7769 6b69 6e65 7773 2e6f
  0x0090:  7267 820d 7769 6b69 7175 6f74 652e 6f72
  0x00a0:  6782 0e77 696b 6973 6f75 7263 652e 6f72
  0x00b0:  6782 0f77 696b 6976 6572 7369 7479 2e6f
  0x00c0:  7267 820e 7769 6b69 766f 7961 6765 2e6f
  0x00d0:  7267 820e 7769 6b74 696f 6e61 7279 2e6f
  0x00e0:  7267 8212 776d 6675 7365 7263 6f6e 7465
  0x00f0:  6e74 2e6f 7267 820d 7769 6b69 7065 6469
  0x0100:  612e 6f72 6730 1d06 0355 1d25 0416 3014
  0x0110:  0608 2b06 0105 0507 0301 0608 2b06 0105
  0x0120:  0507 0302 301d 0603 551d 0e04 1604 1428
  0x0130:  2a26 2a57 8b3b ceb4 d6ab 54ef d738 212c
  0x0140:  495c 3630 1f06 0355 1d23 0418 3016 8014
  0x0150:  96de 61f1 bd1c 1629 531c c0cc 7d3b 8300
  0x0160:  40e6 1a7c 300d 0609 2a86 4886 f70d 0101
  0x0170:  0b05 0003 8201 0100 8bc3 edd1 9d39 6faf
  0x0180:  4072 bd1e 185e 3054 2335 665e 62d5 01e2
  0x0190:  6347 70cb 6d1b 17b0 f54d 11e4 ad94 51c5
  0x01a0:  5e72 03b0 d5ab 18eb b53a 08a8 7395 f37f
  0x01b0:  411a 287b 457c 832e d314 95d8 d5d1 5f99
  0x01c0:  4b0c f4c3 9b0b 4fe9 49f4 2cb5 aec3 1d7d
  0x01d0:  2a80 f670 294c 0ce6 e0cb 888a 8a02 eea5
  0x01e0:  d173 c293 5824 ff43 1be3 fd7b aaf0 150c
  0x01f0:  6052 8f21 7d87 3a14 fa81 4100 604f 969a
  0x0200:  6294 58de cb15 5c3c f4c1 4d33 e3ff 39fe
  0x0210:  28fb b041 3ed2 8a11 d106 0128 747d 71d4
  0x0220:  2aef 1fe3 254b 2df0 66ef 26fb 4cf0 8185
  0x0230:  bb1a 9906 c937 87de 8d49 f700 91a9 4231
  0x0240:  4ab9 40a0 7d4f 4fa6 ead4 5807 3c01 e01a
  0x0250:  5354 66e1 a37e 30cd 3bf8 6959 a348 9248
  0x0260:  e19e 63ab 0870 91f2 48d2 834b 9806 fafd
  0x0270:  bc99 02da 9c98 b1a3 0004 6630 8204 6230
  0x0280:  8203 4aa0 0302 0102 020b 0400 0000 0001
  0x0290:  3189 c644 c930 0d06 092a 8648 86f7 0d01
  0x02a0:  010b 0500 304c 3120 301e 0603 5504 0b13
  0x02b0:  1747 6c6f 6261 6c53 6967 6e20 526f 6f74
  0x02c0:  2043 4120 2d20 5233 3113 3011 0603 5504
  0x02d0:  0a13 0a47 6c6f 6261 6c53 6967 6e31 1330
  0x02e0:  1106 0355 0403 130a 476c 6f62 616c 5369
  0x02f0:  676e 301e 170d 3131 3038 3032 3130 3030
  0x0300:  3030 5a17 0d32 3230 3830 3231 3030 3030
  0x0310:  305a 3066 310b 3009 0603 5504 0613 0242
  0x0320:  4531 1930 1706 0355 040a 1310 476c 6f62
  0x0330:  616c 5369 676e 206e 762d 7361 313c 303a
  0x0340:  0603 5504 0313 3347 6c6f 6261 6c53 6967
  0x0350:  6e20 4f72 6761 6e69 7a61 7469 6f6e 2056
  0x0360:  616c 6964 6174 696f 6e20 4341 202d 2053
  0x0370:  4841 3235 3620 2d20 4732 3082 0122 300d
  0x0380:  0609 2a86 4886 f70d 0101 0105 0003 8201
  0x0390:  0f00 3082 010a 0282 0101 00c7 0e6c 3f23
  0x03a0:  937f cc70 a59d 20c3 0e53 3f7e c04e c298
  0x03b0:  49ca 47d5 23ef 0334 8574 c8a3 022e 465c
  0x03c0:  0b7d c988 9d4f 8bf0 f89c 6c8c 5535 dbbf
  0x03d0:  f2b3 eafb e356 e74a 46d9 1322 ca36 d59b
  0x03e0:  c1a8 e396 4393 f20c bce6 f9e6 e899 c863
  0x03f0:  4878 7f57 3669 1a19 1d5a d1d4 7dc2 9cd4
  0x0400:  7fe1 8012 ae7a ea88 ea57 d8ca 0a0a 3a12
  0x0410:  49a2 6219 7a0d 24f7 37eb b473 927b 0523
  0x0420:  9b12 b5ce eb29 dfa4 1402 b901 a5d4 a69c
  0x0430:  4364 88de f87e fee3 f51e e5fe dca3 a8e4
  0x0440:  6631 d94c 25e9 18b9 8959 09ae e99d 1c6d
  0x0450:  370f 4a1e 3520 28e2 afd4 218b 01c4 45ad
  0x0460:  6e2b 63ab 926b 610a 4d20 ed73 ba7c cefe
  0x0470:  16b5 db9f 80f0 d68b 6cd9 0879 4a4f 7865
  0x0480:  da92 bcbe 35f9 b3c4 f927 804e ff96 52e6
  0x0490:  0220 e107 73e9 5d2b bdb2 f102 0301 0001
  0x04a0:  a382 0129 3082 0125 300e 0603 551d 0f01
  0x04b0:  01ff 0404 0302 0106 3012 0603 551d 1301
  0x04c0:  01ff 0408 3006 0101 ff02 0100 301d 0603
  0x04d0:  551d 0e04 1604 1496 de61 f1bd 1c16 2953
  0x04e0:  1cc0 cc7d 3b83 0040 e61a 7c30 4706 0355
  0x04f0:  1d20 0440 303e 303c 0604 551d 2000 3034
  0x0500:  3032 0608 2b06 0105 0507 0201 1626 6874
  0x0510:  7470 733a 2f2f 7777 772e 676c 6f62 616c
  0x0520:  7369 676e 2e63 6f6d 2f72 6570 6f73 6974
  0x0530:  6f72 792f 3036 0603 551d 1f04 2f30 2d30
  0x0540:  2ba0 29a0 2786 2568 7474 703a 2f2f 6372
  0x0550:  6c2e 676c 6f62 616c 7369 676e 2e6e 6574
  0x0560:  2f72 6f6f 742d 7233 2e63 726c 303e 0608
  0x0570:  2b06 0105 0507 0101 0432 3030 302e 0608
  0x0580:  2b06 0105 0507 3001 8622 6874 7470 3a2f
  0x0590:  2f6f 6373 7032 2e67 6c6f 6261 6c73 6967
  0x05a0:  6e2e 636f 6d2f 726f 6f74 7233 301f 0603
  0x05b0:  551d 2304 1830 1680 148f f04b 7fa8 2e45
  0x05c0:  24ae 4d50 fa63 9a8b dee2 dd1b bc30 0d06
  0x05d0:  092a 8648 86f7 0d01 010b 0500 0382 0101
  0x05e0:  00ba 0629 c0b4 198c 2111
11:00:59.005143 IP > Flags [.], 
seq 2897:4345, ack 206, win 59, options [nop,nop,TS val 46043123 ecr 337164135], length 1448
  0x0040:       c094 119e bb3d d4d5 4340 f69f bb25
  0x0050:  0b23 68b5 1af7 fa54 64cc 2b13 f921 f044
  0x0060:  ade1 e815 58db eefd dba2 4dcc 188f 0d9a
  0x0070:  6dc3 6b01 a131 f08d bc00 40cc 395f 8761
  0x0080:  516d f495 eaea 1535 3e40 85c0 62d5 a134
  0x0090:  fe78 aaa8 b25a 39f3 3741 fb9c e83e 714a
  0x00a0:  5beb f869 58a1 e0c6 9377 e9ba 6792 eb65
  0x00b0:  5890 7073 427d aff4 2326 7917 aafa a4bb
  0x00c0:  99e5 446f 6581 e7ca eb55 c8f4 b627 1121
  0x00d0:  7494 bc6b b774 6229 c4cd ae47 f2e6 425b
  0x00e0:  7886 0561 cb90 aa79 89df 047e b126 704b
  0x00f0:  8d40 1f84 7bc0 fb07 e6c8 b74e 91f4 3503
  0x0100:  ede8 eb41 1017 49b4 62c8 a72c f2e1 4c8f
  0x0110:  032c f316 375d 67f1 a439 7949 a3c0 5dcc
  0x0120:  55f9 2180 0ffb cee2 296a 5850 e9a6 d7eb
  0x0130:  1c32 36b5 62a7 c1fa e6

Figure 1: tcpdump capture of Wikipedia's certificate exchange

Per the TLS specification, section 7.3, the server certificate is the third message exchanged in an ordinary SSL/TLS handshake, right after the client hello and the server hello. Strictly speaking, the certificate message is optional; the client could have negotiated a certificate-less key exchange algorithm like anonymous Diffie-Hellman. In actual practice, though, this is never done, since it offers no protection against man-in-the-middle attacks, so it's safe to say that a certificate message such as the one shown in figure 1 is effectively always required and always the third message in any SSL/TLS handshake.

So, the certificate is the logical third record in the TLS handshake. The TLS record protocol, however, allows multiple TLS messages to be bundled together for efficiency's sake, so the certificate message immediately follows the server hello message. As you can see from figure 1, the certificate message is also very long: the TLS record protocol also permits messages to cross TCP segment boundaries, which is good because the certificate message is 3027 bytes long, but the maximum negotiated TCP record size is 1448 bytes, so this certificate message will necessarily span at least three TCP segments. If you look closely, you may notice that I bolded three bytes near the middle of the second TCP segment (at 0x270); this is the delimiter between the site's certificate and the signing certificate. I'll discuss more what that means, exactly, below.

If you look at the first few bytes of the SSL certificate message from figure 1, repeated in figure 2, it starts out looking fairly familiar, if you've followed the client hello and server hello discussions: a set of marker/version/length indicators (including some redundant length indicators), but after 15 bytes of prologue, the structure changes completely. The 1,888 bytes that follow are not specified by TLS at all, but instead are an ASN.1 DER-encoded representation of a certificate as defined by the X.509 ITU-T standard.

  0x00b1: 16       Handshake marker
  0x00b2: 0303     Version (TLS 1.2)
  0x00b4: 0bd3     Length: 3027 bytes
  0x00b6: 0b       Handshake type certificate
  0x00b7: 000bcf   Length: 3023 bytes
  0x00ba: 000bcc   Length: 3020 bytes
  0x00bd: 000760  iLength: 1888 bytes
  0x00c0: 3082075c30820644a003020102020c10e6fc62b7418ad5005e45b6300d06092a...  Certificate

Figure 2: partially unrolled certificate exchange message

If you've been around SSL certificates much, you're probably used to seeing certificates like the one shown below in figure 3.


Figure 3: PEM-encoded certificate

In fact, besides the "BEGIN CERTIFICATE"/"END CERTIFICATE" markers this is actually a base64 encoded representation of exactly the same 1,888 bytes that are transmitted in the certificate exchange message above. If you've ever been curious what the difference between PEM encoding and DER encoding is, now you know: PEM encoding is the DER encoding in base64 format with a couple of header and footer delimiters surrounding it.

I won't get into the nitty-gritty details of the ASN.1 encoding here, but in essence it's a platform-agnostic way to transmit structured data between heterogeneous systems: structures are collections of strings, numbers, timestamps and other structures, potentially bundled into repeating array-like structures. The openssl tool includes a handy utility that parses and outputs a structured representation of an X.509 certificate. The output of this utility applied to Wikipedia's public certificate is shown in figure 4.

$ openssl x509 -in wikipedia.pem -noout -text
        Version: 3 (0x2)
        Serial Number:
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=BE, O=GlobalSign nv-sa, CN=GlobalSign Organization Validation CA - SHA256 - G2
            Not Before: Nov 21 08:00:00 2016 GMT
            Not After : Nov 22 07:59:59 2017 GMT
        Subject: C=US, ST=California, L=San Francisco, O=Wikimedia Foundation, Inc., CN=*
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                ASN1 OID: prime256v1
                NIST CURVE: P-256
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature, Key Agreement
            Authority Information Access: 
                CA Issuers - URI:
                OCSP - URI:

            X509v3 Certificate Policies: 

            X509v3 Basic Constraints: 
            X509v3 CRL Distribution Points: 

                Full Name:

            X509v3 Subject Alternative Name: 
                DNS:*, DNS:*, DNS:*, 
                DNS:*, DNS:*, DNS:*, 
                DNS:*, DNS:*, DNS:*, 
                DNS:*, DNS:*, DNS:*, 
                DNS:*, DNS:*, DNS:*, 
                DNS:*, DNS:*, DNS:*, 
                DNS:*, DNS:*, DNS:*, 
                DNS:*, DNS:*, DNS:*, 
                DNS:*, DNS:*, DNS:*, 
            X509v3 Extended Key Usage: 
                TLS Web Server Authentication, TLS Web Client Authentication
            X509v3 Subject Key Identifier: 
            X509v3 Authority Key Identifier: 

    Signature Algorithm: sha256WithRSAEncryption

Figure 4: Parsed certificate

You may recall from my previous posts that an X.509 certificate can be viewed as an association between a principal and a public key: the certificate asserts that the principal is identified by the public key. There are five essential parts to the certificate, then:

  1. The principal being identified
  2. The public key that identifies the principal
  3. The identity of the asserting party, called the issuer — who exactly is it that is asserting that this principal is identified by the public key?
  4. A grab-bag of additional attributes including the validity period (start and end date) and what purpose this public key should be considered legitimate for
  5. A digital signature that can be used to verify the issuer's assertion that this key identifies this principal — or, at least, to verify that the issuer really did say that this key identifies this principal, sidestepping the thornier issue of how much trust you can or should put into the issuer.

The principal is identified by the subject, shown in figure 4 to be C=US, ST=California, L=San Francisco, O=Wikimedia Foundation, Inc., CN=* This is a standard X.500 name, but the TLS standard ignores everything except the CN component, which it matches against the requested hostname, honoring wildcards such as the * above. So, since I requested and the certificate is for principal *, TLS accepts this certificate as being valid to identify this web site (however, see below for the discussion on subject alternative names). Note that at this point, I haven't established whether I should trust or accept this certificate, I've just established that it's the one I expected, rather than a certificate for an entirely different web site. Remember, the point of the TLS handshake is to create a strong cryptographic binding between my browser and a web site's server; to do that, at a minimum, I have to establish with confidence that I'm connecting to the correct server.

The public key is shown in the Subject Public Key Info section, as you probably guessed. As I detailed in my last post, Wikipedia is using a modern Elliptic-Curve public key which is used along with the ECDSA protocol to perform a secure key exchange. See my previous post for more detail.

The issuer — the asserting party — is listed under Issuer and is shown here as C=BE, O=GlobalSign nv-sa, CN=GlobalSign Organization Validation CA - SHA256 - G2. At this point, my browser does a check to see if it trusts this issuer. If it does, it can verify the signature and accept (assuming the verification passes) this certificate and its public key. If it doesn't, however, there is a recourse: see below.

The "arbitrary attributes" take up the majority of the space in the certificate. First, there's a version (version 3) of the certificate structure and a serial number. There's a validity period: a start and end date outside of which this certificate should not be accepted (I'll talk a little more about that in conjunction with the OCSP status message in my next post). Then there is a list of 9 extensions: key usage, authority information access, certificate policies, basic constraints, CRL distribution points, subject alternative names, extended key usage, subject key identifier and authority key identifier. It's worth noting that none of the extensions are, or even can be, set by the requester — the issuing certificate authority sets all of these based on information it retrieves as part of the certificate validation process. In essence, these tell the browser how much faith to put in the public key.

The first version of the X.509 certificate specification only included serial number, issuer, subject, validity and public key. Later versions allowed for an ever-growing list of extension attributes to address other useful properties. For the purposes of backward compatibility, though, it was important to allow older versions to ignore extensions that they didn't recognize, but also to allow certificate signers to declare certain extensions non-ignorable — that is, if you don't recognize this extension, you should reject the certificate. For this reason, extensions can be declared "critical": unless the extension is marked critical, it can be safely ignored. If it is recognized, though, it can contain useful information on handling the certificate. Like TCP extensions and SSL client/server hello extensions, X.509 extensions are defined as a tag, a length, and a value whose interpretation varies depending on the tag. If the tag isn't recognized, the inclusion of the length indicator allows the parser to skip over it.

Key Usage

The key usage extension is the only one marked critical - if the browser receives this extension and doesn't know what to do with it, it should reject the certificate and abort the connection altogether. Key usage is a single byte whose individual bits indicate what the public key in this certificate is allowed to do.

Why, you may wonder, is this considered critical? It's actually a workaround to a fatal flaw that was discovered in the X.509 PKI structure after it had been widely deployed. The browser (or, more generally, the relying party) trusts a limited set of certificate authorities to sign certificates. However, since it transitively trusts these certificates, there was nothing stopping the now-trusted certificate from turning around and signing a different certificate which contained false information! The key usage extension indicates exactly what the public key in this certificate is permitted to do: specifically produce digital signatures and perform key agreement.

Extended Key Usage

The key usage extensions is a single byte that can be quickly consulted to determine what the CA has verified the key to be used for. Extended key usage, on the other hand, is helpful, but not critical information about the public key. In the openssl output shown in figure 4, the extended key usage is listed as "TLS Web Server Authentication, TLS Web Client Authentication", which is pretty self-explanatory. However, these values are stored in the certificate itself in the form of Object Identifier (OID)s: a globally-unique sequence of numbers that act as an unambiguous representation of some human-meaningful concept. For instance, the "server authentication" OID is

Basic Constraints

The Basic Constraints interact with the key usage fields to indicate further what the purpose of this certificate is: in particular, the basic constraints indicates how many "subcertificates" this certificate can be the root signer for. In this case, that number is 0, since this is not a CA certificate.

Certificate Policies

A certificate policy is meant to describe how the certificate authority went about validating the subject of the certificate before signing the certificate and thereby providing its "seal of approval" that the party requesting the certificate in the first place was legitimately acting on behalf of the subject identified by the common name. Like extended key usage, these are provided in the form of OIDs: this certificate was issued by a CA that is compliant with baseline requirements and additionally has it's own certificate policy.

Authority Information Access

Like the certificate policies extension, the authority access information is non-critical, and informative: in particular, it points to a URL where you can go to download the signing certificate as well as the Online Certificate Status Protocol (OCSP) endpoint. I'll talk more about OCSP in my next post.

Subject Alternative Name

The purpose of this one is probably fairly evident from its contents: it identifies a list of other domain names, besides the one identified by the subject's common name that this certificate should be considered valid for. Interestingly, in the past few months, Chrome has begun rejecting certificates that don't contain this extension or that don't have the requested domain name included in the list, as recommended by RFC 2818 and by the CA/Browser Forum. Although at the moment, Chrome is the only browser rejecting certificates that lack this extensions, it's almost certain other browsers will follow suit.

Authority Key Identifier

Notice that the issuer was identified using an X.500 common name (CN). However, all valid X.509 certificates have validity periods and, by extension, expiration dates after which they should be rejected, and CA certificates are no exception. So, what happens when the CA certificate expires and is reissued? Does the CN have to be updated so that every client can locate the correct certificate to use to validate the signature? This was a problem with early attempts at a PKI, so the authority key identifier extension was introduced to help the client figure out which "edition" of the issuer's certificate to use.

Notice that this extension is not marked critical — if it's present but not understood, the browser is allowed to make its best effort at finding the correct certificate based only on the issuer's common name. Of course, if the last certificate it has on file has expired, the signature verification is going to fail anyway.

In this case, the authority key identifier is 96:DE:61:F1:BD:1C:16:29:53:1C:C0:CC:7D:3B:83:00:40:E6:1A:7C. What exactly does this sequence of bytes represent? Read on...

Subject Key Identifier

The subject key identifier is a unique code that is strongly tied to the certificate's public key. Although the specification leaves it open as to how this should be generated, it's usually (and is in this case) the SHA-1 hash of the bytes that make up the public key. These bytes are:

Whose SHA-1 hash is 28:2A:26:2A:57:8B:3B:CE:B4:D6:AB:54:EF:D7:38:21:2C:49:5C:36, which you may verify yourself.

So, just as the site certificate includes a subject key identifier, so does the CA certificate, which is also the SHA-1 hash of its public key.

CRL Distribution Points

So, a certificate authority signs a certificate request which contains a public key and a common name. Now, any entity who's interested in checking the status of the certificate can use the CA's public key to verify the signature and ensure that the public key identifies the subject and, by extension, that the holder of the private key is the subject. So, what happens if the private key is compromised?

At this point, the compromiser of the private key can masquerade as the holder of the certificate for as long as the validity period of the certificate. Although he can't change any of the information in the certificate without invalidating the signature, he can spoof DNS entries to re-route traffic to his own site, present what appears to the browser to be a perfectly legitimate certificate (which, in fact, it is), and demonstrate the legitimacy of the certificate by producing valid signatures using the stolen private key. The legitimate domain owner is powerless to stop this, since the signature is a mathematical relationship.

This is where Certificate Revocation List (CRL)s come into play. The CA is responsible for keeping track of which certificates it has issued (that is, signed), by serial number. If the legitimate owner of the certificate, as identified by their private key, reports that the key has been compromised, they must revoke that certificate by adding it to a list of revoked certificates which the client is expected to consult. My browser doesn't — instead, it relies on the more sophisticated Online Certificate Status Protocol (OCSP) which will be the subject of my next post.

The CRL itself is distributed via HTTP in binary form. If you download one and care to look at its contents, openssl includes a tool to do so, as shown in figure 5.

$ openssl crl -in ~/Downloads/gsorganizationvalsha2g2.crl -inform der -noout -text
Certificate Revocation List (CRL):
        Version 2 (0x1)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: /C=BE/O=GlobalSign nv-sa/CN=GlobalSign Organization Validation CA - SHA256 - G2
        Last Update: Jul 26 09:57:50 2017 GMT
        Next Update: Aug  2 09:57:50 2017 GMT
        CRL extensions:
            X509v3 Authority Key Identifier: 

            X509v3 CRL Number: 
Revoked Certificates:
    Serial Number: 38737DC1F3BFCD09D5A648C1
        Revocation Date: Dec  5 16:11:02 2016 GMT
    Serial Number: 57B908F12B4AE687A0B8A137
    Signature Algorithm: sha256WithRSAEncryption

Figure 5: Truncated GlobalSign CRL contents

The CRL is, of course, signed by the certificate authority. Notice that the CRL itself has extensions just like the certificate: one of which is the authority key identifier.

Finally, after all of the extensions have been parsed, there's the signature that provides cryptographic evidence that the issuer actually issued this certificate to this principal/subject. I detailed the signature process in detail here. One interesting point to note, though: Wikipedia's public key is an ECDSA key, but this signature is an RSA signature! There's nothing fundamentally wrong with this — the signature just establishes the validity of a sequence of bytes; the meaning and interpretation of those bytes is up to the receiver.

Above, I mentioned that my browser may or may not trust the issuer of a particular certificate. And, in fact, in my case, my browser didn't trust the certificate whose common name was GlobalSign Organization Validation CA - SHA256 to issue a certificate. Wikipedia anticipated, this though, and went ahead and sent that certificate immediately following its own server certificate. If you refer back to figure 2, you'll notice that the server certificate message was 3,020 bytes, but Wikipedia's server certificate was only 1,888. The signing certificate accounts for the 1,126 of the remaining 1,132 bytes (the other six are the length markers themselves). So, since I don't trust the signer of Wikipedia's server certificate, but they included that certificate, I can check to see if I trust the signer of that certificate which it turns out that I do, verify the signature and then recursively establish enough trust to verify the server certificate and ultimately accept its public key.

        Version: 3 (0x2)
        Serial Number:
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: OU=GlobalSign Root CA - R3, O=GlobalSign, CN=GlobalSign
            Not Before: Aug  2 10:00:00 2011 GMT
            Not After : Aug  2 10:00:00 2022 GMT
        Subject: C=BE, O=GlobalSign nv-sa, CN=GlobalSign Organization Validation CA - SHA256 - G2
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Key Usage: critical
                Certificate Sign, CRL Sign
            X509v3 Basic Constraints: critical
                CA:TRUE, pathlen:0
            X509v3 Subject Key Identifier: 
            X509v3 Certificate Policies: 
                Policy: X509v3 Any Policy

            X509v3 CRL Distribution Points: 

                Full Name:

            Authority Information Access: 
                OCSP - URI:

            X509v3 Authority Key Identifier: 

    Signature Algorithm: sha256WithRSAEncryption

Figure 6: Global Sign Intermediate Certificate

The Global Sign intermediate certificate, which was provided by the server in the initial SSL handshake, is shown in figure 6. Most of it looks similar to the site certificate shown in figure 4: note, however, that the public key is a 2048-bit RSA key, and the key usage extension and basic constraints extensions indicate that this certificate is legitimate as a certificate signer. This is good, because otherwise the browser would have rejected it. You might also want to compare the subject key identifier in this certificate with the authority key identifier shown in figure 4, as they must match.

Finally, this certificate is signed by yet another certificate whose details are embedded in my browser, as it must be in order for the handshake to be completed.

Add a comment:

Completely off-topic or spam comments will be removed at the discretion of the moderator.

You may preserve formatting (e.g. a code sample) by indenting with four spaces preceding the formatted line(s)

Name: Name is required
Email (will not be displayed publicly):
Comment is required
david wong, 2017-07-31
> However, since it transitively trusts these certificates, there was nothing stopping the now-trusted certificate from turning around and signing a different certificate which contained false information

The Basic Constraint field should be enough to prevent this case. I'm not sure about the real utility of this field in internet certificates.
Josh, 2017-08-02
I noticed this as well as I was writing this up; it seems like you would need one or the other, but not both. I’ve been trying to dig deeper into this, but I believe that the reason both are present is because RFC 2459 states that basic constraints should _not_ appear in end-entity certificates, but RFC 3280 which obsoletes 2459 states that it may. The best I can tell is that both are included in the case of older browsers that might not be looking for the basic constraints extension. I haven’t been able to find any definitive conclusion as to whether or not that’s the case, though.
My Book

I'm the author of the book "Implementing SSL/TLS Using Cryptography and PKI". Like the title says, this is a from-the-ground-up examination of the SSL protocol that provides security, integrity and privacy to most application-level internet protocols, most notably HTTP. I include the source code to a complete working SSL implementation, including the most popular cryptographic algorithms (DES, 3DES, RC4, AES, RSA, DSA, Diffie-Hellman, HMAC, MD5, SHA-1, SHA-256, and ECC), and show how they all fit together to provide transport-layer security.

My Picture

Joshua Davies

Past Posts