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.
5 // Must be packed to ../enterprise_platform_keys.crx using the private key
6 // ../enterprise_platform_keys.pem .
10 var systemTokenEnabled = (location.href.indexOf("systemTokenEnabled") != -1);
12 var assertEq = chrome.test.assertEq;
13 var assertTrue = chrome.test.assertTrue;
14 var assertThrows = chrome.test.assertThrows;
15 var fail = chrome.test.fail;
16 var succeed = chrome.test.succeed;
17 var callbackPass = chrome.test.callbackPass;
18 var callbackFail= chrome.test.callbackFail;
20 // openssl req -new -x509 -key privkey.pem \
21 // -outform der -out cert.der -days 36500
23 // Based on privateKeyPkcs8User, which is stored in the user's token.
24 var cert1a = new Uint8Array([
25 0x30, 0x82, 0x01, 0xd5, 0x30, 0x82, 0x01, 0x7f, 0xa0, 0x03, 0x02, 0x01,
26 0x02, 0x02, 0x09, 0x00, 0xd2, 0xcc, 0x76, 0xeb, 0x19, 0xb9, 0x3a, 0x33,
27 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
28 0x05, 0x05, 0x00, 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
29 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
30 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74,
31 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a,
32 0x0c, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57,
33 0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c,
34 0x74, 0x64, 0x30, 0x20, 0x17, 0x0d, 0x31, 0x34, 0x30, 0x34, 0x31, 0x35,
35 0x31, 0x34, 0x35, 0x32, 0x30, 0x33, 0x5a, 0x18, 0x0f, 0x32, 0x31, 0x31,
36 0x34, 0x30, 0x33, 0x32, 0x32, 0x31, 0x34, 0x35, 0x32, 0x30, 0x33, 0x5a,
37 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
38 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
39 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
40 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x49,
41 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
42 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x30,
43 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
44 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41, 0x00,
45 0xc7, 0xc1, 0x4d, 0xd5, 0xdc, 0x3a, 0x2e, 0x1f, 0x42, 0x30, 0x3d, 0x21,
46 0x1e, 0xa2, 0x1f, 0x60, 0xcb, 0x71, 0x11, 0x53, 0xb0, 0x75, 0xa0, 0x62,
47 0xfe, 0x5e, 0x0a, 0xde, 0xb0, 0x0f, 0x48, 0x97, 0x5e, 0x42, 0xa7, 0x3a,
48 0xd1, 0xca, 0x4c, 0xe3, 0xdb, 0x5f, 0x31, 0xc2, 0x99, 0x08, 0x89, 0xcd,
49 0x6d, 0x20, 0xaa, 0x75, 0xe6, 0x2b, 0x98, 0xd2, 0xf3, 0x7b, 0x4b, 0xe5,
50 0x9b, 0xfe, 0xe2, 0x6d, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x50, 0x30,
51 0x4e, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
52 0xbd, 0x85, 0x6b, 0xdd, 0x84, 0xd1, 0x54, 0x2e, 0xad, 0xb4, 0x5e, 0xdd,
53 0x24, 0x7e, 0x16, 0x9c, 0x84, 0x1e, 0x19, 0xf0, 0x30, 0x1f, 0x06, 0x03,
54 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xbd, 0x85, 0x6b,
55 0xdd, 0x84, 0xd1, 0x54, 0x2e, 0xad, 0xb4, 0x5e, 0xdd, 0x24, 0x7e, 0x16,
56 0x9c, 0x84, 0x1e, 0x19, 0xf0, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13,
57 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a,
58 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x41,
59 0x00, 0x37, 0x23, 0x2f, 0x81, 0x24, 0xfc, 0xec, 0x2d, 0x0b, 0xd1, 0xa0,
60 0x74, 0xdf, 0x2e, 0x34, 0x9a, 0x92, 0x33, 0xae, 0x75, 0xd6, 0x60, 0xfc,
61 0x44, 0x1d, 0x65, 0x8c, 0xb7, 0xd9, 0x60, 0x3b, 0xc7, 0x20, 0x30, 0xdf,
62 0x17, 0x07, 0xd1, 0x87, 0xda, 0x2b, 0x7f, 0x84, 0xf3, 0xfc, 0xb0, 0x31,
63 0x42, 0x08, 0x17, 0x96, 0xd2, 0x1b, 0xdc, 0x28, 0xae, 0xf8, 0xbd, 0xf9,
64 0x4e, 0x78, 0xc3, 0xe8, 0x80
67 // Based on privateKeyPkcs8User, different from cert1a.
68 var cert1b = new Uint8Array([
69 0x30, 0x82, 0x01, 0xd5, 0x30, 0x82, 0x01, 0x7f, 0xa0, 0x03, 0x02, 0x01,
70 0x02, 0x02, 0x09, 0x00, 0xe7, 0x1e, 0x6e, 0xb0, 0x12, 0x87, 0xf5, 0x09,
71 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
72 0x05, 0x05, 0x00, 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
73 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
74 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74,
75 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a,
76 0x0c, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57,
77 0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c,
78 0x74, 0x64, 0x30, 0x20, 0x17, 0x0d, 0x31, 0x34, 0x30, 0x34, 0x31, 0x35,
79 0x31, 0x35, 0x31, 0x39, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x32, 0x31, 0x31,
80 0x34, 0x30, 0x33, 0x32, 0x32, 0x31, 0x35, 0x31, 0x39, 0x30, 0x30, 0x5a,
81 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
82 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
83 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
84 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x49,
85 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
86 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x30,
87 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
88 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41, 0x00,
89 0xc7, 0xc1, 0x4d, 0xd5, 0xdc, 0x3a, 0x2e, 0x1f, 0x42, 0x30, 0x3d, 0x21,
90 0x1e, 0xa2, 0x1f, 0x60, 0xcb, 0x71, 0x11, 0x53, 0xb0, 0x75, 0xa0, 0x62,
91 0xfe, 0x5e, 0x0a, 0xde, 0xb0, 0x0f, 0x48, 0x97, 0x5e, 0x42, 0xa7, 0x3a,
92 0xd1, 0xca, 0x4c, 0xe3, 0xdb, 0x5f, 0x31, 0xc2, 0x99, 0x08, 0x89, 0xcd,
93 0x6d, 0x20, 0xaa, 0x75, 0xe6, 0x2b, 0x98, 0xd2, 0xf3, 0x7b, 0x4b, 0xe5,
94 0x9b, 0xfe, 0xe2, 0x6d, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x50, 0x30,
95 0x4e, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
96 0xbd, 0x85, 0x6b, 0xdd, 0x84, 0xd1, 0x54, 0x2e, 0xad, 0xb4, 0x5e, 0xdd,
97 0x24, 0x7e, 0x16, 0x9c, 0x84, 0x1e, 0x19, 0xf0, 0x30, 0x1f, 0x06, 0x03,
98 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xbd, 0x85, 0x6b,
99 0xdd, 0x84, 0xd1, 0x54, 0x2e, 0xad, 0xb4, 0x5e, 0xdd, 0x24, 0x7e, 0x16,
100 0x9c, 0x84, 0x1e, 0x19, 0xf0, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13,
101 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a,
102 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x41,
103 0x00, 0x82, 0x95, 0xa7, 0x08, 0x6c, 0xbd, 0x49, 0xe6, 0x1e, 0xc1, 0xd9,
104 0x58, 0x54, 0x11, 0x11, 0x84, 0x77, 0x1e, 0xad, 0xe9, 0x73, 0x69, 0x1c,
105 0x5c, 0xaa, 0x26, 0x3e, 0x5f, 0x1d, 0x89, 0x20, 0xc3, 0x90, 0xa4, 0x67,
106 0xfa, 0x26, 0x20, 0xd7, 0x1f, 0xae, 0x42, 0x89, 0x30, 0x61, 0x43, 0x8a,
107 0x8c, 0xbe, 0xd4, 0x32, 0xf7, 0x96, 0x71, 0x2a, 0xcd, 0xeb, 0x26, 0xf6,
108 0xdb, 0x54, 0x95, 0xca, 0x5a
111 // Based on a private key different than privateKeyPkcs8User or
112 // privateKeyPkcs8System.
113 var cert2 = new Uint8Array([
114 0x30, 0x82, 0x01, 0xd5, 0x30, 0x82, 0x01, 0x7f, 0xa0, 0x03, 0x02, 0x01,
115 0x02, 0x02, 0x09, 0x00, 0x9e, 0x11, 0x7e, 0xff, 0x43, 0x84, 0xd4, 0xe6,
116 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
117 0x05, 0x05, 0x00, 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
118 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
119 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74,
120 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a,
121 0x0c, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57,
122 0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c,
123 0x74, 0x64, 0x30, 0x20, 0x17, 0x0d, 0x31, 0x34, 0x30, 0x34, 0x30, 0x37,
124 0x31, 0x35, 0x35, 0x30, 0x30, 0x38, 0x5a, 0x18, 0x0f, 0x32, 0x31, 0x31,
125 0x34, 0x30, 0x33, 0x31, 0x34, 0x31, 0x35, 0x35, 0x30, 0x30, 0x38, 0x5a,
126 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
127 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
128 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
129 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x49,
130 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
131 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x30,
132 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
133 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41, 0x00,
134 0xac, 0x6c, 0x72, 0x46, 0xa2, 0xde, 0x88, 0x30, 0x54, 0x06, 0xad, 0xc7,
135 0x2d, 0x64, 0x6e, 0xf6, 0x0f, 0x72, 0x3e, 0x92, 0x31, 0xcc, 0x0b, 0xa0,
136 0x18, 0x20, 0xb0, 0xdb, 0x86, 0xab, 0x11, 0xc6, 0xa5, 0x78, 0xea, 0x64,
137 0xe8, 0xeb, 0xa5, 0xb3, 0x78, 0x5d, 0xbb, 0x10, 0x57, 0xe6, 0x12, 0x23,
138 0x89, 0x92, 0x1d, 0xa0, 0xe5, 0x1e, 0xd1, 0xc9, 0x0e, 0x62, 0xcb, 0xc9,
139 0xaf, 0xde, 0x4e, 0x83, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x50, 0x30,
140 0x4e, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
141 0x75, 0x6c, 0x61, 0xfb, 0xb0, 0x6e, 0x37, 0x32, 0x41, 0x62, 0x3b, 0x55,
142 0xbd, 0x5f, 0x6b, 0xe0, 0xdb, 0xb9, 0xc7, 0xec, 0x30, 0x1f, 0x06, 0x03,
143 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x75, 0x6c, 0x61,
144 0xfb, 0xb0, 0x6e, 0x37, 0x32, 0x41, 0x62, 0x3b, 0x55, 0xbd, 0x5f, 0x6b,
145 0xe0, 0xdb, 0xb9, 0xc7, 0xec, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13,
146 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a,
147 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x41,
148 0x00, 0xa5, 0xe8, 0x9d, 0x3d, 0xc4, 0x1a, 0x6e, 0xd2, 0x92, 0x42, 0x37,
149 0xb9, 0x3a, 0xb3, 0x8e, 0x2f, 0x55, 0xb5, 0xf2, 0xe4, 0x6e, 0x39, 0x0d,
150 0xa8, 0xba, 0x10, 0x43, 0x57, 0xdd, 0x4e, 0x4e, 0x52, 0xc6, 0xbe, 0x07,
151 0xdb, 0x83, 0x05, 0x97, 0x97, 0xc1, 0x7b, 0xd5, 0x5c, 0x50, 0x64, 0x0f,
152 0x96, 0xff, 0x3d, 0x83, 0x37, 0x8f, 0x3a, 0x85, 0x08, 0x62, 0x5c, 0xb1,
153 0x2f, 0x68, 0xb2, 0x4a, 0x4a
156 // Based on privateKeyPkcs8System, which is stored in the system token.
157 var certSystem = new Uint8Array([
158 0x30, 0x82, 0x01, 0xd5, 0x30, 0x82, 0x01, 0x7f, 0xa0, 0x03, 0x02, 0x01,
159 0x02, 0x02, 0x09, 0x00, 0xf4, 0x3d, 0x9f, 0xd2, 0x1e, 0xa4, 0xf5, 0x82,
160 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
161 0x05, 0x05, 0x00, 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
162 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
163 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74,
164 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a,
165 0x0c, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57,
166 0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c,
167 0x74, 0x64, 0x30, 0x20, 0x17, 0x0d, 0x31, 0x34, 0x30, 0x37, 0x32, 0x38,
168 0x31, 0x33, 0x31, 0x36, 0x34, 0x35, 0x5a, 0x18, 0x0f, 0x32, 0x31, 0x31,
169 0x34, 0x30, 0x37, 0x30, 0x34, 0x31, 0x33, 0x31, 0x36, 0x34, 0x35, 0x5a,
170 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
171 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
172 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
173 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x49,
174 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
175 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x30,
176 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
177 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41, 0x00,
178 0xe8, 0xb3, 0x04, 0xb1, 0xad, 0xef, 0x6b, 0xe5, 0xbe, 0xc9, 0x05, 0x75,
179 0x07, 0x41, 0xf5, 0x70, 0x50, 0xc2, 0xe8, 0xee, 0xeb, 0x09, 0x9d, 0x49,
180 0x64, 0x4c, 0x60, 0x61, 0x80, 0xbe, 0xc5, 0x41, 0xf3, 0x8c, 0x57, 0x90,
181 0x3a, 0x44, 0x62, 0x6d, 0x51, 0xb8, 0xbb, 0xc6, 0x9a, 0x16, 0xdf, 0xf9,
182 0xce, 0xe3, 0xb8, 0x8c, 0x2e, 0xa2, 0x16, 0xc8, 0xed, 0xc7, 0xf8, 0x4f,
183 0xbd, 0xd3, 0x6e, 0x63, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x50, 0x30,
184 0x4e, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
185 0xcd, 0x97, 0x2d, 0xb2, 0xe2, 0xb8, 0x11, 0xea, 0xcf, 0x0b, 0xca, 0xad,
186 0x61, 0xf4, 0x2e, 0x49, 0x3e, 0xa0, 0x7e, 0xa7, 0x30, 0x1f, 0x06, 0x03,
187 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xcd, 0x97, 0x2d,
188 0xb2, 0xe2, 0xb8, 0x11, 0xea, 0xcf, 0x0b, 0xca, 0xad, 0x61, 0xf4, 0x2e,
189 0x49, 0x3e, 0xa0, 0x7e, 0xa7, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13,
190 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a,
191 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x41,
192 0x00, 0x8c, 0x05, 0x7e, 0xb1, 0xef, 0x5f, 0x7d, 0x80, 0x0c, 0x70, 0x9c,
193 0x99, 0x70, 0x97, 0x5f, 0x83, 0x89, 0xe3, 0x4e, 0x3c, 0x77, 0xed, 0xf3,
194 0x66, 0x2d, 0xd6, 0xa9, 0x46, 0x7d, 0xeb, 0x58, 0xbc, 0x50, 0xa7, 0xe6,
195 0xd7, 0x7d, 0xfc, 0xdd, 0x18, 0x20, 0x53, 0xfb, 0x11, 0x3d, 0xfc, 0x2f,
196 0xf3, 0x30, 0x60, 0x47, 0x2d, 0x8e, 0xd7, 0xbf, 0x0f, 0x0d, 0x47, 0x99,
197 0xcc, 0x6d, 0xab, 0xb6, 0xd6
201 * Runs an array of asynchronous functions [f1, f2, ...] of the form
202 * function(callback) {}
203 * by chaining, i.e. f1(f2(...)). Additionally, each callback is wrapped with
206 function runAsyncSequence(funcs) {
207 if (funcs.length == 0)
210 var current = funcs[i];
211 console.log('#' + (i + 1) + ' of ' + funcs.length);
212 if (i == funcs.length - 1) {
213 current(callbackPass());
215 current(callbackPass(go.bind(undefined, i + 1)));
221 // Some array comparison. Note: not lexicographical!
222 function compareArrays(array1, array2) {
223 if (array1.length < array2.length)
225 if (array1.length > array2.length)
227 for (var i = 0; i < array1.length; i++) {
228 if (array1[i] < array2[i])
230 if (array1[i] > array2[i])
237 * @param {ArrayBufferView[]} certs
238 * @return {ArrayBufferView[]} |certs| sorted in some order.
240 function sortCerts(certs) {
241 return certs.sort(compareArrays);
245 * Checks whether the certificates currently stored in |token| match
246 * |expectedCerts| by comparing to the result of platformKeys.getCertificates.
247 * The order of |expectedCerts| is ignored. Afterwards calls |callback|.
249 function assertCertsStored(token, expectedCerts, callback) {
255 chrome.enterprise.platformKeys.getCertificates(
257 callbackPass(function(actualCerts) {
258 assertEq(expectedCerts.length,
260 'Number of stored certs not as expected');
261 if (expectedCerts.length == actualCerts.length) {
262 actualCerts = actualCerts.map(
263 function(buffer) { return new Uint8Array(buffer); });
264 actualCerts = sortCerts(actualCerts);
265 expectedCerts = sortCerts(expectedCerts);
266 for (var i = 0; i < expectedCerts.length; i++) {
267 assertTrue(compareArrays(expectedCerts[i], actualCerts[i]) == 0,
268 'Certs at index ' + i + ' differ');
277 * Fetches all available tokens using platformKeys.getTokens and calls
278 * |callback| with the user and system token if available or with undefined
281 function getTokens(callback) {
282 chrome.enterprise.platformKeys.getTokens(function(tokens) {
283 var userToken = null;
284 var systemToken = null;
285 for (var i = 0; i < tokens.length; i++) {
286 if (tokens[i].id == 'user')
287 userToken = tokens[i];
288 else if (tokens[i].id == 'system')
289 systemToken = tokens[i];
291 callback(userToken, systemToken);
296 * Runs preparations before the actual tests. Calls |callback| with |userToken|.
298 function beforeTests(callback) {
299 assertTrue(!!chrome.enterprise, "No enterprise namespace.");
300 assertTrue(!!chrome.enterprise.platformKeys, "No platformKeys namespace.");
301 assertTrue(!!chrome.enterprise.platformKeys.getTokens,
302 "No getTokens function.");
303 assertTrue(!!chrome.enterprise.platformKeys.importCertificate,
304 "No importCertificate function.");
305 assertTrue(!!chrome.enterprise.platformKeys.removeCertificate,
306 "No removeCertificate function.");
308 getTokens(function(userToken, systemToken) {
310 fail('no user token');
311 assertEq('user', userToken.id);
313 if (systemTokenEnabled) {
315 fail('no system token');
316 assertEq('system', systemToken.id);
320 'system token is disabled, but found the token nonetheless.');
323 callback(userToken, systemToken);
327 function checkAlgorithmIsCopiedOnRead(key) {
328 var algorithm = key.algorithm;
329 var originalAlgorithm = {
330 name: algorithm.name,
331 modulusLength: algorithm.modulusLength,
332 publicExponent: algorithm.publicExponent,
333 hash: {name: algorithm.hash.name}
335 var originalModulusLength = algorithm.modulusLength;
336 algorithm.hash.name = null;
337 algorithm.hash = null;
338 algorithm.name = null;
339 algorithm.modulusLength = null;
340 algorithm.publicExponent = null;
341 assertEq(originalAlgorithm, key.algorithm);
344 function checkPropertyIsReadOnly(object, key) {
345 var original = object[key];
348 fail('Expected the property to be read-only and an exception to be thrown');
350 assertEq(original, object[key]);
354 function checkKeyPairCommonFormat(keyPair) {
355 checkPropertyIsReadOnly(keyPair, 'privateKey');
356 var privateKey = keyPair.privateKey;
357 assertEq('private', privateKey.type);
358 assertEq(false, privateKey.extractable);
359 checkPropertyIsReadOnly(privateKey, 'algorithm');
360 checkAlgorithmIsCopiedOnRead(privateKey);
362 checkPropertyIsReadOnly(keyPair, 'publicKey');
363 var publicKey = keyPair.publicKey;
364 assertEq('public', publicKey.type);
365 assertEq(true, publicKey.extractable);
366 checkPropertyIsReadOnly(publicKey, 'algorithm');
367 checkAlgorithmIsCopiedOnRead(publicKey);
370 // Generates a key with the |algorithm| parameters. Signs |data| using the new
371 // key and verifies the signature using WebCrypto. Returns the generated key to
372 // |callback| for further operations.
373 // Also freezes |algorithm|.
374 function generateKeyAndVerify(token, algorithm, data, callback) {
375 // Ensure that this algorithm object is not modified, so that later
376 // comparisons really do the right thing.
377 Object.freeze(algorithm.hash);
378 Object.freeze(algorithm);
383 token.subtleCrypto.generateKey(algorithm, false, ["sign"])
386 assertTrue(!!keyPair, "No key pair.");
387 cachedKeyPair = keyPair;
388 return token.subtleCrypto.exportKey('spki',
391 function(error) { fail("GenerateKey failed: " + error); })
393 function(publicKeySpki) {
394 // Ensure that the returned key pair has the expected format.
395 // Some parameter independent checks:
396 checkKeyPairCommonFormat(cachedKeyPair);
398 // Checks depending on the generateKey arguments:
399 var privateKey = cachedKeyPair.privateKey;
400 assertEq(['sign'], privateKey.usages);
401 assertEq(algorithm, privateKey.algorithm);
403 var publicKey = cachedKeyPair.publicKey;
404 assertEq([], publicKey.usages);
405 assertEq(algorithm, publicKey.algorithm);
407 cachedSpki = publicKeySpki;
408 var signParams = {name: 'RSASSA-PKCS1-v1_5'};
409 return token.subtleCrypto.sign(signParams, privateKey, data);
411 function(error) { fail("Export failed: " + error); })
413 function(signature) {
415 name: algorithm.name,
416 // RsaHashedImportParams
418 name: algorithm.hash.name,
421 assertTrue(!!signature, "No signature.");
422 assertTrue(signature.length != 0, "Signature is empty.");
423 cachedSignature = signature;
424 return window.crypto.subtle.importKey(
425 "spki", cachedSpki, importParams, false, ["verify"]);
427 function(error) { fail("Sign failed: " + error); })
429 function(webCryptoPublicKey) {
430 assertTrue(!!webCryptoPublicKey);
431 assertEq(algorithm.modulusLength,
432 webCryptoPublicKey.algorithm.modulusLength);
433 assertEq(algorithm.publicExponent,
434 webCryptoPublicKey.algorithm.publicExponent);
435 return window.crypto.subtle.verify(
436 algorithm, webCryptoPublicKey, cachedSignature, data);
438 function(error) { fail("Import failed: " + error); })
439 .then(callbackPass(function(success) {
440 assertEq(true, success, "Signature invalid.");
441 callback(cachedKeyPair);
442 }), function(error) { fail("Verification failed: " + error); });
445 function testInitiallyNoCerts(token) {
446 assertCertsStored(token, []);
449 function testHasSubtleCryptoMethods(token) {
450 assertTrue(!!token.subtleCrypto.generateKey,
451 "token has no generateKey method");
452 assertTrue(!!token.subtleCrypto.sign, "token has no sign method");
453 assertTrue(!!token.subtleCrypto.exportKey,
454 "token has no exportKey method");
458 // Generates a key and signs some data with it. Verifies the signature using
459 // WebCrypto. Verifies also that a second sign operation fails.
460 function testGenerateKeyAndSign(token) {
462 name: "RSASSA-PKCS1-v1_5",
463 // RsaHashedKeyGenParams
465 // Equivalent to 65537
466 publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
472 // Some random data to sign.
473 var data = new Uint8Array([0, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 6]);
474 generateKeyAndVerify(token,
477 callbackPass(function(keyPair) {
478 // Try to sign data with the same key a second time, which
480 var signParams = {name: 'RSASSA-PKCS1-v1_5'};
481 token.subtleCrypto.sign(signParams, keyPair.privateKey, data).then(
482 function(signature) { fail("Second sign call was expected to fail."); },
483 callbackPass(function(error) {
484 assertTrue(error instanceof Error);
485 assertEq('The operation failed for an operation-specific reason',
491 // Generates a key and signs some data with other parameters. Verifies the
492 // signature using WebCrypto.
493 function testGenerateKeyAndSignOtherParameters(token) {
495 name: "RSASSA-PKCS1-v1_5",
496 // RsaHashedKeyGenParams
498 // Equivalent to 65537
499 publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
505 // Some random data to sign.
506 var data = new Uint8Array([5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 0, 0, 254]);
507 generateKeyAndVerify(token, algorithm, data, callbackPass());
510 // Call generate key with invalid algorithm parameter, missing
512 function testAlgorithmParameterMissingModulusLength(token) {
514 name: "RSASSA-PKCS1-v1_5",
515 // Equivalent to 65537
516 publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
521 token.subtleCrypto.generateKey(algorithm, false, ['sign'])
522 .then(function(keyPair) { fail('generateKey was expected to fail'); },
523 callbackPass(function(error) {
524 assertTrue(error instanceof Error);
525 assertEq('A required parameter was missing or out-of-range', error.message);
529 // Call generate key with invalid algorithm parameter, missing hash.
530 function testAlgorithmParameterMissingHash(token) {
532 name: 'RSASSA-PKCS1-v1_5',
534 // Equivalent to 65537
535 publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
537 token.subtleCrypto.generateKey(algorithm, false, ['sign'])
538 .then(function(keyPair) { fail('generateKey was expected to fail'); },
539 callbackPass(function(error) {
541 new Error('Error: A required parameter was missing our out-of-range'),
546 // Call generate key with invalid algorithm parameter, unsupported public
548 function testAlgorithmParameterUnsupportedPublicExponent(token) {
550 name: 'RSASSA-PKCS1-v1_5',
552 // Different from 65537.
553 publicExponent: new Uint8Array([0x01, 0x01]),
555 token.subtleCrypto.generateKey(algorithm, false, ['sign'])
556 .then(function(keyPair) { fail('generateKey was expected to fail'); },
557 callbackPass(function(error) {
558 assertTrue(error instanceof Error);
559 assertEq('A required parameter was missing or out-of-range', error.message);
563 function testImportInvalidCert(token) {
564 var invalidCert = new ArrayBuffer(16);
565 chrome.enterprise.platformKeys.importCertificate(
568 callbackFail('Certificate is not a valid X.509 certificate.'));
571 function testRemoveUnknownCert(token) {
572 chrome.enterprise.platformKeys.removeCertificate(
573 token.id, cert2.buffer, callbackFail('Certificate could not be found.'));
576 function testRemoveInvalidCert(token) {
577 var invalidCert = new ArrayBuffer(16);
578 chrome.enterprise.platformKeys.removeCertificate(
581 callbackFail('Certificate is not a valid X.509 certificate.'));
584 function bindTestsToToken(tests, token) {
585 return tests.map(function(test) {
586 var bound = test.bind(undefined, token);
587 bound.generatedName = test.name;
592 function runTests(userToken, systemToken) {
593 // These tests don't depend on keys being loaded on C++ side (which will be
594 // removed by tests below) and are run for each available token.
595 var testsIndependentOfKeysWithTokenParameter = [
596 testInitiallyNoCerts,
597 testHasSubtleCryptoMethods,
598 testRemoveUnknownCert,
599 testGenerateKeyAndSign,
600 testGenerateKeyAndSignOtherParameters,
601 testAlgorithmParameterMissingModulusLength,
602 testAlgorithmParameterMissingHash,
603 testAlgorithmParameterUnsupportedPublicExponent,
604 testImportInvalidCert,
605 testRemoveInvalidCert,
607 var testsIndependentOfKeys =
608 bindTestsToToken(testsIndependentOfKeysWithTokenParameter, userToken);
610 testsIndependentOfKeys.concat(bindTestsToToken(
611 testsIndependentOfKeysWithTokenParameter, systemToken));
614 // These tests are not parameterized and work with the keys loaded by the C++
615 // side and potentially remove these keys from the tokens.
616 var testsNotParameterized = [
617 // Importing a cert should fail, if the private key is stored in another
619 // This uses the certs that refers to the privateKeyPkcs8User and
620 // privateKeyPkcs8System keys, which were imported on C++'s side.
621 function importCertWithKeyInOtherToken() {
627 function importToSystemWithKeyInUserToken(callback) {
628 chrome.enterprise.platformKeys.importCertificate(
631 callbackFail('Key not found.', callback));
633 function importToUserWithKeyInSystemToken(callback) {
634 chrome.enterprise.platformKeys.importCertificate(
637 callbackFail('Key not found.', callback));
640 importToSystemWithKeyInUserToken(
641 importToUserWithKeyInSystemToken.bind(null, null));
644 // Imports and removes certificates for privateKeyPkcs8User and
645 // privateKeyPkcs8System (if the system token is enabled), which were
646 // imported on C++'s side.
647 // Note: After this test, privateKeyPkcs8User and privateKeyPkcs8System are
648 // not stored anymore!
649 function importAndRemoveCerts() {
652 chrome.enterprise.platformKeys.importCertificate.bind(
653 null, userToken.id, cert1a.buffer),
654 assertCertsStored.bind(null, userToken, [cert1a]),
656 // Importing the same cert again shouldn't change anything.
657 chrome.enterprise.platformKeys.importCertificate.bind(
658 null, userToken.id, cert1a.buffer),
659 assertCertsStored.bind(null, userToken, [cert1a]),
661 // The system token should still be empty.
662 assertCertsStored.bind(null, systemToken, []),
664 // Importing to the system token should not affect the user token.
665 chrome.enterprise.platformKeys.importCertificate.bind(
666 null, systemToken.id, certSystem.buffer),
667 assertCertsStored.bind(null, systemToken, [certSystem]),
668 assertCertsStored.bind(null, userToken, [cert1a]),
670 // Importing the same cert again to the system token shouldn't change
672 chrome.enterprise.platformKeys.importCertificate.bind(
673 null, systemToken.id, certSystem.buffer),
674 assertCertsStored.bind(null, systemToken, [certSystem]),
676 // Importing another certificate should succeed.
677 chrome.enterprise.platformKeys.importCertificate.bind(
678 null, userToken.id, cert1b.buffer),
679 assertCertsStored.bind(null, userToken, [cert1a, cert1b]),
682 chrome.enterprise.platformKeys.removeCertificate.bind(
683 null, userToken.id, cert1a.buffer),
684 assertCertsStored.bind(null, userToken, [cert1b]),
686 // Remove certSystem.
687 chrome.enterprise.platformKeys.removeCertificate.bind(
688 null, systemToken.id, certSystem.buffer),
689 assertCertsStored.bind(null, systemToken, []),
690 assertCertsStored.bind(null, userToken, [cert1b]),
693 chrome.enterprise.platformKeys.removeCertificate.bind(
694 null, userToken.id, cert1b.buffer),
695 assertCertsStored.bind(null, userToken, [])
699 chrome.enterprise.platformKeys.importCertificate.bind(
700 null, userToken.id, cert1a.buffer),
701 assertCertsStored.bind(null, userToken, [cert1a]),
702 // Importing the same cert again shouldn't change anything.
703 chrome.enterprise.platformKeys.importCertificate.bind(
704 null, userToken.id, cert1a.buffer),
705 assertCertsStored.bind(null, userToken, [cert1a]),
706 // Importing another certificate should succeed.
707 chrome.enterprise.platformKeys.importCertificate.bind(
708 null, userToken.id, cert1b.buffer),
709 assertCertsStored.bind(null, userToken, [cert1a, cert1b]),
710 chrome.enterprise.platformKeys.removeCertificate.bind(
711 null, userToken.id, cert1a.buffer),
712 assertCertsStored.bind(null, userToken, [cert1b]),
713 chrome.enterprise.platformKeys.removeCertificate.bind(
714 null, userToken.id, cert1b.buffer),
715 assertCertsStored.bind(null, userToken, [])
720 function getCertsInvalidToken() {
721 chrome.enterprise.platformKeys.getCertificates(
722 'invalid token id', callbackFail('The token is not valid.'));
725 // Imports a certificate for which no private key was imported/generated
727 function missingPrivateKeyUserToken() {
728 chrome.enterprise.platformKeys.importCertificate(
729 userToken.id, cert2.buffer, callbackFail('Key not found.'));
732 function missingPrivateKeySystemToken() {
737 chrome.enterprise.platformKeys.importCertificate(
738 systemToken.id, certSystem.buffer, callbackFail('Key not found.'));
742 chrome.test.runTests(testsIndependentOfKeys.concat(testsNotParameterized));
745 beforeTests(runTests);