Home | History | Annotate | Download | only in cast_channel
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "extensions/browser/api/cast_channel/cast_auth_util.h"
      6 
      7 #include <cert.h>
      8 #include <cryptohi.h>
      9 #include <pk11pub.h>
     10 #include <seccomon.h>
     11 #include <string>
     12 
     13 #include "base/logging.h"
     14 #include "base/strings/stringprintf.h"
     15 #include "crypto/nss_util.h"
     16 #include "crypto/scoped_nss_types.h"
     17 #include "extensions/browser/api/cast_channel/cast_message_util.h"
     18 #include "extensions/common/api/cast_channel/cast_channel.pb.h"
     19 #include "net/base/hash_value.h"
     20 #include "net/cert/x509_certificate.h"
     21 
     22 namespace extensions {
     23 namespace core_api {
     24 namespace cast_channel {
     25 
     26 namespace {
     27 
     28 // Fingerprints and public keys of the allowed / trusted ICAs.
     29 static const net::SHA1HashValue kFingerprintICA1 = { {
     30     0x57,0x16,0xE2,0xAD,0x73,0x2E,0xBE,0xDA,0xEB,0x18,
     31     0xE8,0x47,0x15,0xA8,0xDE,0x90,0x3B,0x5E,0x2A,0xF4
     32 } };
     33 static const unsigned char kPublicKeyICA1[] = {
     34     0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xBC,0x22,0x80,
     35     0xBD,0x80,0xF6,0x3A,0x21,0x00,0x3B,0xAE,0x76,0x5E,0x35,0x7F,
     36     0x3D,0xC3,0x64,0x5C,0x55,0x94,0x86,0x34,0x2F,0x05,0x87,0x28,
     37     0xCD,0xF7,0x69,0x8C,0x17,0xB3,0x50,0xA7,0xB8,0x82,0xFA,0xDF,
     38     0xC7,0x43,0x2D,0xD6,0x7E,0xAB,0xA0,0x6F,0xB7,0x13,0x72,0x80,
     39     0xA4,0x47,0x15,0xC1,0x20,0x99,0x50,0xCD,0xEC,0x14,0x62,0x09,
     40     0x5B,0xA4,0x98,0xCD,0xD2,0x41,0xB6,0x36,0x4E,0xFF,0xE8,0x2E,
     41     0x32,0x30,0x4A,0x81,0xA8,0x42,0xA3,0x6C,0x9B,0x33,0x6E,0xCA,
     42     0xB2,0xF5,0x53,0x66,0xE0,0x27,0x53,0x86,0x1A,0x85,0x1E,0xA7,
     43     0x39,0x3F,0x4A,0x77,0x8E,0xFB,0x54,0x66,0x66,0xFB,0x58,0x54,
     44     0xC0,0x5E,0x39,0xC7,0xF5,0x50,0x06,0x0B,0xE0,0x8A,0xD4,0xCE,
     45     0xE1,0x6A,0x55,0x1F,0x8B,0x17,0x00,0xE6,0x69,0xA3,0x27,0xE6,
     46     0x08,0x25,0x69,0x3C,0x12,0x9D,0x8D,0x05,0x2C,0xD6,0x2E,0xA2,
     47     0x31,0xDE,0xB4,0x52,0x50,0xD6,0x20,0x49,0xDE,0x71,0xA0,0xF9,
     48     0xAD,0x20,0x40,0x12,0xF1,0xDD,0x25,0xEB,0xD5,0xE6,0xB8,0x36,
     49     0xF4,0xD6,0x8F,0x7F,0xCA,0x43,0xDC,0xD7,0x10,0x5B,0xE6,0x3F,
     50     0x51,0x8A,0x85,0xB3,0xF3,0xFF,0xF6,0x03,0x2D,0xCB,0x23,0x4F,
     51     0x9C,0xAD,0x18,0xE7,0x93,0x05,0x8C,0xAC,0x52,0x9A,0xF7,0x4C,
     52     0xE9,0x99,0x7A,0xBE,0x6E,0x7E,0x4D,0x0A,0xE3,0xC6,0x1C,0xA9,
     53     0x93,0xFA,0x3A,0xA5,0x91,0x5D,0x1C,0xBD,0x66,0xEB,0xCC,0x60,
     54     0xDC,0x86,0x74,0xCA,0xCF,0xF8,0x92,0x1C,0x98,0x7D,0x57,0xFA,
     55     0x61,0x47,0x9E,0xAB,0x80,0xB7,0xE4,0x48,0x80,0x2A,0x92,0xC5,
     56     0x1B,0x02,0x03,0x01,0x00,0x01
     57 };
     58 
     59 static const net::SHA1HashValue kFingerprintICA2 = { {
     60     0x1B,0xA2,0x9E,0xC9,0x8E,0x4E,0xB3,0x80,0xEE,0x55,
     61     0xB2,0x97,0xFD,0x2E,0x2B,0x2C,0xB6,0x8E,0x0B,0x2F
     62 } };
     63 static const unsigned char kPublicKeyICA2[] = {
     64     0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xBC,0x22,0x80,
     65     0xBD,0x80,0xF6,0x3A,0x21,0x00,0x3B,0xAE,0x76,0x5E,0x35,0x7F,
     66     0x3D,0xC3,0x64,0x5C,0x55,0x94,0x86,0x34,0x2F,0x05,0x87,0x28,
     67     0xCD,0xF7,0x69,0x8C,0x17,0xB3,0x50,0xA7,0xB8,0x82,0xFA,0xDF,
     68     0xC7,0x43,0x2D,0xD6,0x7E,0xAB,0xA0,0x6F,0xB7,0x13,0x72,0x80,
     69     0xA4,0x47,0x15,0xC1,0x20,0x99,0x50,0xCD,0xEC,0x14,0x62,0x09,
     70     0x5B,0xA4,0x98,0xCD,0xD2,0x41,0xB6,0x36,0x4E,0xFF,0xE8,0x2E,
     71     0x32,0x30,0x4A,0x81,0xA8,0x42,0xA3,0x6C,0x9B,0x33,0x6E,0xCA,
     72     0xB2,0xF5,0x53,0x66,0xE0,0x27,0x53,0x86,0x1A,0x85,0x1E,0xA7,
     73     0x39,0x3F,0x4A,0x77,0x8E,0xFB,0x54,0x66,0x66,0xFB,0x58,0x54,
     74     0xC0,0x5E,0x39,0xC7,0xF5,0x50,0x06,0x0B,0xE0,0x8A,0xD4,0xCE,
     75     0xE1,0x6A,0x55,0x1F,0x8B,0x17,0x00,0xE6,0x69,0xA3,0x27,0xE6,
     76     0x08,0x25,0x69,0x3C,0x12,0x9D,0x8D,0x05,0x2C,0xD6,0x2E,0xA2,
     77     0x31,0xDE,0xB4,0x52,0x50,0xD6,0x20,0x49,0xDE,0x71,0xA0,0xF9,
     78     0xAD,0x20,0x40,0x12,0xF1,0xDD,0x25,0xEB,0xD5,0xE6,0xB8,0x36,
     79     0xF4,0xD6,0x8F,0x7F,0xCA,0x43,0xDC,0xD7,0x10,0x5B,0xE6,0x3F,
     80     0x51,0x8A,0x85,0xB3,0xF3,0xFF,0xF6,0x03,0x2D,0xCB,0x23,0x4F,
     81     0x9C,0xAD,0x18,0xE7,0x93,0x05,0x8C,0xAC,0x52,0x9A,0xF7,0x4C,
     82     0xE9,0x99,0x7A,0xBE,0x6E,0x7E,0x4D,0x0A,0xE3,0xC6,0x1C,0xA9,
     83     0x93,0xFA,0x3A,0xA5,0x91,0x5D,0x1C,0xBD,0x66,0xEB,0xCC,0x60,
     84     0xDC,0x86,0x74,0xCA,0xCF,0xF8,0x92,0x1C,0x98,0x7D,0x57,0xFA,
     85     0x61,0x47,0x9E,0xAB,0x80,0xB7,0xE4,0x48,0x80,0x2A,0x92,0xC5,
     86     0x1B,0x02,0x03,0x01,0x00,0x01
     87 };
     88 
     89 static const net::SHA1HashValue kFingerprintICA3 = { {
     90     0x97,0x05,0xCE,0xF6,0x3F,0xA9,0x5E,0x0F,0xE7,0x61,
     91     0xFB,0x08,0x44,0x31,0xBE,0xDE,0x01,0xB8,0xFB,0xEB
     92 } };
     93 static const unsigned char kPublicKeyICA3[] = {
     94     0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xB7,0xE8,0xC3,
     95     0xE4,0x2C,0xDE,0x74,0x53,0xF2,0x49,0x95,0x6D,0xD1,0xDA,0x69,
     96     0x57,0x0D,0x86,0xE5,0xED,0xB4,0xB9,0xE6,0x73,0x9F,0x6C,0xAD,
     97     0x3B,0x64,0x85,0x03,0x0D,0x08,0x44,0xAF,0x18,0x69,0x82,0xAD,
     98     0xA9,0x74,0x64,0x37,0x47,0xE1,0xE7,0x26,0x19,0x33,0x3C,0xE2,
     99     0xD0,0xB5,0x84,0x3C,0xD7,0xAC,0x63,0xAE,0xC4,0x32,0x23,0xF6,
    100     0xDC,0x14,0x10,0x4B,0x95,0x7F,0xE8,0x98,0xD7,0x7A,0x9E,0x43,
    101     0x3D,0x68,0x8B,0x2A,0x70,0xF7,0x1E,0x43,0x70,0xBA,0xA5,0xA5,
    102     0x93,0xAD,0x8A,0xD4,0x9F,0xAC,0x83,0x16,0xF3,0x48,0x5F,0xC5,
    103     0xE0,0xA5,0x44,0xB8,0x4F,0xD9,0xD8,0x75,0x90,0x25,0x8B,0xE3,
    104     0x1C,0x6C,0xDA,0x88,0xFF,0x09,0x2B,0xCA,0x1E,0x48,0xDD,0x76,
    105     0x0F,0x68,0x56,0x7B,0x15,0x9D,0xCA,0x6B,0x1C,0xF7,0x48,0xC2,
    106     0x89,0xC6,0x93,0x0A,0x31,0xF2,0x78,0x27,0x45,0x3D,0xF1,0x0D,
    107     0x5B,0x6E,0x55,0x32,0xEF,0x49,0xA0,0xD6,0xAF,0xA6,0x30,0x91,
    108     0xF2,0x21,0x2F,0xDB,0xA4,0x29,0xB9,0x9B,0x22,0xBC,0xCD,0x0B,
    109     0xA6,0x8B,0xA6,0x22,0x79,0xFD,0xCF,0x95,0x93,0x96,0xB3,0x23,
    110     0xC9,0xC6,0x30,0x8E,0xC0,0xE9,0x1F,0xEC,0xFB,0xF5,0x88,0xDD,
    111     0x97,0x72,0x16,0x29,0x08,0xFA,0x42,0xE7,0x4F,0xCA,0xAE,0xD7,
    112     0x0F,0x23,0x48,0x9B,0x82,0xA7,0x37,0x4A,0xDD,0x60,0x04,0x75,
    113     0xDC,0xDE,0x09,0x98,0xD2,0x16,0x23,0x04,0x70,0x4D,0x99,0x9F,
    114     0x4A,0x82,0x28,0xE6,0xBE,0x8F,0x9D,0xBF,0xA1,0x4B,0xA2,0xBA,
    115     0xF5,0xB2,0x51,0x1E,0x4E,0xE7,0x80,0x9E,0x7A,0x38,0xA1,0xC7,
    116     0x09,0x02,0x03,0x01,0x00,0x01
    117 };
    118 
    119 static const net::SHA1HashValue kFingerprintICA4 = { {
    120     0x01,0xF5,0x28,0x56,0x33,0x80,0x9B,0x31,0xE7,0xD9,
    121     0xF7,0x4E,0xAA,0xDD,0x97,0x37,0xA0,0x28,0xE7,0x24
    122 } };
    123 static const unsigned char kPublicKeyICA4[] = {
    124     0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xB0,0x0E,0x5E,
    125     0x07,0x3A,0xDF,0xA4,0x5F,0x68,0xF7,0x21,0xC7,0x64,0xDB,0xB6,
    126     0x76,0xEF,0xEE,0x8B,0x93,0xF8,0xF6,0x1B,0x88,0xE1,0x93,0xB7,
    127     0x17,0xF0,0x15,0x1E,0x7E,0x52,0x55,0x77,0x3C,0x02,0x8D,0x7B,
    128     0x4A,0x6C,0xD3,0xBD,0xD6,0xC1,0x9C,0x72,0xC8,0xB3,0x15,0xCF,
    129     0x11,0xC1,0xF5,0x46,0xC4,0xD5,0x20,0x47,0xFB,0x30,0xF4,0xE4,
    130     0x61,0x0C,0x68,0xF0,0x5E,0xAB,0x37,0x8E,0x9B,0xE1,0xBC,0x81,
    131     0xC3,0x70,0x8A,0x78,0xD6,0x83,0x34,0x32,0x9C,0x19,0x62,0xEB,
    132     0xE4,0x9C,0xED,0xE3,0x64,0x6C,0x41,0x1D,0x9C,0xD2,0x8B,0x48,
    133     0x4C,0x23,0x90,0x95,0xB3,0xE7,0x52,0xEA,0x05,0x57,0xCC,0x60,
    134     0xB3,0xBA,0x14,0xE4,0xBA,0x00,0x39,0xE4,0x46,0x55,0x74,0xCE,
    135     0x5A,0x8E,0x7A,0x67,0x23,0xDA,0x68,0x0A,0xFA,0xC4,0x84,0x1E,
    136     0xB4,0xC5,0xA1,0xA2,0x6A,0x73,0x1F,0x6E,0xC8,0x2E,0x2F,0x9A,
    137     0x9E,0xA8,0xB1,0x0E,0xFD,0x87,0xA6,0x8F,0x4D,0x3D,0x4B,0x05,
    138     0xD5,0x35,0x5A,0x74,0x4D,0xBC,0x8E,0x82,0x44,0x96,0xF4,0xB5,
    139     0x95,0x60,0x4E,0xA5,0xDF,0x27,0x3D,0x41,0x5C,0x07,0xA3,0xB4,
    140     0x35,0x5A,0xB3,0x9E,0xF2,0x05,0x24,0xCA,0xCD,0x31,0x5A,0x0D,
    141     0x26,0x4C,0xD4,0xD3,0xFD,0x50,0xE1,0x34,0xE9,0x4C,0x81,0x58,
    142     0x30,0xB2,0xC7,0x7A,0xDD,0x81,0x89,0xA6,0xD4,0x3A,0x38,0x84,
    143     0x03,0xB7,0x34,0x9E,0x77,0x3F,0xFF,0x78,0x07,0x5B,0x99,0xC1,
    144     0xB2,0x1F,0x35,0x56,0x6E,0x3A,0x3C,0x0C,0x25,0xE1,0x57,0xF6,
    145     0x8A,0x7E,0x49,0xC0,0xCC,0x83,0x11,0x35,0xE7,0x91,0x6D,0x2E,
    146     0x65,0x02,0x03,0x01,0x00,0x01
    147 };
    148 
    149 static const net::SHA1HashValue kFingerprintICA5 = { {
    150     0x59,0xD6,0xA3,0xAB,0xF3,0x2E,0x1D,0x33,0x6C,0xA1,
    151     0x08,0xA4,0x8A,0xA4,0x32,0x90,0x5C,0x63,0x2B,0x1E
    152 } };
    153 static const unsigned char kPublicKeyICA5[] = {
    154     0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xC2,0xF6,0xD5,
    155     0x91,0xDC,0x37,0xB4,0x9A,0x73,0x4A,0xE7,0x74,0x6D,0x03,0xAE,
    156     0x27,0x24,0x41,0x99,0x96,0x1B,0x05,0x0E,0xC7,0xCF,0x09,0xCD,
    157     0x65,0x56,0x02,0xFC,0x98,0x59,0xB4,0xBB,0x95,0x71,0xD7,0x88,
    158     0x66,0xC8,0x08,0xCB,0xBF,0x5B,0x85,0x65,0x7E,0xDE,0xC4,0xB5,
    159     0xE3,0x71,0x24,0xA2,0xFD,0x92,0x2C,0x77,0xC5,0x08,0xE0,0xF0,
    160     0xB1,0x8A,0x8A,0x54,0xCA,0xA6,0xAF,0x87,0xB8,0xCB,0x7D,0x83,
    161     0x28,0x59,0x9C,0x01,0xF5,0x7B,0x10,0xD0,0xF3,0x52,0x09,0x3F,
    162     0xF5,0x7D,0xDA,0x21,0x63,0x8F,0xAC,0x8B,0x60,0x67,0x22,0xEF,
    163     0x6B,0x66,0x91,0xFC,0x97,0x30,0x8D,0xCC,0xFE,0xDE,0x5C,0xF9,
    164     0x19,0xBB,0x1C,0x25,0x29,0x2C,0x99,0x48,0x41,0xC2,0xFC,0x5B,
    165     0x66,0xD6,0x79,0x84,0x16,0x8D,0x0D,0x4F,0x75,0x01,0x40,0xC5,
    166     0x50,0x69,0xFA,0xA4,0x88,0xF1,0xD2,0x3B,0xD1,0x23,0xDF,0xC5,
    167     0xBA,0xE3,0xE8,0xBA,0xCC,0x1E,0x93,0x17,0xF7,0x97,0xE2,0x71,
    168     0x42,0x75,0x5B,0x99,0x55,0x98,0x22,0x23,0x98,0xDC,0x10,0x89,
    169     0xF4,0xE8,0x26,0xBB,0x98,0x66,0xFD,0xBB,0x9A,0x21,0x62,0xA2,
    170     0xDF,0x90,0xDB,0x48,0x6F,0xDB,0x2A,0xEF,0xDE,0x53,0x59,0x31,
    171     0x5D,0x38,0xCD,0x80,0xA8,0x0C,0x6E,0x4E,0x37,0x65,0xEB,0x36,
    172     0x1C,0x13,0xBA,0x53,0xD3,0x8F,0xCC,0x43,0x86,0x02,0x70,0xD2,
    173     0x91,0xF6,0x96,0x25,0x6C,0xA4,0xE8,0x1F,0xD8,0xB3,0x74,0x20,
    174     0xEB,0x60,0x9D,0x3D,0xD3,0x3D,0x2E,0x36,0x0F,0xF1,0x94,0x10,
    175     0xF9,0x7A,0x03,0x52,0x7E,0xA4,0xEF,0xE3,0x40,0x9E,0x74,0x0E,
    176     0xDF,0x02,0x03,0x01,0x00,0x01
    177 };
    178 
    179 static const net::SHA1HashValue kFingerprintICA6 = { {
    180     0xE0,0xE1,0x57,0x47,0xFD,0x50,0xA4,0x99,0x80,0x6E,
    181     0x52,0x40,0x9F,0x9C,0xE3,0x9F,0x6D,0x81,0x59,0xFE
    182 } };
    183 static const unsigned char kPublicKeyICA6[] = {
    184     0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xB5,0xC8,0x14,
    185     0x5B,0x94,0x2E,0x8E,0x40,0xBC,0x8A,0xAB,0x1F,0x48,0xEE,0xA5,
    186     0x5C,0x5D,0xA9,0x44,0x23,0x33,0xE5,0x09,0xDD,0x84,0xDD,0xA6,
    187     0x08,0x95,0xB0,0xEA,0x64,0xEB,0xC1,0xCA,0x02,0x60,0xFF,0x83,
    188     0xF9,0x17,0x71,0x2C,0xC7,0xAB,0x06,0x0F,0xE4,0xAD,0x39,0x24,
    189     0xFB,0x1F,0xED,0xFA,0xB2,0x4D,0x14,0x5A,0x6E,0x5B,0x06,0x10,
    190     0x13,0xE7,0x77,0x22,0xAA,0xE5,0xD1,0x2C,0x05,0xC4,0x06,0x05,
    191     0xB1,0xCD,0xBE,0xCB,0x4B,0xAF,0x11,0x3E,0xA0,0x77,0xBA,0x6D,
    192     0xE4,0xA7,0xBA,0xC9,0x9D,0x3F,0x47,0xE0,0xD6,0x20,0x75,0x1C,
    193     0xE9,0x89,0xD3,0x88,0x56,0x4F,0x29,0xF6,0x7D,0x49,0x96,0xBE,
    194     0xE8,0x41,0xAB,0x35,0x08,0xAD,0x07,0x22,0x90,0xA3,0x4A,0x98,
    195     0xBA,0xC3,0xE2,0x29,0xDA,0x2E,0xBD,0x34,0xF5,0x41,0xBC,0x27,
    196     0x7D,0xE0,0x02,0xBF,0xB7,0xAE,0x8B,0x1E,0xEE,0xE9,0xC1,0x59,
    197     0x92,0xEA,0xE3,0x76,0x0E,0xE7,0x77,0xEF,0x10,0x7E,0x4F,0xD8,
    198     0xAD,0xC4,0x5D,0xBB,0xB7,0x9F,0x23,0x0B,0x34,0x89,0xF7,0x97,
    199     0x9A,0x40,0x79,0x00,0xDD,0x10,0x9E,0x01,0xA7,0xF0,0xD8,0xC4,
    200     0x37,0xF1,0x6A,0xD7,0xC2,0xE9,0x75,0x94,0x55,0xA9,0x81,0xA8,
    201     0xF8,0xC6,0xF9,0xD2,0xCF,0x26,0xA0,0x74,0x58,0x2E,0xD0,0xCB,
    202     0x16,0x58,0x1B,0x1E,0x2B,0x94,0x80,0x26,0x82,0x3F,0x01,0x36,
    203     0x01,0x97,0x1E,0xA6,0x94,0x14,0xC0,0xB2,0x55,0x95,0x2E,0x30,
    204     0x9C,0x7B,0xC6,0x79,0xF8,0x12,0xB3,0xB4,0x11,0x93,0x73,0x9C,
    205     0xD4,0x3F,0x29,0x6E,0x6A,0xAA,0xA8,0xE9,0xA2,0xF3,0x20,0x4E,
    206     0xE9,0x02,0x03,0x01,0x00,0x01
    207 };
    208 
    209 static const net::SHA1HashValue kFingerprintICA7 = { {
    210     0xF9,0xDC,0x51,0x97,0x48,0xB6,0x61,0xBD,0x60,0x78,
    211     0x91,0x6B,0x20,0xC1,0x9A,0xA3,0xCA,0xEC,0xF8,0xFC
    212 } };
    213 static const unsigned char kPublicKeyICA7[] = {
    214     0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xCC,0xE2,0xB6,
    215     0x2F,0x11,0xAB,0xFF,0xD0,0x5D,0x63,0x97,0x59,0xFA,0x5F,0x26,
    216     0xD7,0x91,0xE9,0x90,0x86,0x31,0x91,0x8E,0x2D,0x29,0x5F,0x7A,
    217     0x2F,0x12,0x77,0x21,0xD9,0x0E,0x99,0x0F,0x11,0x08,0x69,0x3C,
    218     0x9C,0x58,0xD4,0xCE,0x44,0xB3,0x8E,0x46,0x6C,0xC1,0x8E,0x60,
    219     0x63,0x3E,0x99,0x24,0x72,0x69,0x07,0xC2,0x30,0x0F,0xD5,0x74,
    220     0x06,0xC6,0x09,0x94,0x13,0xD7,0x34,0x34,0x75,0x73,0x4F,0x4A,
    221     0x01,0xFE,0x1E,0x3C,0x91,0x86,0x9C,0x63,0xF8,0xEF,0x15,0x79,
    222     0xE5,0x5A,0xC1,0xF2,0x05,0xDC,0xE0,0x76,0xDE,0x69,0x46,0xDF,
    223     0x12,0x3D,0xF4,0xD9,0x05,0xE2,0x9E,0xAD,0x07,0xCC,0x69,0x5F,
    224     0x1D,0x42,0x5E,0x6C,0x4A,0xB4,0x89,0x7C,0xDB,0xBC,0x69,0x4E,
    225     0x23,0x70,0x9A,0x67,0xC5,0xFA,0x29,0x88,0x7C,0x30,0xFA,0x61,
    226     0x98,0x3C,0x43,0x4A,0x1E,0xCA,0xAE,0xA8,0x7B,0x65,0x68,0xA3,
    227     0xFB,0x38,0xB4,0x4F,0xCA,0x49,0x60,0x85,0xA0,0xC1,0x55,0xA1,
    228     0xCE,0x67,0x78,0x9F,0x53,0x81,0xD7,0x92,0xC9,0x6D,0x44,0xF1,
    229     0x97,0x95,0xA5,0x7C,0x83,0xEC,0xD3,0xEB,0x7D,0xD7,0x0A,0x06,
    230     0xFE,0xBA,0xFC,0x56,0x5F,0xF0,0x70,0xE4,0x82,0xBE,0x69,0x6D,
    231     0x95,0x00,0xDF,0xB5,0xE5,0xBF,0x9E,0xF1,0x12,0x47,0x14,0x9C,
    232     0x7D,0xE5,0xA0,0xB8,0x70,0x29,0x6B,0xC8,0x8A,0xF2,0xBA,0x35,
    233     0xD8,0xC4,0xD3,0xB4,0xB5,0xEB,0xDF,0x2D,0x27,0x46,0xA5,0xFF,
    234     0x35,0xB5,0x5F,0x85,0x72,0xEB,0xCF,0xAD,0x09,0x18,0x05,0x95,
    235     0x56,0x88,0x95,0x22,0xD7,0x60,0x47,0xC9,0x1F,0xFA,0x2D,0x51,
    236     0x3F,0x02,0x03,0x01,0x00,0x01
    237 };
    238 
    239 static const net::SHA1HashValue kFingerprintICA8 = { {
    240     0x51,0xD4,0x70,0x0A,0x03,0x6E,0xA5,0x6A,0xF3,0x99,
    241     0xCF,0x3D,0x0F,0x17,0x8D,0x10,0x1A,0x4B,0xD2,0x44
    242 } };
    243 static const unsigned char kPublicKeyICA8[] = {
    244     0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xBF,0x3A,0x31,
    245     0xFC,0xF8,0xE6,0xEE,0xC0,0x48,0x00,0xB4,0x05,0x65,0x36,0x23,
    246     0x6D,0x34,0xD6,0x00,0xD5,0x43,0x89,0x6A,0x90,0xCB,0x7D,0x1B,
    247     0x39,0xFE,0x2E,0x83,0x84,0x29,0xBE,0x51,0xEF,0x98,0x66,0x48,
    248     0x59,0x8E,0x7E,0x10,0x14,0x1D,0x9F,0xAA,0x52,0xFD,0x6B,0xBF,
    249     0xC6,0x13,0xF2,0xE9,0x79,0x62,0xE2,0xA0,0x3B,0xC6,0x44,0x70,
    250     0x94,0x98,0xAF,0x92,0x9E,0x66,0x3F,0xA4,0x6C,0xC1,0x2F,0x6D,
    251     0xA2,0x08,0x8A,0x47,0x1B,0xFA,0x6D,0x09,0xCF,0x94,0xDB,0x20,
    252     0xCE,0xA2,0xBF,0xEA,0x06,0xF4,0xD3,0x4D,0xF7,0x62,0xAE,0x1A,
    253     0x64,0xEC,0x1F,0xA5,0x40,0x2D,0x15,0xE7,0xF7,0x26,0xFB,0x08,
    254     0xD9,0x5B,0xFC,0x86,0x7E,0xC7,0x94,0x18,0x08,0x2A,0xF5,0x83,
    255     0x44,0x06,0x15,0x12,0x5A,0x1F,0xBB,0x47,0xE3,0x2C,0x61,0x64,
    256     0xDF,0xFE,0x74,0x0E,0x78,0xA4,0x65,0xB8,0x70,0xC1,0xDB,0x3D,
    257     0xCA,0x26,0x33,0xBD,0x4A,0x14,0xDA,0x0B,0xEC,0xEC,0xB3,0x34,
    258     0x23,0x59,0xD2,0x11,0xF9,0xB0,0x53,0x1C,0x75,0x76,0xF5,0x65,
    259     0x00,0x6C,0xF0,0x7F,0xFA,0x1A,0x59,0xFE,0xF8,0x9D,0x1A,0x4E,
    260     0x42,0x35,0xEE,0x2F,0xE3,0xA1,0xE2,0xDF,0xDB,0x7A,0x6B,0x5E,
    261     0x6B,0x21,0xFF,0xA5,0xE1,0x87,0xDF,0xB8,0xE7,0x52,0xAD,0x99,
    262     0xCD,0x47,0x88,0xE0,0xBA,0xF0,0x3D,0x9D,0x87,0x93,0xAD,0xA7,
    263     0x45,0x67,0xF0,0x1E,0x46,0xD7,0x83,0x9A,0xE5,0x49,0x76,0x21,
    264     0x82,0xCB,0x82,0x67,0xA5,0xFF,0x63,0xD8,0x97,0x51,0xB4,0x44,
    265     0xA0,0x76,0xBA,0x40,0xD8,0xAB,0xA6,0xEB,0x70,0xD5,0xA4,0x38,
    266     0xB9,0x02,0x03,0x01,0x00,0x01
    267 };
    268 
    269 static const net::SHA1HashValue kFingerprintICA9 = { {
    270     0x9B,0x2A,0x45,0xBD,0x4F,0x80,0x53,0x94,0xD3,0xA7,
    271     0x9D,0xC7,0xFA,0xCD,0x77,0x0B,0x36,0xB2,0x3C,0x18
    272 } };
    273 static const unsigned char kPublicKeyICA9[] = {
    274     0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xE5,0x44,0x79,
    275     0xD4,0x75,0x3A,0xBD,0x25,0x6F,0x89,0xF7,0x94,0xE9,0x23,0xAE,
    276     0x19,0x38,0x09,0xA7,0x75,0x9C,0x5A,0x08,0x4A,0xC2,0xC6,0xA4,
    277     0x95,0x13,0x96,0x95,0x4E,0xFA,0xF1,0xC3,0xD2,0x7A,0xBC,0x4A,
    278     0xEE,0x65,0x2D,0xE2,0xB1,0x57,0x49,0x02,0x84,0x7C,0x35,0x31,
    279     0x8A,0xBB,0xCB,0x75,0x9C,0x14,0x84,0x52,0x85,0x40,0xD2,0x1D,
    280     0x03,0xAE,0x2B,0x38,0xA2,0x7F,0xEE,0xE8,0x3C,0x51,0x5B,0x82,
    281     0x11,0x9E,0xE2,0xC9,0x0B,0x7B,0x66,0xF2,0xE5,0x35,0x64,0x4B,
    282     0xF1,0x98,0xD9,0x60,0x0A,0xA2,0x8B,0xB2,0xD3,0x96,0x35,0xBE,
    283     0x2D,0xB4,0x7E,0xAC,0x75,0x73,0x5F,0xC0,0x78,0xC1,0x91,0x3E,
    284     0xB7,0xB2,0x53,0x4F,0x78,0x7D,0x58,0x93,0x12,0x3B,0xA9,0xB3,
    285     0x8F,0xA7,0xF6,0x7F,0x4C,0x2F,0x7B,0xFA,0x41,0xCA,0xF5,0x5A,
    286     0xF4,0x8A,0x5B,0xFE,0x82,0x18,0x90,0xE5,0x15,0x01,0xD3,0xD8,
    287     0x83,0x6B,0x02,0xA3,0xAE,0x54,0x5C,0xD9,0x0B,0x65,0x00,0xD6,
    288     0x06,0xF6,0x4E,0x52,0x2C,0x9C,0x06,0x1B,0x11,0x53,0xA5,0x7E,
    289     0xBE,0xAC,0x5E,0x01,0xF1,0x50,0xF2,0xC0,0x26,0xC6,0xF9,0xDD,
    290     0x89,0x8C,0x1D,0xD4,0x7A,0x59,0xC2,0xD7,0xF8,0x7A,0x03,0x6A,
    291     0xBD,0xC5,0x75,0x04,0xED,0x29,0x90,0xD8,0x24,0x75,0x12,0x38,
    292     0x24,0xF2,0x56,0xB4,0x87,0xB2,0x55,0x0F,0x26,0x1D,0xD0,0x6B,
    293     0x32,0xDF,0x05,0xFA,0x73,0x94,0xB0,0x6B,0x41,0xE7,0x2D,0xF0,
    294     0x24,0x48,0xA8,0x5B,0x03,0x34,0xE7,0x48,0x92,0x4E,0x99,0x3A,
    295     0x6B,0x96,0x8E,0x8E,0x48,0x52,0xA5,0xE8,0x13,0x54,0xCF,0x8D,
    296     0xA1,0x02,0x03,0x01,0x00,0x01
    297 };
    298 
    299 static const net::SHA1HashValue kFingerprintICA10 = { {
    300     0xDD,0x37,0x71,0xB1,0x84,0x07,0xA5,0x1A,0x8B,0x9C,
    301     0x75,0xA3,0x77,0x3B,0xE4,0x67,0x04,0xB8,0x66,0xE5
    302 } };
    303 static const unsigned char kPublicKeyICA10[] = {
    304     0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xAF,0xA1,0x27,
    305     0x5B,0x18,0x01,0xF9,0x16,0x7C,0xB9,0x1D,0xBB,0x34,0xC4,0x45,
    306     0xCF,0x7A,0x7B,0x7A,0xB7,0xC9,0x52,0xC6,0xC1,0xBE,0x14,0x57,
    307     0xF5,0xDC,0xF7,0xA3,0xB9,0x1F,0x63,0x5B,0xDE,0x95,0x36,0x23,
    308     0x3A,0xD4,0xDF,0x33,0xA5,0x75,0xF6,0x2B,0x70,0x6B,0xE6,0x46,
    309     0xA9,0x94,0x84,0x22,0xD0,0xC7,0xF4,0x2C,0x8D,0x20,0xBC,0x2F,
    310     0x8E,0x08,0x44,0xA4,0x99,0x30,0xE2,0x2B,0x37,0x1E,0x1A,0xB7,
    311     0x0D,0x98,0x20,0x40,0x18,0xEC,0x7E,0x7C,0x65,0xD7,0xF7,0x1E,
    312     0x7A,0x50,0x1C,0x27,0xFE,0x82,0x5F,0xFA,0xDF,0xAC,0xA6,0x4E,
    313     0xB4,0x91,0x2F,0x73,0xFB,0x20,0xFC,0x70,0x3F,0x5E,0x58,0x7B,
    314     0xAC,0xC6,0x1C,0xAD,0xEF,0x0A,0xB1,0xB3,0x12,0x2E,0xB8,0xC3,
    315     0x60,0xCB,0xF7,0x71,0x5F,0x18,0xDD,0x85,0x64,0x06,0xA7,0x17,
    316     0x60,0x81,0x72,0x6D,0xE2,0x24,0x57,0xCA,0x3D,0x1D,0x87,0x75,
    317     0x05,0x95,0xDE,0x38,0x8A,0xE0,0xC2,0xF7,0xCB,0x2F,0xA6,0xB9,
    318     0x24,0x50,0x14,0x17,0x12,0x77,0xFB,0x41,0xA8,0xA1,0x79,0xBC,
    319     0xC0,0x87,0x06,0x34,0xF2,0xAF,0x87,0x12,0xB6,0x66,0x24,0xDD,
    320     0x3E,0xBA,0x4E,0x34,0x02,0xF2,0x1B,0xAB,0x1D,0x79,0x72,0x41,
    321     0x16,0x0E,0x1F,0x9B,0x35,0x40,0xD0,0xC6,0x07,0xA7,0x91,0x53,
    322     0x55,0x19,0x0C,0xB1,0x1B,0x42,0x20,0x41,0xC5,0x2A,0xA8,0x26,
    323     0x8D,0x44,0x50,0x1B,0x0B,0x21,0xB2,0x16,0xA2,0x1B,0xF3,0xBD,
    324     0xC2,0x1D,0xAF,0x4F,0x41,0x43,0xAD,0x3A,0x76,0x45,0x3C,0x2B,
    325     0xD3,0x71,0x31,0x43,0x37,0xB6,0x68,0xA6,0x5D,0x8C,0x50,0x2B,
    326     0x8F,0x02,0x03,0x01,0x00,0x01
    327 };
    328 
    329 static const net::SHA1HashValue kFingerprintICA11 = { {
    330     0x34,0xAB,0x0F,0x01,0x2C,0x4F,0x99,0x70,0xA2,0x44,
    331     0x57,0x12,0xFB,0xE3,0x52,0xC4,0x9E,0x0A,0x20,0x6B
    332 } };
    333 static const unsigned char kPublicKeyICA11[] = {
    334     0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xA8,0xB2,0x65,
    335     0xFB,0x07,0xB0,0x21,0xBE,0x11,0xD1,0xDA,0x5D,0x89,0xB5,0xAA,
    336     0xC2,0xFD,0xD3,0x27,0x8D,0x3A,0x29,0x2F,0x3E,0xD4,0x87,0xC1,
    337     0x1B,0x51,0x39,0x48,0x73,0x4A,0xD5,0x52,0x5D,0x59,0x93,0x8B,
    338     0xF3,0x3D,0x57,0x6A,0x77,0x7D,0x43,0x3A,0xED,0xE5,0xC2,0x0E,
    339     0xFB,0xE0,0xFB,0x0C,0x65,0x65,0x74,0xA9,0x1F,0x3C,0x56,0x77,
    340     0xC8,0x5C,0x8F,0xA3,0xCB,0xB4,0x68,0xBC,0xE9,0x0F,0xE4,0x52,
    341     0x46,0x1B,0xB2,0x23,0x6F,0x66,0x9D,0xB7,0xCF,0xD9,0x48,0xE2,
    342     0x7D,0x17,0x26,0x45,0x4F,0xA5,0x14,0x10,0x08,0xCE,0xEC,0x18,
    343     0xE0,0x78,0x8E,0x25,0xB7,0xAE,0x23,0xBD,0xAE,0x56,0x33,0x1F,
    344     0x5B,0x02,0x41,0xE1,0x22,0x6D,0x85,0x8E,0xB0,0x87,0x73,0xF8,
    345     0xBF,0x3A,0x06,0xF7,0xDA,0x70,0xCB,0x14,0x1F,0x1E,0xFF,0x78,
    346     0x9D,0xC4,0x7A,0xFF,0x76,0x32,0x35,0x28,0x16,0xD4,0xBF,0xBC,
    347     0x2B,0x4E,0xD2,0x86,0x50,0x14,0x7A,0x8D,0x3F,0x8F,0x9E,0x53,
    348     0x0B,0xB5,0x83,0x6E,0x00,0x82,0xB0,0x08,0x6F,0x22,0xF4,0x26,
    349     0x33,0x19,0xCC,0x82,0xC7,0x4C,0xA0,0x1B,0xD2,0x62,0x33,0xF7,
    350     0x75,0x0B,0x57,0x4A,0xDF,0xDD,0x68,0xCB,0xFD,0x6F,0xB8,0xB3,
    351     0x8F,0x8E,0x45,0x8D,0xEE,0xF2,0xA2,0xFD,0x71,0xF5,0xE0,0x1B,
    352     0x3E,0x62,0x00,0x35,0x98,0x19,0x6B,0xA3,0x1B,0x1A,0xA3,0x5D,
    353     0xDE,0x49,0xB9,0x20,0x0D,0x44,0x8F,0x58,0x3C,0xDD,0x52,0x6D,
    354     0x03,0x7A,0x33,0xB3,0x06,0x7A,0xC7,0x49,0x23,0xC5,0x2A,0x24,
    355     0xB6,0x96,0x12,0x4C,0x16,0xB3,0x3A,0xFC,0x46,0x03,0xEC,0xBB,
    356     0xF9,0x02,0x03,0x01,0x00,0x01
    357 };
    358 
    359 static const net::SHA1HashValue kFingerprintICA12 = { {
    360     0x7C,0x3E,0x64,0x37,0x30,0xA4,0x6D,0xE5,0x16,0x7F,
    361     0xAC,0xEA,0xEA,0x2A,0x16,0x3E,0xE7,0x15,0x45,0x3A
    362 } };
    363 static const unsigned char kPublicKeyICA12[] = {
    364     0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xD9,0xE3,0x76,
    365     0x97,0x6A,0xEF,0x2D,0x16,0xD5,0xF9,0xDC,0x9D,0x0E,0x65,0x12,
    366     0x65,0x72,0xC0,0xE9,0x11,0x12,0x37,0x09,0x5D,0x54,0xF4,0x8F,
    367     0x3C,0xDB,0xF2,0xE9,0x42,0x9F,0x4E,0xF2,0xD0,0x4E,0xC8,0x10,
    368     0x31,0xE8,0x1B,0xFE,0x5B,0xFB,0xC8,0xD3,0xFB,0x77,0x25,0xC4,
    369     0x69,0xFA,0x53,0x03,0x16,0x12,0x7F,0x23,0x9F,0x4C,0xFB,0x35,
    370     0x60,0xAE,0xFB,0xA5,0x94,0xD3,0x5A,0x97,0x38,0x91,0x6E,0x87,
    371     0xE4,0xB5,0xA1,0x6E,0x23,0x1C,0x7A,0x41,0x55,0x27,0xA3,0x9E,
    372     0x6E,0xF3,0xD0,0xA7,0x19,0x52,0x0C,0x7C,0xBC,0xEC,0xB6,0xB8,
    373     0x54,0x40,0x77,0x0E,0x67,0x14,0x0D,0x19,0x1B,0x74,0xD4,0x2C,
    374     0x16,0x01,0xE5,0x57,0x6C,0x03,0x1E,0xE3,0x9E,0xA3,0x8E,0x72,
    375     0xA6,0x63,0x3A,0xED,0x25,0xEC,0x15,0x2F,0xE8,0xCE,0x52,0x1E,
    376     0xCB,0x50,0x39,0x36,0x7E,0xC2,0xEC,0x7C,0xCA,0x4A,0xB8,0x73,
    377     0x91,0xC8,0x88,0x98,0x31,0x0F,0x2E,0x68,0x45,0x53,0x22,0x66,
    378     0xF1,0xF5,0xBF,0xF9,0x11,0x88,0xB6,0x36,0x8E,0xAA,0x1A,0xB8,
    379     0xC9,0x18,0x90,0x44,0xBE,0xBD,0xDD,0xB1,0x81,0x98,0xBE,0xEB,
    380     0x1F,0xF6,0x28,0x85,0xB3,0xA4,0xA1,0xAE,0x14,0xD2,0x91,0x9D,
    381     0xD3,0xB1,0x0B,0xEC,0x72,0x3D,0x43,0xEB,0xD3,0x79,0x2A,0x7D,
    382     0xAD,0x79,0xA5,0xB5,0xA0,0xDD,0x88,0x89,0x6E,0xB4,0xC8,0x11,
    383     0xB6,0x11,0xED,0x18,0x50,0x43,0x2E,0xD7,0xCE,0x18,0x58,0xEB,
    384     0xCE,0x2E,0xE9,0x9E,0x20,0x86,0xFE,0x97,0xCD,0xB2,0x9C,0xC1,
    385     0xAF,0x24,0x02,0x38,0x60,0x6B,0xCC,0x66,0xC3,0x04,0x72,0xD3,
    386     0xF1,0x02,0x03,0x01,0x00,0x01
    387 };
    388 
    389 static const net::SHA1HashValue kFingerprintICA13 = { {
    390     0x26,0x43,0xE5,0x33,0x9E,0x07,0x14,0x83,0x9A,0xB1,
    391     0xCF,0x38,0x1C,0x77,0x74,0xF0,0xE5,0xBF,0x88,0x6F
    392 } };
    393 static const unsigned char kPublicKeyICA13[] = {
    394     0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xBB,0xE5,0x0F,
    395     0xD2,0x1C,0x6B,0xBA,0x23,0xA9,0x2F,0x87,0xEC,0xDB,0x92,0x3F,
    396     0xAF,0xC8,0xD4,0xB2,0x59,0x24,0x2E,0xC8,0xCD,0x00,0xEF,0x09,
    397     0xFB,0xF6,0x19,0xE7,0x6C,0x8A,0x1A,0x3B,0xB6,0xCC,0xEF,0x3A,
    398     0x40,0x6C,0x93,0xF8,0xE3,0x1B,0xB7,0xE5,0x1C,0x92,0x65,0xE8,
    399     0x5E,0x64,0x83,0x90,0xF1,0x24,0x4A,0xD1,0xC5,0x3D,0x8C,0x3B,
    400     0x71,0x66,0x31,0x58,0xD8,0x55,0xC2,0xCC,0xD3,0xEA,0x0E,0x66,
    401     0x88,0x59,0x14,0x77,0xED,0x12,0xC5,0x96,0x54,0x7F,0x97,0x28,
    402     0x3B,0x5E,0xCA,0xF7,0x1B,0xD3,0x4B,0x10,0xC3,0x45,0x3A,0x4D,
    403     0xCA,0x36,0x5A,0xFF,0x4F,0x86,0xDD,0x9E,0x69,0xDF,0xD5,0x4A,
    404     0xD0,0xB8,0x9F,0x8D,0x31,0x70,0x76,0x63,0x33,0xB0,0xB8,0xF4,
    405     0xB0,0x45,0x28,0xB3,0x5D,0xF2,0x2F,0xC5,0xA4,0xD9,0x30,0x6F,
    406     0x9F,0x69,0x23,0x42,0x6D,0x7D,0x73,0x29,0x56,0x61,0xCC,0x56,
    407     0xC9,0xAE,0xED,0x13,0x33,0xB4,0x0E,0xD0,0x25,0xE3,0x06,0xC1,
    408     0x9A,0x26,0xDB,0x8E,0x89,0xA6,0xA0,0xF9,0x30,0xE6,0x92,0xD0,
    409     0xEC,0x77,0xB9,0xA8,0x0C,0x8E,0x83,0x5D,0x6B,0xB9,0x49,0xF2,
    410     0xFB,0x1C,0xE4,0x79,0xC8,0xB3,0x90,0x88,0xE9,0x92,0x24,0x8A,
    411     0x18,0x7E,0xE3,0x5C,0xEF,0xC0,0x4B,0xDD,0xFD,0x09,0x14,0x4C,
    412     0x9C,0x7A,0xB3,0x56,0x84,0x96,0xDB,0x08,0xA8,0xE1,0xCD,0x40,
    413     0x94,0xF5,0x12,0xF4,0x63,0x38,0x0C,0x51,0xE4,0x03,0x63,0xC4,
    414     0x76,0x54,0xB7,0x59,0x25,0xCE,0x62,0xDE,0x73,0x3F,0xAB,0x15,
    415     0x56,0xC5,0xBC,0x99,0x8C,0x3A,0x46,0x3F,0x13,0x0E,0xF4,0x53,
    416     0x1D,0x02,0x03,0x01,0x00,0x01
    417 };
    418 
    419 static const net::SHA1HashValue kFingerprintICA14 = { {
    420     0xCF,0x58,0x82,0xEE,0x81,0x71,0x71,0x8E,0x2C,0xBD,
    421     0xDB,0x87,0xE0,0x18,0xF5,0xED,0xDA,0x85,0x4A,0x13
    422 } };
    423 static const unsigned char kPublicKeyICA14[] = {
    424     0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xAD,0x16,0x57,
    425     0x87,0xD7,0x0D,0xA3,0xA2,0x7E,0x8B,0xAE,0x45,0x7A,0x1F,0xCA,
    426     0xFE,0xB9,0x15,0xB7,0x5B,0x9F,0x7D,0x16,0xA5,0xA5,0x63,0xB1,
    427     0xF5,0x6E,0x17,0x7F,0x35,0xD8,0x4A,0x8C,0x97,0xBF,0x77,0x84,
    428     0x5E,0xC6,0x21,0x81,0xAF,0x72,0xEF,0xCF,0xDE,0x46,0xB7,0xE7,
    429     0x49,0x61,0x8E,0xFC,0x84,0x12,0xBC,0x30,0xEA,0xF8,0x5B,0x78,
    430     0x6C,0x3E,0x12,0x23,0x33,0x29,0x80,0x34,0x6A,0x1E,0x8D,0x3C,
    431     0x15,0xE9,0x47,0x9E,0x33,0x27,0x90,0x73,0x52,0xD0,0xBF,0xCE,
    432     0x0D,0x68,0xE5,0x5A,0x90,0x71,0xB2,0xF2,0xBD,0x7E,0x69,0xE0,
    433     0x92,0xDC,0x44,0x9F,0x4B,0xA3,0xC2,0x58,0x16,0x1A,0x35,0x18,
    434     0x88,0x3A,0x82,0x15,0xFC,0x41,0x8C,0x72,0x11,0x2E,0xC4,0xED,
    435     0xD3,0x7E,0x68,0xF2,0x00,0x01,0xE2,0x71,0xC3,0x91,0x91,0xFD,
    436     0xF3,0xBE,0x11,0xE7,0x62,0xB4,0xAF,0xC8,0xF0,0x12,0xBC,0xB2,
    437     0x0E,0x58,0x5C,0xFF,0x08,0xCB,0xCB,0x91,0xD2,0xD0,0x11,0x87,
    438     0x72,0x04,0x99,0x63,0x12,0xA6,0x6F,0x7D,0x40,0x76,0xB7,0xE8,
    439     0x89,0xCE,0xCD,0x5A,0x73,0x18,0x8A,0x73,0xAF,0xFD,0x21,0x68,
    440     0xE5,0x26,0x74,0x12,0x2C,0xC3,0xE6,0x7D,0x1D,0x9A,0xC8,0x12,
    441     0xCD,0x38,0xCB,0x47,0xA6,0x54,0x8F,0xAD,0x9F,0xFA,0xB1,0xDF,
    442     0xB0,0xBF,0xE7,0x12,0x32,0x76,0xA7,0xA5,0xD7,0x46,0xF8,0x62,
    443     0x15,0x54,0x78,0xBA,0x9E,0x4D,0xD8,0x99,0x62,0x9E,0xE8,0x45,
    444     0x93,0x8C,0x14,0x7E,0x9C,0xE9,0xF7,0x2A,0x7E,0x56,0xE3,0xBD,
    445     0xF1,0x65,0xC8,0x6B,0xB9,0xE5,0x16,0x1E,0x22,0x29,0xEC,0xCA,
    446     0xD9,0x02,0x03,0x01,0x00,0x01
    447 };
    448 
    449 static const net::SHA1HashValue kFingerprintICA15 = { {
    450     0xFD,0x28,0xC3,0x71,0x00,0x27,0x0F,0x36,0x28,0x32,
    451     0x7F,0xE6,0xD6,0x8A,0x6F,0x59,0x58,0x4B,0x3E,0x1E
    452 } };
    453 static const unsigned char kPublicKeyICA15[] = {
    454     0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xDD,0xFE,0x56,
    455     0x5F,0x53,0x05,0x59,0x8F,0x7C,0xF4,0x8B,0x90,0x38,0xED,0x51,
    456     0xE6,0x8A,0xAC,0x78,0x1F,0x7B,0x33,0x74,0x7F,0x33,0xAA,0x6A,
    457     0x13,0x6F,0x7C,0xDF,0x82,0x8F,0x7B,0xC4,0x11,0xAE,0x5C,0x2B,
    458     0x1A,0xDB,0x9A,0x95,0x13,0xE8,0x64,0x48,0x37,0x6C,0x6B,0x8C,
    459     0xDD,0x42,0xE1,0xCE,0xE4,0x0C,0xDF,0xA2,0x41,0x9E,0x78,0x8B,
    460     0x26,0xBF,0xA1,0x6E,0x59,0x8E,0x10,0xF8,0x31,0xAD,0x13,0xD2,
    461     0x1F,0x84,0xCC,0xE0,0x88,0x59,0x5D,0x0C,0xD0,0xAB,0x24,0xC8,
    462     0x1F,0xCB,0xE0,0x13,0x72,0xD3,0xF3,0x90,0xFB,0xB0,0x1D,0x36,
    463     0x4E,0xB6,0xDC,0x42,0xC2,0x87,0xD8,0x38,0x6D,0x18,0x23,0x3F,
    464     0xDF,0x95,0x8B,0xF1,0x40,0x89,0xEE,0x43,0xD5,0x09,0x1F,0xBB,
    465     0xDA,0x96,0x4C,0xB7,0x23,0x33,0xE9,0x48,0xEA,0x9E,0x1D,0x30,
    466     0xFD,0x72,0x90,0x81,0x74,0x1C,0xE7,0x8A,0xA9,0x8C,0xD9,0x4B,
    467     0x30,0x35,0x47,0x60,0xDC,0x28,0x34,0x92,0x39,0xD6,0xEA,0x3E,
    468     0x1F,0x70,0x1B,0xCA,0x28,0x64,0xA5,0x2E,0x90,0x3E,0x25,0x90,
    469     0xE7,0x70,0x10,0x55,0x1E,0xAE,0x9B,0x5C,0xB3,0x88,0xB7,0x00,
    470     0x76,0x7B,0xF7,0xB6,0x4A,0xD3,0x69,0x1E,0x00,0xDF,0xB1,0xE6,
    471     0x4D,0xD1,0x18,0x3A,0xAD,0x7E,0xB9,0x6C,0x6D,0x51,0x81,0x75,
    472     0xFE,0xC4,0xAA,0xE6,0x17,0x37,0xBA,0x2B,0x3B,0xD4,0x4E,0xFC,
    473     0xEC,0xE6,0x60,0x7B,0x20,0x7F,0xC3,0x74,0xD9,0xA3,0x67,0x80,
    474     0x8B,0x4A,0x34,0xDC,0x25,0x6E,0x9B,0xA5,0x67,0x97,0x54,0xAC,
    475     0x6C,0x8E,0x7A,0x64,0x20,0xDA,0xD6,0xAA,0x59,0x6B,0x27,0x28,
    476     0x99,0x02,0x03,0x01,0x00,0x01
    477 };
    478 
    479 static const net::SHA1HashValue kFingerprintICA16 = { {
    480     0xBC,0x59,0x07,0x13,0xA9,0xCE,0x8B,0xFE,0xE3,0x5B,
    481     0xB7,0xC3,0xC3,0xC2,0x48,0x44,0xE8,0x6A,0x77,0xC0
    482 } };
    483 static const unsigned char kPublicKeyICA16[] = {
    484     0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xD2,0xB0,0xC9,
    485     0xB3,0x88,0xCD,0x93,0x23,0x6A,0x46,0xD3,0x69,0x0A,0xD7,0xFF,
    486     0xE1,0x51,0x7E,0x29,0xA9,0x6B,0x71,0x68,0xC0,0xCF,0x69,0xA3,
    487     0xE8,0xAD,0xA9,0x58,0x22,0x18,0x45,0x9F,0x04,0x86,0x7F,0xBA,
    488     0x1B,0xC8,0x1C,0x3A,0x99,0x80,0xFF,0x73,0x8C,0x65,0xE7,0xDA,
    489     0x76,0x5F,0xCE,0xD6,0xB8,0x28,0xCA,0xC9,0x20,0x7A,0x4B,0xB9,
    490     0xC2,0xCE,0x89,0x46,0x40,0x68,0x60,0x7E,0x3B,0xE0,0x88,0x1C,
    491     0x1B,0xDC,0xEE,0xDC,0x06,0x42,0x5B,0x28,0x1A,0xCD,0xCB,0x3E,
    492     0x4E,0xF3,0x19,0x0D,0x83,0xE2,0x2A,0x9D,0x8C,0xA3,0x78,0xE8,
    493     0x1D,0x6B,0x79,0x7C,0x48,0xA9,0xE1,0x8B,0x56,0x8B,0x66,0x63,
    494     0xCE,0x54,0xA7,0xD2,0x1F,0xE6,0x81,0x5B,0x0C,0x63,0xB9,0xF0,
    495     0x94,0xBD,0xC1,0xB2,0x5A,0x7F,0xEC,0x9A,0x09,0x4F,0xB8,0x02,
    496     0x6D,0x7F,0x59,0x64,0xBE,0x01,0xF8,0x83,0xD4,0xF0,0x0E,0x96,
    497     0x78,0xDC,0xF4,0x9D,0x4C,0x91,0x4C,0x08,0xB3,0xFA,0x28,0x55,
    498     0xB7,0xF6,0x06,0x1E,0x34,0xC3,0x79,0x90,0xAB,0x2C,0x4E,0x2E,
    499     0xD9,0xE4,0x78,0x87,0xCF,0xF2,0xAA,0x83,0x2D,0x74,0x8F,0xE4,
    500     0xDA,0xEE,0xD0,0x24,0x06,0xDE,0x40,0xE7,0xC9,0xC0,0x02,0xF5,
    501     0x8D,0x7D,0xDE,0x28,0x03,0x8A,0xAE,0x21,0xBD,0xF1,0x29,0x36,
    502     0xEB,0xD7,0xC9,0x3B,0x34,0xE3,0x08,0x8C,0xCA,0x25,0xEE,0x3C,
    503     0xE4,0x07,0x49,0xB9,0xB8,0xDB,0x35,0x90,0x99,0x50,0x99,0xC2,
    504     0x7D,0x6A,0x3A,0x33,0x31,0xC7,0x61,0x13,0xB7,0x71,0x10,0x80,
    505     0xC1,0x8C,0xE0,0x69,0xA2,0xDD,0xA3,0xE5,0x52,0x8A,0xF5,0xEF,
    506     0x63,0x02,0x03,0x01,0x00,0x01
    507 };
    508 
    509 // Info for trusted ICA certs.
    510 struct ICACertInfo {
    511   const net::SHA1HashValue* fingerprint;
    512   SECItem public_key;
    513 };
    514 
    515 // List of allowed / trusted ICAs.
    516 static const ICACertInfo kAllowedICAs[] = {
    517   { &kFingerprintICA1,
    518     { siDERCertBuffer,
    519       const_cast<unsigned char*>(kPublicKeyICA1),
    520       sizeof(kPublicKeyICA1) } },
    521   { &kFingerprintICA2,
    522     { siDERCertBuffer,
    523       const_cast<unsigned char*>(kPublicKeyICA2),
    524       sizeof(kPublicKeyICA2) } },
    525   { &kFingerprintICA3,
    526     { siDERCertBuffer,
    527       const_cast<unsigned char*>(kPublicKeyICA3),
    528       sizeof(kPublicKeyICA3) } },
    529   { &kFingerprintICA4,
    530     { siDERCertBuffer,
    531       const_cast<unsigned char*>(kPublicKeyICA4),
    532       sizeof(kPublicKeyICA4) } },
    533   { &kFingerprintICA5,
    534     { siDERCertBuffer,
    535       const_cast<unsigned char*>(kPublicKeyICA5),
    536       sizeof(kPublicKeyICA5) } },
    537   { &kFingerprintICA6,
    538     { siDERCertBuffer,
    539       const_cast<unsigned char*>(kPublicKeyICA6),
    540       sizeof(kPublicKeyICA6) } },
    541   { &kFingerprintICA7,
    542     { siDERCertBuffer,
    543       const_cast<unsigned char*>(kPublicKeyICA7),
    544       sizeof(kPublicKeyICA7) } },
    545   { &kFingerprintICA8,
    546     { siDERCertBuffer,
    547       const_cast<unsigned char*>(kPublicKeyICA8),
    548       sizeof(kPublicKeyICA8) } },
    549   { &kFingerprintICA9,
    550     { siDERCertBuffer,
    551       const_cast<unsigned char*>(kPublicKeyICA9),
    552       sizeof(kPublicKeyICA9) } },
    553   { &kFingerprintICA10,
    554     { siDERCertBuffer,
    555       const_cast<unsigned char*>(kPublicKeyICA10),
    556       sizeof(kPublicKeyICA10) } },
    557   { &kFingerprintICA11,
    558     { siDERCertBuffer,
    559       const_cast<unsigned char*>(kPublicKeyICA11),
    560       sizeof(kPublicKeyICA11) } },
    561   { &kFingerprintICA12,
    562     { siDERCertBuffer,
    563       const_cast<unsigned char*>(kPublicKeyICA12),
    564       sizeof(kPublicKeyICA12) } },
    565   { &kFingerprintICA13,
    566     { siDERCertBuffer,
    567       const_cast<unsigned char*>(kPublicKeyICA13),
    568       sizeof(kPublicKeyICA13) } },
    569   { &kFingerprintICA14,
    570     { siDERCertBuffer,
    571       const_cast<unsigned char*>(kPublicKeyICA14),
    572       sizeof(kPublicKeyICA14) } },
    573   { &kFingerprintICA15,
    574     { siDERCertBuffer,
    575       const_cast<unsigned char*>(kPublicKeyICA15),
    576       sizeof(kPublicKeyICA15) } },
    577   { &kFingerprintICA16,
    578     { siDERCertBuffer,
    579       const_cast<unsigned char*>(kPublicKeyICA16),
    580       sizeof(kPublicKeyICA16) } },
    581 };
    582 
    583 typedef scoped_ptr<
    584     CERTCertificate,
    585     crypto::NSSDestroyer<CERTCertificate, CERT_DestroyCertificate> >
    586         ScopedCERTCertificate;
    587 
    588 // Returns the index of the ICA whose fingerprint matches |fingerprint|.
    589 // Returns -1, if no such ICA is found.
    590 static int GetICAWithFingerprint(const net::SHA1HashValue& fingerprint) {
    591   for (size_t i = 0; i < arraysize(kAllowedICAs); ++i) {
    592     if (kAllowedICAs[i].fingerprint->Equals(fingerprint))
    593       return static_cast<int>(i);
    594   }
    595   return -1;
    596 }
    597 
    598 // Parses out DeviceAuthMessage from CastMessage
    599 static AuthResult ParseAuthMessage(const CastMessage& challenge_reply,
    600                                    DeviceAuthMessage* auth_message) {
    601   const std::string kErrorPrefix("Failed to parse auth message: ");
    602   if (challenge_reply.payload_type() != CastMessage_PayloadType_BINARY) {
    603     return AuthResult::Create(
    604         kErrorPrefix + "Wrong payload type in challenge reply",
    605         AuthResult::ERROR_WRONG_PAYLOAD_TYPE);
    606   }
    607   if (!challenge_reply.has_payload_binary()) {
    608     return AuthResult::Create(
    609         kErrorPrefix +
    610             "Payload type is binary but payload_binary field not set",
    611         AuthResult::ERROR_NO_PAYLOAD);
    612   }
    613   if (!auth_message->ParseFromString(challenge_reply.payload_binary())) {
    614     return AuthResult::Create(
    615         kErrorPrefix + "Cannot parse binary payload into DeviceAuthMessage",
    616         AuthResult::ERROR_PAYLOAD_PARSING_FAILED);
    617   }
    618 
    619   VLOG(1) << "Auth message: " << AuthMessageToString(*auth_message);
    620 
    621   if (auth_message->has_error()) {
    622     std::string error_format_str = kErrorPrefix + "Auth message error: %d";
    623     return AuthResult::Create(
    624         base::StringPrintf(error_format_str.c_str(),
    625                            auth_message->error().error_type()),
    626         AuthResult::ERROR_MESSAGE_ERROR);
    627   }
    628   if (!auth_message->has_response()) {
    629     return AuthResult::Create(
    630         kErrorPrefix + "Auth message has no response field",
    631         AuthResult::ERROR_NO_RESPONSE);
    632   }
    633   return AuthResult();
    634 }
    635 
    636 // Authenticates the given credentials:
    637 // 1. |signature| verification of |data| using |certificate|.
    638 // 2. |certificate| is signed by a trusted CA.
    639 AuthResult VerifyCredentials(const AuthResponse& response,
    640                              const std::string& data) {
    641   const std::string kErrorPrefix("Failed to verify credentials: ");
    642   const std::string& certificate = response.client_auth_certificate();
    643   const std::string& signature = response.signature();
    644 
    645   const SECItem* trusted_ca_key_der;
    646 
    647   // If the list of intermediates is empty then use kPublicKeyICA1 as
    648   // the trusted CA (legacy case).
    649   // Otherwise, use the first intermediate in the list as long as it
    650   // is in the allowed list of intermediates.
    651   int num_intermediates = response.intermediate_certificate_size();
    652 
    653   VLOG(1) << "Response has " << num_intermediates << " intermediates";
    654 
    655   if (num_intermediates <= 0) {
    656     trusted_ca_key_der = &kAllowedICAs[0].public_key;
    657   } else {
    658     const std::string& ica = response.intermediate_certificate(0);
    659     scoped_refptr<net::X509Certificate> ica_cert
    660         = net::X509Certificate::CreateFromBytes(ica.data(), ica.length());
    661     int index = GetICAWithFingerprint(ica_cert->fingerprint());
    662     if (index == -1) {
    663       return AuthResult::Create(kErrorPrefix + "Disallowed intermediate cert",
    664                                 AuthResult::ERROR_FINGERPRINT_NOT_FOUND);
    665     }
    666     trusted_ca_key_der = &kAllowedICAs[index].public_key;
    667   }
    668 
    669   crypto::EnsureNSSInit();
    670   SECItem der_cert;
    671   der_cert.type = siDERCertBuffer;
    672   // Make a copy of certificate string so it is safe to type cast.
    673   der_cert.data = reinterpret_cast<unsigned char*>(const_cast<char*>(
    674       certificate.data()));
    675   der_cert.len = certificate.length();
    676 
    677   // Parse into a certificate structure.
    678   ScopedCERTCertificate cert(CERT_NewTempCertificate(
    679       CERT_GetDefaultCertDB(), &der_cert, NULL, PR_FALSE, PR_TRUE));
    680   if (!cert.get()) {
    681     return AuthResult::CreateWithNSSError(
    682         kErrorPrefix + "Failed to parse certificate.",
    683         AuthResult::ERROR_NSS_CERT_PARSING_FAILED,
    684         PORT_GetError());
    685   }
    686 
    687   // Check that the certificate is signed by trusted CA.
    688   // NOTE: We const_cast trusted_ca_key_der since on some platforms
    689   // SECKEY_ImportDERPublicKey API takes in SECItem* and not const
    690   // SECItem*.
    691   crypto::ScopedSECKEYPublicKey ca_public_key(
    692       SECKEY_ImportDERPublicKey(
    693           const_cast<SECItem*>(trusted_ca_key_der), CKK_RSA));
    694   SECStatus verified = CERT_VerifySignedDataWithPublicKey(
    695       &cert->signatureWrap, ca_public_key.get(), NULL);
    696   if (verified != SECSuccess) {
    697     return AuthResult::CreateWithNSSError(
    698         kErrorPrefix + "Cert not signed by trusted CA",
    699         AuthResult::ERROR_NSS_CERT_NOT_SIGNED_BY_TRUSTED_CA,
    700         PORT_GetError());
    701   }
    702 
    703   VLOG(1) << "Cert signed by trusted CA";
    704 
    705   // Verify that the |signature| matches |data|.
    706   crypto::ScopedSECKEYPublicKey public_key(CERT_ExtractPublicKey(cert.get()));
    707   if (!public_key.get()) {
    708     return AuthResult::CreateWithNSSError(
    709         kErrorPrefix + "Unable to extract public key from certificate",
    710         AuthResult::ERROR_NSS_CANNOT_EXTRACT_PUBLIC_KEY,
    711         PORT_GetError());
    712   }
    713   SECItem signature_item;
    714   signature_item.type = siBuffer;
    715   signature_item.data = reinterpret_cast<unsigned char*>(
    716       const_cast<char*>(signature.data()));
    717   signature_item.len = signature.length();
    718   verified = VFY_VerifyDataDirect(
    719       reinterpret_cast<unsigned char*>(const_cast<char*>(data.data())),
    720       data.size(),
    721       public_key.get(),
    722       &signature_item,
    723       SEC_OID_PKCS1_RSA_ENCRYPTION,
    724       SEC_OID_SHA1, NULL, NULL);
    725 
    726   if (verified != SECSuccess) {
    727     return AuthResult::CreateWithNSSError(
    728         kErrorPrefix + "Signed blobs did not match",
    729         AuthResult::ERROR_NSS_SIGNED_BLOBS_MISMATCH,
    730         PORT_GetError());
    731   }
    732 
    733   VLOG(1) << "Signature verification succeeded";
    734 
    735   return AuthResult();
    736 }
    737 
    738 }  // namespace
    739 
    740 AuthResult AuthenticateChallengeReply(const CastMessage& challenge_reply,
    741                                       const std::string& peer_cert) {
    742   if (peer_cert.empty()) {
    743     AuthResult result = AuthResult::Create("Peer cert was empty.",
    744                                            AuthResult::ERROR_PEER_CERT_EMPTY);
    745     VLOG(1) << result.error_message;
    746     return result;
    747   }
    748 
    749   VLOG(1) << "Challenge reply: " << CastMessageToString(challenge_reply);
    750   DeviceAuthMessage auth_message;
    751   AuthResult result = ParseAuthMessage(challenge_reply, &auth_message);
    752   if (!result.success()) {
    753     VLOG(1) << result.error_message;
    754     return result;
    755   }
    756 
    757   const AuthResponse& response = auth_message.response();
    758   result = VerifyCredentials(response, peer_cert);
    759   if (!result.success()) {
    760     VLOG(1) << result.error_message
    761             << ", NSS error code: " << result.nss_error_code;
    762     return result;
    763   }
    764 
    765   return AuthResult();
    766 }
    767 
    768 }  // namespace cast_channel
    769 }  // namespace core_api
    770 }  // namespace extensions
    771