@breakside/jskit 2024.34.0 → 2024.41.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Frameworks/DOM.jsframework/Info.json +2 -2
- package/Frameworks/DOM.jsframework/io.breakside.JSKit.DOM-bundle.js +2 -2
- package/Frameworks/FontKit.jsframework/Info.json +2 -2
- package/Frameworks/FontKit.jsframework/io.breakside.JSKit.FontKit-bundle.js +2 -2
- package/Frameworks/Foundation.jsframework/Info.json +2 -2
- package/Frameworks/Foundation.jsframework/JS/Foundation+HTML.js +3 -1
- package/Frameworks/Foundation.jsframework/JS/JSClass.js +4 -1
- package/Frameworks/Foundation.jsframework/JS/JSHTMLUserAgent.js +130 -0
- package/Frameworks/Foundation.jsframework/JS/JSNodeURLSessionStreamTask.js +1 -1
- package/Frameworks/Foundation.jsframework/io.breakside.JSKit.Foundation-bundle.js +2 -2
- package/Frameworks/Foundation.jsframework/sources.json +3 -1
- package/Frameworks/SecurityKit.jsframework/Info.json +2 -2
- package/Frameworks/SecurityKit.jsframework/JS/SECCBOR.js +4 -0
- package/Frameworks/SecurityKit.jsframework/JS/SECCOSE.js +135 -0
- package/Frameworks/SecurityKit.jsframework/JS/SECCipher+HTML.js +231 -70
- package/Frameworks/SecurityKit.jsframework/JS/SECCipher+Node.js +155 -60
- package/Frameworks/SecurityKit.jsframework/JS/SECCipher.js +125 -54
- package/Frameworks/SecurityKit.jsframework/JS/SECDataKey.js +5 -4
- package/Frameworks/SecurityKit.jsframework/JS/SECHMAC+HTML.js +15 -11
- package/Frameworks/SecurityKit.jsframework/JS/SECHMAC+Node.js +17 -3
- package/Frameworks/SecurityKit.jsframework/JS/SECHTMLDeviceAuthentication.js +206 -120
- package/Frameworks/SecurityKit.jsframework/JS/SECHTMLKey.js +17 -0
- package/Frameworks/SecurityKit.jsframework/JS/SECHash.js +1 -0
- package/Frameworks/SecurityKit.jsframework/JS/SECJSONWebAlgorithms.js +9 -1
- package/Frameworks/SecurityKit.jsframework/JS/SECJSONWebEncryption.js +391 -0
- package/Frameworks/SecurityKit.jsframework/JS/SECJSONWebToken.js +1 -1
- package/Frameworks/SecurityKit.jsframework/JS/SECKey.js +14 -1
- package/Frameworks/SecurityKit.jsframework/JS/SECNodeKey.js +66 -1
- package/Frameworks/SecurityKit.jsframework/JS/SECSign+HTML.js +2 -27
- package/Frameworks/SecurityKit.jsframework/JS/SECSign+Node.js +103 -278
- package/Frameworks/SecurityKit.jsframework/JS/SECSign.js +27 -0
- package/Frameworks/SecurityKit.jsframework/JS/SECVerify+Node.js +60 -57
- package/Frameworks/SecurityKit.jsframework/JS/SecurityKit.js +1 -0
- package/Frameworks/SecurityKit.jsframework/io.breakside.JSKit.SecurityKit-bundle.js +2 -2
- package/Frameworks/SecurityKit.jsframework/sources.json +6 -0
- package/Info.json +2 -2
- package/Node/KeyCommand.js +8 -1
- package/Node/io.breakside.jskit-bundle.js +2 -2
- package/Node/jskit +1 -0
- package/Root/Frameworks/APIKit/Info.yaml +1 -1
- package/Root/Frameworks/APIKitTesting/Info.yaml +1 -1
- package/Root/Frameworks/AuthKit/Info.yaml +1 -1
- package/Root/Frameworks/CSSOM/Info.yaml +1 -1
- package/Root/Frameworks/ChartKit/Info.yaml +1 -1
- package/Root/Frameworks/ConferenceKit/Info.yaml +1 -1
- package/Root/Frameworks/DBKit/DBEncryptedObject.js +2 -2
- package/Root/Frameworks/DBKit/Info.yaml +1 -1
- package/Root/Frameworks/DOM/Info.yaml +1 -1
- package/Root/Frameworks/Dispatch/Info.yaml +1 -1
- package/Root/Frameworks/FontKit/Info.yaml +1 -1
- package/Root/Frameworks/Foundation/Foundation+HTML.js +3 -1
- package/Root/Frameworks/Foundation/Info.yaml +1 -1
- package/Root/Frameworks/Foundation/JSClass.js +4 -1
- package/Root/Frameworks/Foundation/JSHTMLUserAgent.js +130 -0
- package/Root/Frameworks/Foundation/JSNodeURLSessionStreamTask.js +1 -1
- package/Root/Frameworks/ImageKit/Info.yaml +1 -1
- package/Root/Frameworks/MediaKit/Info.yaml +1 -1
- package/Root/Frameworks/MediaKitUI/Info.yaml +1 -1
- package/Root/Frameworks/NotificationKit/Info.yaml +1 -1
- package/Root/Frameworks/NotificationKit/NKWebPushService.js +2 -2
- package/Root/Frameworks/PDFKit/Info.yaml +1 -1
- package/Root/Frameworks/PDFKit/PDFEncryption.js +1 -1
- package/Root/Frameworks/QRKit/Info.yaml +1 -1
- package/Root/Frameworks/SearchKit/Info.yaml +1 -1
- package/Root/Frameworks/SecurityKit/Info.yaml +1 -1
- package/Root/Frameworks/SecurityKit/SECCBOR.js +4 -0
- package/Root/Frameworks/SecurityKit/SECCOSE.js +135 -0
- package/Root/Frameworks/SecurityKit/SECCipher+HTML.js +231 -70
- package/Root/Frameworks/SecurityKit/SECCipher+Node.js +155 -60
- package/Root/Frameworks/SecurityKit/SECCipher.js +125 -54
- package/Root/Frameworks/SecurityKit/SECDataKey.js +5 -4
- package/Root/Frameworks/SecurityKit/SECHMAC+HTML.js +15 -11
- package/Root/Frameworks/SecurityKit/SECHMAC+Node.js +17 -3
- package/Root/Frameworks/SecurityKit/SECHTMLDeviceAuthentication.js +206 -120
- package/Root/Frameworks/SecurityKit/SECHTMLKey.js +17 -0
- package/Root/Frameworks/SecurityKit/SECHash.js +1 -0
- package/Root/Frameworks/SecurityKit/SECJSONWebAlgorithms.js +9 -1
- package/Root/Frameworks/SecurityKit/SECJSONWebEncryption.js +391 -0
- package/Root/Frameworks/SecurityKit/SECJSONWebToken.js +1 -1
- package/Root/Frameworks/SecurityKit/SECKey.js +14 -1
- package/Root/Frameworks/SecurityKit/SECNodeKey.js +66 -1
- package/Root/Frameworks/SecurityKit/SECSign+HTML.js +2 -27
- package/Root/Frameworks/SecurityKit/SECSign+Node.js +103 -278
- package/Root/Frameworks/SecurityKit/SECSign.js +27 -0
- package/Root/Frameworks/SecurityKit/SECVerify+Node.js +60 -57
- package/Root/Frameworks/SecurityKit/SecurityKit.js +1 -0
- package/Root/Frameworks/ServerKit/Info.yaml +1 -1
- package/Root/Frameworks/ServerKitTesting/Info.yaml +1 -1
- package/Root/Frameworks/TestKit/Info.yaml +1 -1
- package/Root/Frameworks/UIKit/Info.yaml +1 -1
- package/Root/Frameworks/UIKit/UIPlatform+HTML.js +2 -1
- package/Root/Frameworks/UIKitTesting/Info.yaml +1 -1
- package/package.json +1 -1
- package/Root/Templates/workspace/.gitignore +0 -4
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
// #import "SECCipher.js"
|
|
18
18
|
// #import "SECHTMLKey.js"
|
|
19
19
|
// #import "SECHash.js"
|
|
20
|
+
// #import "SECASN1Parser.js"
|
|
20
21
|
// #feature window.crypto.subtle
|
|
21
22
|
// jshint browser: true
|
|
22
23
|
/* global crypto */
|
|
@@ -44,7 +45,13 @@ var HTMLCryptoAlgorithmNames = {
|
|
|
44
45
|
}
|
|
45
46
|
};
|
|
46
47
|
|
|
47
|
-
|
|
48
|
+
var HTMLHashAlgorithms = {};
|
|
49
|
+
HTMLHashAlgorithms[SECHash.Algorithm.sha1] = 'SHA-1';
|
|
50
|
+
HTMLHashAlgorithms[SECHash.Algorithm.sha256] = 'SHA-256';
|
|
51
|
+
HTMLHashAlgorithms[SECHash.Algorithm.sha384] = 'SHA-384';
|
|
52
|
+
HTMLHashAlgorithms[SECHash.Algorithm.sha512] = 'SHA-512';
|
|
53
|
+
|
|
54
|
+
SECCipherAES.definePropertiesFromExtensions({
|
|
48
55
|
|
|
49
56
|
htmlAlgorithmName: null,
|
|
50
57
|
|
|
@@ -58,7 +65,9 @@ SECCipher.definePropertiesFromExtensions({
|
|
|
58
65
|
};
|
|
59
66
|
var extractable = true;
|
|
60
67
|
crypto.subtle.generateKey(algorithm, extractable, ["encrypt", "decrypt", "wrapKey", "unwrapKey"]).then(function(htmlKey){
|
|
61
|
-
|
|
68
|
+
var key = SECHTMLKey.initWithKey(htmlKey);
|
|
69
|
+
key.id = JSSHA1Hash(UUID.init().bytes).base64URLStringRepresentation();
|
|
70
|
+
completion.call(target, key);
|
|
62
71
|
}, function(e){
|
|
63
72
|
completion.call(target, null);
|
|
64
73
|
});
|
|
@@ -87,30 +96,20 @@ SECCipherAESCipherBlockChaining.definePropertiesFromExtensions({
|
|
|
87
96
|
|
|
88
97
|
htmlAlgorithmName: HTMLCryptoAlgorithmNames.aesCBC,
|
|
89
98
|
|
|
90
|
-
_getHTMLEncryptAlgorithm: function(){
|
|
91
|
-
return {
|
|
92
|
-
name: HTMLCryptoAlgorithmNames.aesCBC,
|
|
93
|
-
iv: crypto.getRandomValues(JSData.initWithLength(16))
|
|
94
|
-
};
|
|
95
|
-
},
|
|
96
|
-
|
|
97
|
-
_getHTMLDecryptAlgorithm: function(prefixedData){
|
|
98
|
-
return {
|
|
99
|
-
name: HTMLCryptoAlgorithmNames.aesCBC,
|
|
100
|
-
iv: prefixedData.subdataInRange(JSRange(0, 16))
|
|
101
|
-
};
|
|
102
|
-
},
|
|
103
|
-
|
|
104
99
|
encrypt: function(data, key, completion, target){
|
|
105
100
|
if (!completion){
|
|
106
101
|
completion = Promise.completion(Promise.resolveNonNull);
|
|
107
102
|
}
|
|
108
|
-
var
|
|
103
|
+
var iv = this.iv !== null ? this.iv : this.randomIV();
|
|
104
|
+
var algorithm = {
|
|
105
|
+
name: HTMLCryptoAlgorithmNames.aesCBC,
|
|
106
|
+
iv: iv
|
|
107
|
+
};
|
|
109
108
|
crypto.subtle.encrypt(algorithm, key.htmlKey, data).then(function(encrypted){
|
|
110
109
|
// prefix the encrypted data with the random initializtion vector so
|
|
111
110
|
// it is available to the decrypt function. The iv does not need
|
|
112
111
|
// to be a secret, it just needs to be random, so prefixing does not affect security.
|
|
113
|
-
var ivPrefixed = JSData.initWithChunks([
|
|
112
|
+
var ivPrefixed = JSData.initWithChunks([iv, JSData.initWithBuffer(encrypted)]);
|
|
114
113
|
completion.call(target, ivPrefixed);
|
|
115
114
|
},function(e){
|
|
116
115
|
completion.call(target, null);
|
|
@@ -122,9 +121,13 @@ SECCipherAESCipherBlockChaining.definePropertiesFromExtensions({
|
|
|
122
121
|
if (!completion){
|
|
123
122
|
completion = Promise.completion(Promise.resolveNonNull);
|
|
124
123
|
}
|
|
125
|
-
var
|
|
126
|
-
var
|
|
127
|
-
|
|
124
|
+
var iv = data.subdataInRange(JSRange(0, this.ivByteLength));
|
|
125
|
+
var ciphertext = data.subdataInRange(JSRange(this.ivByteLength, data.length - this.ivByteLength));
|
|
126
|
+
var algorithm = {
|
|
127
|
+
name: HTMLCryptoAlgorithmNames.aesCBC,
|
|
128
|
+
iv: iv
|
|
129
|
+
};
|
|
130
|
+
crypto.subtle.decrypt(algorithm, key.htmlKey, ciphertext).then(function(decrypted){
|
|
128
131
|
var decryptedData = JSData.initWithBuffer(decrypted);
|
|
129
132
|
completion.call(target, decryptedData);
|
|
130
133
|
}, function(e){
|
|
@@ -137,9 +140,13 @@ SECCipherAESCipherBlockChaining.definePropertiesFromExtensions({
|
|
|
137
140
|
if (!completion){
|
|
138
141
|
completion = Promise.completion(Promise.resolveNonNull);
|
|
139
142
|
}
|
|
140
|
-
var
|
|
143
|
+
var iv = this.iv !== null ? this.iv : this.randomIV();
|
|
144
|
+
var algorithm = {
|
|
145
|
+
name: HTMLCryptoAlgorithmNames.aesCBC,
|
|
146
|
+
iv: iv
|
|
147
|
+
};
|
|
141
148
|
crypto.subtle.wrapKey("raw", key.htmlKey, wrappingKey.htmlKey, algorithm).then(function(bytes){
|
|
142
|
-
var ivPrefixed = JSData.initWithChunks([
|
|
149
|
+
var ivPrefixed = JSData.initWithChunks([iv, JSData.initWithBuffer(bytes)]);
|
|
143
150
|
completion.call(target, ivPrefixed);
|
|
144
151
|
}, function(e){
|
|
145
152
|
completion.call(target, null);
|
|
@@ -151,10 +158,14 @@ SECCipherAESCipherBlockChaining.definePropertiesFromExtensions({
|
|
|
151
158
|
if (!completion){
|
|
152
159
|
completion = Promise.completion(Promise.resolveNonNull);
|
|
153
160
|
}
|
|
154
|
-
var
|
|
161
|
+
var iv = wrappedKeyData.subdataInRange(JSRange(0, this.ivByteLength));
|
|
162
|
+
var ciphertext = wrappedKeyData.subdataInRange(JSRange(16, wrappedKeyData.length - 16));
|
|
163
|
+
var algorithm = {
|
|
164
|
+
name: HTMLCryptoAlgorithmNames.aesCBC,
|
|
165
|
+
iv: iv
|
|
166
|
+
};
|
|
155
167
|
var unwrappedKeyHTMLAlgorithm = HTMLCryptoAlgorithmNames.fromAlgorithm(unwrappedKeyAlgorithm);
|
|
156
|
-
|
|
157
|
-
crypto.subtle.unwrapKey("raw", wrappedKeyData, wrappingKey.htmlKey, algorithm, unwrappedKeyHTMLAlgorithm, true, ["encrypt", "decrypt"]).then(function(key){
|
|
168
|
+
crypto.subtle.unwrapKey("raw", ciphertext, wrappingKey.htmlKey, algorithm, unwrappedKeyHTMLAlgorithm, true, ["encrypt", "decrypt"]).then(function(key){
|
|
158
169
|
completion.call(target, SECHTMLKey.initWithKey(key));
|
|
159
170
|
}, function(e){
|
|
160
171
|
completion.call(target, null);
|
|
@@ -274,57 +285,202 @@ SECCipherAESGaloisCounterMode.definePropertiesFromExtensions({
|
|
|
274
285
|
|
|
275
286
|
htmlAlgorithmName: HTMLCryptoAlgorithmNames.aesGCM,
|
|
276
287
|
|
|
277
|
-
|
|
278
|
-
if (
|
|
279
|
-
|
|
288
|
+
encrypt: function(data, key, completion, target){
|
|
289
|
+
if (!completion){
|
|
290
|
+
completion = Promise.completion(Promise.resolveNonNull);
|
|
280
291
|
}
|
|
292
|
+
var iv = this.iv !== null ? this.iv : this.randomIV();
|
|
281
293
|
var algorithm = {
|
|
282
294
|
name: HTMLCryptoAlgorithmNames.aesGCM,
|
|
283
|
-
iv:
|
|
284
|
-
tagLength:
|
|
295
|
+
iv: iv,
|
|
296
|
+
tagLength: this.tagByteLength << 3
|
|
285
297
|
};
|
|
286
|
-
|
|
287
|
-
|
|
298
|
+
if (this.additionalData !== null){
|
|
299
|
+
algorithm.additionalData = this.additionalData;
|
|
300
|
+
}
|
|
301
|
+
crypto.subtle.encrypt(algorithm, key.htmlKey, data).then(function(encrypted){
|
|
302
|
+
var ivPrefixed = JSData.initWithChunks([iv, JSData.initWithBuffer(encrypted)]);
|
|
303
|
+
completion.call(target, ivPrefixed);
|
|
304
|
+
},function(e){
|
|
305
|
+
completion.call(target, null);
|
|
306
|
+
});
|
|
307
|
+
return completion.promise;
|
|
288
308
|
},
|
|
289
309
|
|
|
290
|
-
|
|
291
|
-
if (
|
|
292
|
-
|
|
310
|
+
decrypt: function(data, key, completion, target){
|
|
311
|
+
if (!completion){
|
|
312
|
+
completion = Promise.completion(Promise.resolveNonNull);
|
|
293
313
|
}
|
|
294
|
-
|
|
295
|
-
|
|
314
|
+
var iv = data.subdataInRange(JSRange(0, this.ivByteLength));
|
|
315
|
+
var ciphertext = data.subdataInRange(JSRange(this.ivByteLength, data.length - this.ivByteLength));
|
|
316
|
+
var algorithm = {
|
|
317
|
+
name: HTMLCryptoAlgorithmNames.aesGCM,
|
|
318
|
+
iv: iv,
|
|
319
|
+
tagLength: this.tagByteLength << 3
|
|
320
|
+
};
|
|
321
|
+
if (this.additionalData !== null){
|
|
322
|
+
algorithm.additionalData = this.additionalData;
|
|
323
|
+
}
|
|
324
|
+
crypto.subtle.decrypt(algorithm, key.htmlKey, ciphertext).then(function(decrypted){
|
|
325
|
+
var decryptedData = JSData.initWithBuffer(decrypted);
|
|
326
|
+
completion.call(target, decryptedData);
|
|
327
|
+
}, function(error){
|
|
328
|
+
completion.call(target, null);
|
|
329
|
+
});
|
|
330
|
+
return completion.promise;
|
|
331
|
+
},
|
|
332
|
+
|
|
333
|
+
wrapKey: function(key, wrappingKey, completion, target){
|
|
334
|
+
if (!completion){
|
|
335
|
+
completion = Promise.completion(Promise.resolveNonNull);
|
|
296
336
|
}
|
|
297
|
-
var
|
|
337
|
+
var iv = this.iv !== null ? this.iv : this.randomIV();
|
|
298
338
|
var algorithm = {
|
|
299
339
|
name: HTMLCryptoAlgorithmNames.aesGCM,
|
|
300
|
-
iv:
|
|
301
|
-
tagLength:
|
|
340
|
+
iv: iv,
|
|
341
|
+
tagLength: this.tagByteLength << 3
|
|
302
342
|
};
|
|
303
|
-
|
|
304
|
-
|
|
343
|
+
crypto.subtle.wrapKey("raw", key.htmlKey, wrappingKey.htmlKey, algorithm).then(function(bytes){
|
|
344
|
+
var ivPrefixed = JSData.initWithChunks([iv, JSData.initWithBuffer(bytes)]);
|
|
345
|
+
completion.call(target, ivPrefixed);
|
|
346
|
+
}, function(e){
|
|
347
|
+
completion.call(target, null);
|
|
348
|
+
});
|
|
349
|
+
return completion.promise;
|
|
350
|
+
},
|
|
351
|
+
|
|
352
|
+
unwrapKey: function(wrappedKeyData, unwrappedKeyAlgorithm, wrappingKey, completion, target){
|
|
353
|
+
if (!completion){
|
|
354
|
+
completion = Promise.completion(Promise.resolveNonNull);
|
|
355
|
+
}
|
|
356
|
+
var iv = wrappedKeyData.subdataInRange(JSRange(0, this.ivByteLength));
|
|
357
|
+
var ciphertext = wrappedKeyData.subdataInRange(JSRange(this.ivByteLength, wrappedKeyData.length - this.ivByteLength));
|
|
358
|
+
var algorithm = {
|
|
359
|
+
name: HTMLCryptoAlgorithmNames.aesGCM,
|
|
360
|
+
iv: iv,
|
|
361
|
+
tagLength: this.tagByteLength << 3
|
|
362
|
+
};
|
|
363
|
+
var unwrappedKeyHTMLAlgorithm = HTMLCryptoAlgorithmNames.fromAlgorithm(unwrappedKeyAlgorithm);
|
|
364
|
+
crypto.subtle.unwrapKey("raw", ciphertext, wrappingKey.htmlKey, algorithm, unwrappedKeyHTMLAlgorithm, true, ["encrypt", "decrypt"]).then(function(key){
|
|
365
|
+
completion.call(target, SECHTMLKey.initWithKey(key));
|
|
366
|
+
}, function(e){
|
|
367
|
+
completion.call(target, null);
|
|
368
|
+
});
|
|
369
|
+
return completion.promise;
|
|
370
|
+
}
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
SECCipherRSAOAEP.definePropertiesFromExtensions({
|
|
374
|
+
|
|
375
|
+
createKey: function(completion, target){
|
|
376
|
+
if (!completion){
|
|
377
|
+
completion = Promise.completion(Promise.resolveNonNull);
|
|
378
|
+
}
|
|
379
|
+
var algorithm = {
|
|
380
|
+
name: "RSA-OAEP",
|
|
381
|
+
modulusLength: this.modulusLength,
|
|
382
|
+
publicExponent: bigIntegerFromNumber(this.publicExponent),
|
|
383
|
+
hash: HTMLHashAlgorithms[this.hash]
|
|
384
|
+
};
|
|
385
|
+
crypto.subtle.generateKey(algorithm, true, ["encrypt", "decrypt", "wrapKey", "unwrapKey"]).then(function(htmlPair){
|
|
386
|
+
var privateKey = SECHTMLKey.initWithKey(htmlPair.privateKey);
|
|
387
|
+
privateKey.publicKey = SECHTMLKey.initWithKey(htmlPair.publicKey);
|
|
388
|
+
privateKey.id = privateKey.publicKey.id = JSSHA1Hash(UUID.init().bytes).base64URLStringRepresentation();
|
|
389
|
+
completion.call(target, privateKey);
|
|
390
|
+
}, function(e){
|
|
391
|
+
completion.call(target, null);
|
|
392
|
+
});
|
|
393
|
+
return completion.promise;
|
|
394
|
+
},
|
|
395
|
+
|
|
396
|
+
createKeyFromJWK: function(jwk, completion, target){
|
|
397
|
+
if (!completion){
|
|
398
|
+
completion = Promise.completion(Promise.resolveNonNull);
|
|
399
|
+
}
|
|
400
|
+
var algorithm = {
|
|
401
|
+
name: "RSA-OAEP",
|
|
402
|
+
hash: HTMLHashAlgorithms[this.hash]
|
|
403
|
+
};
|
|
404
|
+
var usages = jwk.d ? ["decrypt", "unwrapKey"] : ["encrypt", "wrapKey"];
|
|
405
|
+
crypto.subtle.importKey("jwk", jwk, algorithm, true, usages).then(function(htmlKey){
|
|
406
|
+
var key = SECHTMLKey.initWithKey(htmlKey);
|
|
407
|
+
key.id = jwk.kid || null;
|
|
408
|
+
completion.call(target, key);
|
|
409
|
+
}, function(e){
|
|
410
|
+
completion.call(target, null);
|
|
411
|
+
});
|
|
412
|
+
return completion.promise;
|
|
413
|
+
},
|
|
414
|
+
|
|
415
|
+
createKeyWithData: function(data, completion, target){
|
|
416
|
+
if (!completion){
|
|
417
|
+
completion = Promise.completion(Promise.resolveNonNull);
|
|
418
|
+
}
|
|
419
|
+
var algorithm = {
|
|
420
|
+
name: "RSA-OAEP",
|
|
421
|
+
hash: HTMLHashAlgorithms[this.hash]
|
|
422
|
+
};
|
|
423
|
+
var usages;
|
|
424
|
+
var parser;
|
|
425
|
+
try{
|
|
426
|
+
parser = SECASN1Parser.initWithPEM(data, "RSA PRIVATE KEY");
|
|
427
|
+
data = parser.der;
|
|
428
|
+
usages = ["decrypt", "unwrapKey"];
|
|
429
|
+
}catch (e){
|
|
430
|
+
try {
|
|
431
|
+
parser = SECASN1Parser.initWithPEM(data, "RSA PUBLIC KEY");
|
|
432
|
+
data = parser.der;
|
|
433
|
+
usages = ["encrypt", "wrapKey"];
|
|
434
|
+
}catch (e){
|
|
435
|
+
// assume data was already DER
|
|
436
|
+
parser = SECASN1Parser.initWithDER(data);
|
|
437
|
+
var sequence = parser.parse;
|
|
438
|
+
if (sequence.length > 2){
|
|
439
|
+
usages = ["decrypt", "unwrapKey"];
|
|
440
|
+
}else{
|
|
441
|
+
usages = ["encrypt", "wrapKey"];
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
crypto.subtle.importKey("pkcs8", data, algorithm, true, usages).then(function(htmlKey){
|
|
446
|
+
var key = SECHTMLKey.initWithKey(htmlKey);
|
|
447
|
+
completion.call(target, key);
|
|
448
|
+
}, function(e){
|
|
449
|
+
completion.call(target, null);
|
|
450
|
+
});
|
|
451
|
+
return completion.promise;
|
|
305
452
|
},
|
|
306
453
|
|
|
307
|
-
|
|
454
|
+
encrypt: function(data, key, completion, target){
|
|
308
455
|
if (!completion){
|
|
309
456
|
completion = Promise.completion(Promise.resolveNonNull);
|
|
310
457
|
}
|
|
311
|
-
var algorithm =
|
|
458
|
+
var algorithm = {
|
|
459
|
+
name: "RSA-OAEP"
|
|
460
|
+
};
|
|
461
|
+
if (this.label !== null){
|
|
462
|
+
algorithm.label = this.label;
|
|
463
|
+
}
|
|
312
464
|
crypto.subtle.encrypt(algorithm, key.htmlKey, data).then(function(encrypted){
|
|
313
|
-
var
|
|
314
|
-
completion.call(target,
|
|
465
|
+
var encryptedData = JSData.initWithBuffer(encrypted);
|
|
466
|
+
completion.call(target, encryptedData);
|
|
315
467
|
},function(e){
|
|
316
468
|
completion.call(target, null);
|
|
317
469
|
});
|
|
318
470
|
return completion.promise;
|
|
319
471
|
},
|
|
320
472
|
|
|
321
|
-
|
|
473
|
+
decrypt: function(data, key, completion, target){
|
|
322
474
|
if (!completion){
|
|
323
475
|
completion = Promise.completion(Promise.resolveNonNull);
|
|
324
476
|
}
|
|
325
|
-
var algorithm =
|
|
326
|
-
|
|
327
|
-
|
|
477
|
+
var algorithm = {
|
|
478
|
+
name: "RSA-OAEP"
|
|
479
|
+
};
|
|
480
|
+
if (this.label !== null){
|
|
481
|
+
algorithm.label = this.label;
|
|
482
|
+
}
|
|
483
|
+
crypto.subtle.decrypt(algorithm, key.htmlKey, data).then(function(decrypted){
|
|
328
484
|
var decryptedData = JSData.initWithBuffer(decrypted);
|
|
329
485
|
completion.call(target, decryptedData);
|
|
330
486
|
}, function(error){
|
|
@@ -337,24 +493,15 @@ SECCipherAESGaloisCounterMode.definePropertiesFromExtensions({
|
|
|
337
493
|
if (!completion){
|
|
338
494
|
completion = Promise.completion(Promise.resolveNonNull);
|
|
339
495
|
}
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
496
|
+
var algorithm = {
|
|
497
|
+
name: "RSA-OAEP"
|
|
498
|
+
};
|
|
499
|
+
if (this.label !== null){
|
|
500
|
+
algorithm.label = this.label;
|
|
343
501
|
}
|
|
344
|
-
var nonce = JSData.initWithArray([
|
|
345
|
-
1,
|
|
346
|
-
((this.encryptedMessageId / 0x100000000) >> 16) & 0xFF,
|
|
347
|
-
((this.encryptedMessageId / 0x100000000) >> 8) & 0xFF,
|
|
348
|
-
(this.encryptedMessageId / 0x100000000) & 0xFF,
|
|
349
|
-
(this.encryptedMessageId >> 24) & 0xFF,
|
|
350
|
-
(this.encryptedMessageId >> 16) & 0xFF,
|
|
351
|
-
(this.encryptedMessageId >> 8) & 0xFF,
|
|
352
|
-
this.encryptedMessageId & 0xF
|
|
353
|
-
]);
|
|
354
|
-
var algorithm = this._getHTMLEncryptAlgorithm(nonce, 16);
|
|
355
502
|
crypto.subtle.wrapKey("raw", key.htmlKey, wrappingKey.htmlKey, algorithm).then(function(bytes){
|
|
356
|
-
var
|
|
357
|
-
completion.call(target,
|
|
503
|
+
var wrapped = JSData.initWithBuffer(bytes);
|
|
504
|
+
completion.call(target, wrapped);
|
|
358
505
|
}, function(e){
|
|
359
506
|
completion.call(target, null);
|
|
360
507
|
});
|
|
@@ -365,20 +512,34 @@ SECCipherAESGaloisCounterMode.definePropertiesFromExtensions({
|
|
|
365
512
|
if (!completion){
|
|
366
513
|
completion = Promise.completion(Promise.resolveNonNull);
|
|
367
514
|
}
|
|
368
|
-
var algorithm =
|
|
515
|
+
var algorithm = {
|
|
516
|
+
name: "RSA-OAEP"
|
|
517
|
+
};
|
|
518
|
+
if (this.label !== null){
|
|
519
|
+
algorithm.label = this.label;
|
|
520
|
+
}
|
|
369
521
|
var unwrappedKeyHTMLAlgorithm = HTMLCryptoAlgorithmNames.fromAlgorithm(unwrappedKeyAlgorithm);
|
|
370
|
-
wrappedKeyData = wrappedKeyData.subdataInRange(JSRange(8, wrappedKeyData.length - 8));
|
|
371
522
|
crypto.subtle.unwrapKey("raw", wrappedKeyData, wrappingKey.htmlKey, algorithm, unwrappedKeyHTMLAlgorithm, true, ["encrypt", "decrypt"]).then(function(key){
|
|
372
523
|
completion.call(target, SECHTMLKey.initWithKey(key));
|
|
373
524
|
}, function(e){
|
|
374
525
|
completion.call(target, null);
|
|
375
526
|
});
|
|
376
527
|
return completion.promise;
|
|
377
|
-
}
|
|
528
|
+
}
|
|
529
|
+
|
|
378
530
|
});
|
|
379
531
|
|
|
380
532
|
SECCipher.getRandomData = function(length){
|
|
381
533
|
return crypto.getRandomValues(JSData.initWithLength(length));
|
|
382
534
|
};
|
|
383
535
|
|
|
536
|
+
var bigIntegerFromNumber = function(n){
|
|
537
|
+
var elements = [];
|
|
538
|
+
while (n > 0){
|
|
539
|
+
elements.unshift(n & 0xFF);
|
|
540
|
+
n >>>= 8;
|
|
541
|
+
}
|
|
542
|
+
return JSData.initWithArray(elements);
|
|
543
|
+
};
|
|
544
|
+
|
|
384
545
|
})();
|