Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chrome / test / data / extensions / api_test / enterprise_platform_keys / basic.js
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 // Must be packed to ../enterprise_platform_keys.crx using the private key
6 // ../enterprise_platform_keys.pem .
7
8 'use strict';
9
10 var systemTokenEnabled = (location.href.indexOf("systemTokenEnabled") != -1);
11
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;
19
20 // openssl req -new -x509 -key privkey.pem \
21 //   -outform der -out cert.der -days 36500
22 // xxd -i cert.der
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
65 ]);
66
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
109 ]);
110
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
154 ]);
155
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
198 ]);
199
200 /**
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
204  * callbackPass.
205  */
206 function runAsyncSequence(funcs) {
207   if (funcs.length == 0)
208     return;
209   function go(i) {
210     var current = funcs[i];
211     console.log('#' + (i + 1) + ' of ' + funcs.length);
212     if (i == funcs.length - 1) {
213       current(callbackPass());
214     } else {
215       current(callbackPass(go.bind(undefined, i + 1)));
216     }
217   };
218   go(0);
219 }
220
221 // Some array comparison. Note: not lexicographical!
222 function compareArrays(array1, array2) {
223   if (array1.length < array2.length)
224     return -1;
225   if (array1.length > array2.length)
226     return 1;
227   for (var i = 0; i < array1.length; i++) {
228     if (array1[i] < array2[i])
229       return -1;
230     if (array1[i] > array2[i])
231       return 1;
232   }
233   return 0;
234 }
235
236 /**
237  * @param {ArrayBufferView[]} certs
238  * @return {ArrayBufferView[]} |certs| sorted in some order.
239  */
240 function sortCerts(certs) {
241   return certs.sort(compareArrays);
242 }
243
244 /**
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|.
248  */
249 function assertCertsStored(token, expectedCerts, callback) {
250   if (!token) {
251     if (callback)
252       callback();
253     return;
254   }
255   chrome.enterprise.platformKeys.getCertificates(
256       token.id,
257       callbackPass(function(actualCerts) {
258         assertEq(expectedCerts.length,
259                  actualCerts.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');
269           }
270         }
271         if (callback)
272           callback();
273       }));
274 }
275
276 /**
277  * Fetches all available tokens using platformKeys.getTokens and calls
278  * |callback| with the user and system token if available or with undefined
279  * otherwise.
280  */
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];
290     }
291     callback(userToken, systemToken);
292   });
293 }
294
295 /**
296  * Runs preparations before the actual tests. Calls |callback| with |userToken|.
297  */
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.");
307
308   getTokens(function(userToken, systemToken) {
309     if (!userToken)
310       fail('no user token');
311     assertEq('user', userToken.id);
312
313     if (systemTokenEnabled) {
314       if (!systemToken)
315         fail('no system token');
316       assertEq('system', systemToken.id);
317     } else {
318       assertEq(null,
319                systemToken,
320                'system token is disabled, but found the token nonetheless.');
321     }
322
323     callback(userToken, systemToken);
324   });
325 }
326
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}
334   };
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);
342 }
343
344 function checkPropertyIsReadOnly(object, key) {
345   var original = object[key];
346   try {
347     object[key] = {};
348     fail('Expected the property to be read-only and an exception to be thrown');
349   } catch (error) {
350     assertEq(original, object[key]);
351   }
352 }
353
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);
361
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);
368 }
369
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);
379
380   var cachedSignature;
381   var cachedKeyPair;
382   var cachedSpki;
383   token.subtleCrypto.generateKey(algorithm, false, ["sign"])
384       .then(callbackPass(
385                 function(keyPair) {
386                   assertTrue(!!keyPair, "No key pair.");
387                   cachedKeyPair = keyPair;
388                   return token.subtleCrypto.exportKey('spki',
389                                                       keyPair.publicKey);
390                 }),
391             function(error) { fail("GenerateKey failed: " + error); })
392       .then(callbackPass(
393                 function(publicKeySpki) {
394                   // Ensure that the returned key pair has the expected format.
395                   // Some parameter independent checks:
396                   checkKeyPairCommonFormat(cachedKeyPair);
397
398                   // Checks depending on the generateKey arguments:
399                   var privateKey = cachedKeyPair.privateKey;
400                   assertEq(['sign'], privateKey.usages);
401                   assertEq(algorithm, privateKey.algorithm);
402
403                   var publicKey = cachedKeyPair.publicKey;
404                   assertEq([], publicKey.usages);
405                   assertEq(algorithm, publicKey.algorithm);
406
407                   cachedSpki = publicKeySpki;
408                   var signParams = {name: 'RSASSA-PKCS1-v1_5'};
409                   return token.subtleCrypto.sign(signParams, privateKey, data);
410                 }),
411             function(error) { fail("Export failed: " + error); })
412       .then(callbackPass(
413                 function(signature) {
414                   var importParams = {
415                     name: algorithm.name,
416                     // RsaHashedImportParams
417                     hash: {
418                       name: algorithm.hash.name,
419                     }
420                   };
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"]);
426                 }),
427             function(error) { fail("Sign failed: " + error); })
428       .then(callbackPass(
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);
437                 }),
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); });
443 }
444
445 function testInitiallyNoCerts(token) {
446   assertCertsStored(token, []);
447 }
448
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");
455   succeed();
456 }
457
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) {
461   var algorithm = {
462     name: "RSASSA-PKCS1-v1_5",
463     // RsaHashedKeyGenParams
464     modulusLength: 512,
465     // Equivalent to 65537
466     publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
467     hash: {
468       name: "SHA-1",
469     }
470   };
471
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,
475                        algorithm,
476                        data,
477                        callbackPass(function(keyPair) {
478     // Try to sign data with the same key a second time, which
479     // must fail.
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',
486                error.message);
487     }));
488   }));
489 }
490
491 // Generates a key and signs some data with other parameters. Verifies the
492 // signature using WebCrypto.
493 function testGenerateKeyAndSignOtherParameters(token) {
494   var algorithm = {
495     name: "RSASSA-PKCS1-v1_5",
496     // RsaHashedKeyGenParams
497     modulusLength: 1024,
498     // Equivalent to 65537
499     publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
500     hash: {
501       name: "SHA-512",
502     }
503   };
504
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());
508 }
509
510 // Call generate key with invalid algorithm parameter, missing
511 // modulusLength.
512 function testAlgorithmParameterMissingModulusLength(token) {
513   var algorithm = {
514     name: "RSASSA-PKCS1-v1_5",
515     // Equivalent to 65537
516     publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
517     hash: {
518       name: "SHA-1",
519     }
520   };
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);
526   }));
527 }
528
529 // Call generate key with invalid algorithm parameter, missing hash.
530 function testAlgorithmParameterMissingHash(token) {
531   var algorithm = {
532     name: 'RSASSA-PKCS1-v1_5',
533     modulusLength: 512,
534     // Equivalent to 65537
535     publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
536   };
537   token.subtleCrypto.generateKey(algorithm, false, ['sign'])
538       .then(function(keyPair) { fail('generateKey was expected to fail'); },
539             callbackPass(function(error) {
540     assertEq(
541         new Error('Error: A required parameter was missing our out-of-range'),
542         error);
543   }));
544 }
545
546 // Call generate key with invalid algorithm parameter, unsupported public
547 // exponent.
548 function testAlgorithmParameterUnsupportedPublicExponent(token) {
549   var algorithm = {
550     name: 'RSASSA-PKCS1-v1_5',
551     modulusLength: 512,
552                    // Different from 65537.
553     publicExponent: new Uint8Array([0x01, 0x01]),
554   };
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);
560   }));
561 }
562
563 function testImportInvalidCert(token) {
564   var invalidCert = new ArrayBuffer(16);
565   chrome.enterprise.platformKeys.importCertificate(
566       token.id,
567       invalidCert,
568       callbackFail('Certificate is not a valid X.509 certificate.'));
569 }
570
571 function testRemoveUnknownCert(token) {
572   chrome.enterprise.platformKeys.removeCertificate(
573       token.id, cert2.buffer, callbackFail('Certificate could not be found.'));
574 }
575
576 function testRemoveInvalidCert(token) {
577   var invalidCert = new ArrayBuffer(16);
578   chrome.enterprise.platformKeys.removeCertificate(
579       token.id,
580       invalidCert,
581       callbackFail('Certificate is not a valid X.509 certificate.'));
582 }
583
584 function bindTestsToToken(tests, token) {
585   return tests.map(function(test) {
586     var bound = test.bind(undefined, token);
587     bound.generatedName = test.name;
588     return bound;
589   });
590 }
591
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,
606   ];
607   var testsIndependentOfKeys =
608       bindTestsToToken(testsIndependentOfKeysWithTokenParameter, userToken);
609   if (systemToken) {
610     testsIndependentOfKeys.concat(bindTestsToToken(
611         testsIndependentOfKeysWithTokenParameter, systemToken));
612   }
613
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
618     // token.
619     // This uses the certs that refers to the privateKeyPkcs8User and
620     // privateKeyPkcs8System keys, which were imported on C++'s side.
621     function importCertWithKeyInOtherToken() {
622       if (!systemToken) {
623         succeed();
624         return;
625       }
626
627       function importToSystemWithKeyInUserToken(callback) {
628         chrome.enterprise.platformKeys.importCertificate(
629             systemToken.id,
630             cert1a.buffer,
631             callbackFail('Key not found.', callback));
632       }
633       function importToUserWithKeyInSystemToken(callback) {
634         chrome.enterprise.platformKeys.importCertificate(
635             userToken.id,
636             certSystem.buffer,
637             callbackFail('Key not found.', callback));
638       }
639
640       importToSystemWithKeyInUserToken(
641           importToUserWithKeyInSystemToken.bind(null, null));
642     },
643
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() {
650       if (systemToken) {
651         runAsyncSequence([
652           chrome.enterprise.platformKeys.importCertificate.bind(
653               null, userToken.id, cert1a.buffer),
654           assertCertsStored.bind(null, userToken, [cert1a]),
655
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]),
660
661           // The system token should still be empty.
662           assertCertsStored.bind(null, systemToken, []),
663
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]),
669
670           // Importing the same cert again to the system token shouldn't change
671           // anything.
672           chrome.enterprise.platformKeys.importCertificate.bind(
673               null, systemToken.id, certSystem.buffer),
674           assertCertsStored.bind(null, systemToken, [certSystem]),
675
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]),
680
681           // Remove cert1a.
682           chrome.enterprise.platformKeys.removeCertificate.bind(
683               null, userToken.id, cert1a.buffer),
684           assertCertsStored.bind(null, userToken, [cert1b]),
685
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]),
691
692           // Remove cert1b.
693           chrome.enterprise.platformKeys.removeCertificate.bind(
694               null, userToken.id, cert1b.buffer),
695           assertCertsStored.bind(null, userToken, [])
696         ]);
697       } else {
698         runAsyncSequence([
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, [])
716         ]);
717       }
718     },
719
720     function getCertsInvalidToken() {
721       chrome.enterprise.platformKeys.getCertificates(
722           'invalid token id', callbackFail('The token is not valid.'));
723     },
724
725     // Imports a certificate for which no private key was imported/generated
726     // before.
727     function missingPrivateKeyUserToken() {
728       chrome.enterprise.platformKeys.importCertificate(
729           userToken.id, cert2.buffer, callbackFail('Key not found.'));
730     },
731
732     function missingPrivateKeySystemToken() {
733       if (!systemToken) {
734         succeed();
735         return;
736       }
737       chrome.enterprise.platformKeys.importCertificate(
738           systemToken.id, certSystem.buffer, callbackFail('Key not found.'));
739     }
740   ];
741
742   chrome.test.runTests(testsIndependentOfKeys.concat(testsNotParameterized));
743 }
744
745 beforeTests(runTests);