1 /*
2 * Sybase Hybrid App version 2.3
3 *
4 * Certificate.js
5 * This file will not be regenerated, so it is possible to modify it, but it
6 * is not recommended.
7 *
8 * Last Updated: 2011/6/29
9 *
10 * Copyright (c) 2012 Sybase Inc. All rights reserved.
11 *
12 * Note a certificate object will have the following fields
13 - issuerCN - The common name (CN) from the certificate issuer's distinguished name.
14 - issuerDN - The certificate issuer's distinguished name, in string form.
15 - notAfter - End time for certificate's validity period, with date/time fields as they would appear in UTC.
16 - notBefore - Start time for the certificate's validity period, with date/time fields as they would appear in UTC.
17 - signedCertificate - The digitally signed certificate in Base64 format
18 - subjectCN - The common name (CN) from the certificate subject's distinguished name.
19 - subjectDN - The certificate subject's distinguished name, in string form.
20 */
21
22 /**
23 * This class represents an X.509 public certificate store.
24 */
25
26 /**
27 * The namespace for the Hybrid Web Container javascript
28 * @namespace
29 */
30 hwc = (typeof hwc === "undefined" || !hwc) ? {} : hwc; // SUP 'namespace'
31
32
33 (function(hwc, window, undefined) {
34 /**
35 * Use these functions for X.509 credential handling.
36 * <p>
37 * Use these functions to create a user interface in HTML and JavaScript, that uses X.509 certificates as the Workflow credentials.
38 * </p>
39 * <p>
40 * This file contains the functions that allow parsing a certificate date, creating a certificate from a JSON string value, retrieving a certificate from a file (Android), retrieving a certificate from the server (iOS), and so on.
41 * </p>
42 * @class
43 * @memberOf hwc
44 */
45 hwc.CertificateStore = function() {
46 };
47
48 (function() {
49 /**
50 * Private function
51 * Convert string type date to JavaScript Date
52 * Format: 2014-05-24T20:00:12Z -> Sat May 24 2014 16:00:12 GMT-0400 (Eastern Daylight Time)
53 *
54 * @private
55 * @param value Date string to parse
56 * @return Javascript type Date object
57 */
58 function parseCertDate(value) {
59 var a = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
60 return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], +a[5], +a[6]));
61 }
62
63 /**
64 * Private function
65 * Create certificate object
66 *
67 * @private
68 * @param value JSON string type certificate
69 * {"subjectDN":"CN=android, OU=SUP, O=Sybase, L=Dublin, ST=California, C=US",
70 * "notBefore":"2012-05-24T20:00:12Z",
71 * "notAfter":"2014-05-24T20:00:12Z",
72 * "subjectCN":"android",
73 * "signedCertificate":"base64 encoded string here",
74 * "issuerDN":"CN=teva, CN=sybase.com, OU=Unwired Enterprise, O=Sybase Inc., L=Dublin, ST=California, C=US",
75 * "issuerCN":"teva"}
76 * @return Certificate object
77 */
78 function createCert(value) {
79 var cert;
80 if (value === null || typeof value === 'undefined' || value.length === 0) {
81 return null;
82 }
83
84 cert = JSON.parse(value);
85
86 if (cert.notAfter) {
87 cert.notAfter = new Date(parseCertDate(cert.notAfter));
88 }
89 if (cert.notBefore) {
90 cert.notBefore = new Date(parseCertDate(cert.notBefore));
91 }
92
93 return cert;
94 }
95
96 /**
97 * Returns a list of all the certificate labels in this store (can be empty). Each certificate in this store has a unique label.
98 *
99 * <b>Supported Platforms: </b> Windows Mobile and BlackBerry.
100 * @feature Certificate
101 * @public
102 * @memberOf hwc.CertificateStore
103 * @param {String} filterSubject filter of subject
104 * @param {String} filterIssuer filter of issuer
105 * @return {String[]} Only filtered certificate labels
106 * @example
107 * // The following script gets all the labels for certificates
108 * // with the provided subject and issuer
109 * var certStore = CertificateStore.getDefault();
110 * var labels = certStore.certificateLabels("MyUser", "mydomain.com");
111 */
112 hwc.CertificateStore.prototype.certificateLabels = function(filterSubject, filterIssuer) {
113 var response = "";
114
115 hwc.traceEnteringMethod("hwc.CertificateStore.certificateLabels");
116 try {
117 filterSubject = filterSubject ? filterSubject : "";
118 filterIssuer = filterIssuer ? filterIssuer : "";
119
120 if (hwc.isWindowsMobile()) {
121 response = hwc.getDataFromContainer("certificatestore", "&command=certificateLabels" +
122 "&filterSubject=" + encodeURIComponent(filterSubject) + "&filterIssuer=" + encodeURIComponent(filterIssuer));
123 }
124 else if (hwc.isBlackBerry()) {
125 response = _HWC.getCertificateLabels(filterSubject, filterIssuer);
126 }
127 else {
128 throw "Not supported on this platform";
129 }
130
131 return eval('(' + response + ')');
132 } finally {
133 hwc.traceLeavingMethod("hwc.CertificateStore.certificateLabels");
134 }
135 };
136
137 /**
138 * Returns a certificate without the signedCertificate part set.
139 * @feature Certificate
140 * @public
141 * @memberOf hwc.CertificateStore
142 * @return {hwc.CertificateStore} a certificate without the signedCertificate part set
143 */
144 hwc.CertificateStore.getDefault = function() {
145 return new hwc.CertificateStore();
146 };
147
148 /**
149 * Returns a certificate without the signedCertificate part set.
150 *
151 * <b> Supported Platforms </b>: Windows Mobile and BlackBerry.
152 * @feature Certificate
153 * @public
154 * @memberOf hwc.CertificateStore
155 * @param {String} label label of the desired certificate
156 * @return certificate object
157 * @example
158 * // The following script gets the certificate data for the first
159 * // certificate to match the provided subject and issuer
160 * var certStore = CertificateStore.getDefault();
161 * var labels = certStore.certificateLabels("MyUser", "mydomain.com");
162 * var cert = certStore.getPublicCertificate(labels[0]);
163 */
164 hwc.CertificateStore.prototype.getPublicCertificate = function(label) {
165 var response = "";
166
167 hwc.traceEnteringMethod("hwc.CertificateStore.getPublicCertificate");
168 try {
169 if (hwc.isWindowsMobile()) {
170 response = hwc.getDataFromContainer("certificatestore", "&command=getPublicCertificate" +
171 "&label=" + encodeURIComponent(label));
172 }
173 else if (hwc.isBlackBerry()) {
174 response = _HWC.getPublicCertificate(label);
175 }
176 else {
177 throw "Not supported on this platform";
178 }
179
180 return createCert(response);
181 } finally {
182 hwc.traceLeavingMethod("hwc.CertificateStore.getPublicCertificate");
183 }
184 };
185
186
187 /**
188 * Returns the certificate with the specified label, and decrypts it if necessary using the specified password,
189 * or returns null if the certificate is encrypted and the password is incorrect.
190 *
191 * <b>Supported Platforms</b>: Windows Mobile and BlackBerry
192 * @feature Certificate
193 *
194 * @public
195 * @memberOf hwc.CertificateStore
196 * @param {String} label label of the desired certificate
197 * @param {String} password Access password for the private key of the certificate. Pass null unless the platform requires a password.
198 * @return Certificate object
199 * @example
200 * // The following script gets the signed certificate data for the first
201 * // certificate to match the provided subject and issuer
202 * var certStore = CertificateStore.getDefault();
203 * var labels = certStore.certificateLabels("MyUser", mydomain.com");
204 * var cert = certStore.getSignedCertificate(labels[0]);
205 *
206 * var username = cert.subjectCN;
207 * var password = cert.signedCertificate;
208 */
209 hwc.CertificateStore.prototype.getSignedCertificate = function(label, password) {
210 var response = "";
211
212 hwc.traceEnteringMethod("hwc.CertificateStore.getSignedCertificate");
213 try {
214 if (hwc.isWindowsMobile()) {
215 response = hwc.getDataFromContainer("certificatestore", "&command=getSignedCertificate" +
216 "&label=" + encodeURIComponent(label));
217 } else if (hwc.isBlackBerry()) {
218 response = _HWC.getSignedCertificate(label);
219 } else {
220 throw "Not supported on this platform";
221 }
222
223 return createCert(response);
224 } finally {
225 hwc.traceLeavingMethod("hwc.CertificateStore.getSignedCertificate");
226 }
227 };
228
229 /**
230 * Returns a list of full path names for the certificate files found in the
231 * file system for import.
232 *
233 * <b>Supported Platforms</b>: Android
234 * @feature Certificate
235 * @memberOf hwc.CertificateStore
236 * @public
237 * @param {String} sFolder Folder in which to search for files. This should be a full
238 * absolute path, based on the root of the device file system. The
239 * separator may be either "/" or "\". For example, "\sdcard\mycerts"
240 * or "/sdcard/mycerts" is acceptable. Do not include any http
241 * prefixes, such as "file:".
242 * @param {String} sFileExtension File extension to which the list should be
243 * restricted. Pass the string expected after the "." in the file
244 * name. For example, to match *.p12, pass "p12" as the argument.
245 * Pass null to return all files in the folder.
246 * @return {String[]} A list of Strings, each String being the full path name of a
247 * matched file in the given folder.
248 * @example
249 * // The following script gets an array of file paths for files on
250 * // the sdcard with the extension p12
251 * var certStore = CertificateStore.getDefault();
252 * var certPaths = certStore.listAvailableCertificatesFromFileSystem("/sdcard/", "p12");
253 */
254 hwc.CertificateStore.prototype.listAvailableCertificatesFromFileSystem = function(sFolder, sFileExtension) {
255 var response = "";
256
257 hwc.traceEnteringMethod("hwc.CertificateStore.listAvailableCertificatesFromFileSystem");
258 try {
259 if (hwc.isAndroid()) {
260 response = _HWC.listAvailableCertificatesFromFileSystem(sFolder, sFileExtension);
261 } else {
262 throw "Not supported on this platform";
263 }
264
265 return eval('(' + response + ')');
266 } finally {
267 hwc.traceLeavingMethod("hwc.CertificateStore.listAvailableCertificatesFromFileSystem");
268 }
269 };
270
271 /**
272 * Gets a certificate from a file.
273 *
274 * <b>Supported Platforms</b>: Android
275 * @feature Certificate
276 * @public
277 * @memberOf hwc.CertificateStore
278 * @param {String} filePath The absolute path to the file.
279 * @param {String} password The password needed to access the certificate's private data.
280 * @example
281 * // The following script gets the signed certificate data for the first
282 * // p12 file found on the sdcard
283 * var certStore = CertificateStore.getDefault();
284 * var certPaths = certStore.listAvailableCertificatesFromFileSystem("/sdcard/", "p12");
285 * var cert = certStore.getSignedCertificateFromFile(certPaths[0], "password");
286 */
287 hwc.CertificateStore.prototype.getSignedCertificateFromFile = function(filePath, password) {
288 var response = "";
289
290 hwc.traceEnteringMethod("hwc.CertificateStore.getSignedCertificateFromFile");
291 try {
292 if (hwc.isAndroid()) {
293 response = _HWC.getSignedCertificateFromFile(filePath, password);
294 } else if (hwc.isIOS()) {
295 response = hwc.getDataFromContainer("certificatestore", "&command=getSignedCertificateFromFile" +
296 "&filePath=" + encodeURIComponent(filePath) + "&password=" + encodeURIComponent(password));
297 }
298 else {
299 throw "Not supported on this platform";
300 }
301
302 return createCert(response);
303 } finally {
304 hwc.traceLeavingMethod("hwc.CertificateStore.getSignedCertificateFromFile");
305 }
306 };
307
308
309 /**
310 * Gets a certificate from the server.
311 *
312 * <b>Supported Platforms</b>: iOS
313 * @feature Certificate
314 * @public
315 * @memberOf hwc.CertificateStore
316 * @param {String} username The username for the Windows user (in the form "DOMAIN\\username")
317 * @param {String} serverPassword The password for the Windows user
318 * @param {String} certPassword The password needed to access the certificate (may be the same or different from the Windows password)
319 * @example
320 * // The following script gets the signed certificate data for the
321 * // user MYDOMAIN\MYUSERNAME from the server
322 * var certStore = CertificateStore.getDefault();
323 * cert = certStore.getSignedCertificateFromServer("MYDOMAIN\\MYUSERNAME", "myserverpassword", "mycertpassword");
324 */
325 hwc.CertificateStore.prototype.getSignedCertificateFromServer = function(username, serverPassword, certPassword) {
326 var response = "";
327
328 hwc.traceEnteringMethod("hwc.CertificateStore.getSignedCertificateFromServer");
329 try {
330 if (hwc.isIOS()) {
331 response = hwc.getDataFromContainer("certificatestore", "&command=getSignedCertificateFromServer" +
332 "&username=" + encodeURIComponent(username) + "&serverPassword=" + encodeURIComponent(serverPassword) +
333 "&certPassword=" + encodeURIComponent(certPassword));
334 } else {
335 throw "Not supported on this platform";
336 }
337
338 return eval('(' + response + ')');
339 } finally {
340 hwc.traceLeavingMethod("hwc.CertificateStore.getSignedCertificateFromServer");
341 }
342 };
343
344 /**
345 * Gets a certificate from the Afaria server.
346 * To retrieve an x509 certificate from Afaria, you must get a CertificateStore and then call getSignedCertificateFromAfaria. If Afaria is installed and configured on the device, this gets the Afaria seeding file from the Afaria server.
347 * If the seeding file is retrieved from the Afaria server, the user is prompted to update user specific information in the Settings screen.
348 *
349 * <b>Supported Platforms</b>: iOS, Android & BlackBerry
350 * @feature Certificate
351 * @public
352 * @memberOf hwc.CertificateStore
353 * @param {String} commonName Common name used to generate the certificate by Afaria
354 * @param {String} challengeCode Challenge code for the user so that CA can verify and sign it
355 * @return JSON object with CertBlob in Base64 encoded format and other information about certificate
356 * @throws If called on a platform that is not supported.
357 * @example
358 * // The following script gets a signed certificate from the Afaria server.
359 * var certStore = CertificateStore.getDefault();
360 * cert = certStore.getSignedCertificateFromAfaria("Your_CN", "CA_challenge_code");
361 */
362 hwc.CertificateStore.prototype.getSignedCertificateFromAfaria = function(commonName, challengeCode) {
363 var response = "";
364
365 hwc.traceEnteringMethod("hwc.CertificateStore.getSignedCertificateFromAfaria");
366 try {
367 if (hwc.isIOS()) {
368 response = hwc.getDataFromContainer("certificatestore", "&command=getSignedCertificateFromAfaria" +
369 "&commonname=" + encodeURIComponent(commonName) + "&challengecode=" + encodeURIComponent(challengeCode));
370 } else if (hwc.isAndroid() || hwc.isBlackBerry()) {
371 response = _HWC.getSignedCertificateFromAfaria(commonName, challengeCode);
372 }
373 else {
374 throw "Not supported on this platform";
375 }
376
377 return eval('(' + response + ')');
378 } finally {
379 hwc.traceLeavingMethod("hwc.CertificateStore.getSignedCertificateFromAfaria");
380 }
381 };
382 } ());
383
384 })(hwc, window);
385