@breakside/jskit 2024.33.0 → 2024.40.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/JSClass.js +4 -1
- package/Frameworks/Foundation.jsframework/JS/JSFile.js +23 -2
- package/Frameworks/Foundation.jsframework/JS/JSHTMLFile.js +4 -0
- package/Frameworks/Foundation.jsframework/JS/JSNodeURLSessionStreamTask.js +1 -1
- package/Frameworks/Foundation.jsframework/JS/JSSynchronizer.js +11 -7
- package/Frameworks/Foundation.jsframework/io.breakside.JSKit.Foundation-bundle.js +2 -2
- package/Frameworks/SecurityKit.jsframework/Info.json +2 -2
- 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 +139 -106
- 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/Info.yaml +1 -1
- package/Root/Frameworks/Foundation/JSClass.js +4 -1
- package/Root/Frameworks/Foundation/JSFile.js +23 -2
- package/Root/Frameworks/Foundation/JSHTMLFile.js +4 -0
- package/Root/Frameworks/Foundation/JSNodeURLSessionStreamTask.js +1 -1
- package/Root/Frameworks/Foundation/JSSynchronizer.js +11 -7
- 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/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 +139 -106
- 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/UIKitTesting/Info.yaml +1 -1
- package/package.json +1 -1
- package/Root/Templates/workspace/.gitignore +0 -4
|
@@ -16,6 +16,8 @@
|
|
|
16
16
|
// #import Foundation
|
|
17
17
|
// #import "SECCipher.js"
|
|
18
18
|
// #import "SECNodeKey.js"
|
|
19
|
+
// #import "SECASN1Parser.js"
|
|
20
|
+
// #import "SECJSONWebAlgorithms.js"
|
|
19
21
|
// jshint node: true
|
|
20
22
|
'use strict';
|
|
21
23
|
|
|
@@ -27,7 +29,9 @@ SECCipher.definePropertiesFromExtensions({
|
|
|
27
29
|
if (!completion){
|
|
28
30
|
completion = Promise.completion(Promise.resolveNonNull);
|
|
29
31
|
}
|
|
30
|
-
|
|
32
|
+
key.getData(function(keyData){
|
|
33
|
+
this.encrypt(keyData, wrappingKey, completion, target);
|
|
34
|
+
}, this);
|
|
31
35
|
return completion.promise;
|
|
32
36
|
},
|
|
33
37
|
|
|
@@ -45,15 +49,21 @@ SECCipher.definePropertiesFromExtensions({
|
|
|
45
49
|
return completion.promise;
|
|
46
50
|
},
|
|
47
51
|
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
SECCipherAES.definePropertiesFromExtensions({
|
|
55
|
+
|
|
48
56
|
createKey: function(completion, target){
|
|
49
57
|
if (!completion){
|
|
50
58
|
completion = Promise.completion(Promise.resolveNonNull);
|
|
51
59
|
}
|
|
52
|
-
crypto.
|
|
60
|
+
crypto.generateKey("aes", {length: this.keyBitLength}, function(error, nodeKeyObject){
|
|
53
61
|
if (error){
|
|
54
62
|
completion.call(target, null);
|
|
55
63
|
}else{
|
|
56
|
-
|
|
64
|
+
var key = SECNodeKey.initWithNodeKeyObject(nodeKeyObject);
|
|
65
|
+
key.id = JSSHA1Hash(UUID.init().bytes).base64URLStringRepresentation();
|
|
66
|
+
completion.call(target, key);
|
|
57
67
|
}
|
|
58
68
|
});
|
|
59
69
|
return completion.promise;
|
|
@@ -71,8 +81,8 @@ SECCipher.definePropertiesFromExtensions({
|
|
|
71
81
|
|
|
72
82
|
SECCipherAESCipherBlockChaining.definePropertiesFromExtensions({
|
|
73
83
|
|
|
74
|
-
|
|
75
|
-
switch (
|
|
84
|
+
nodeCipherName: JSLazyInitProperty(function(){
|
|
85
|
+
switch (this.keyByteLength){
|
|
76
86
|
case 16:
|
|
77
87
|
return 'AES-128-CBC';
|
|
78
88
|
case 24:
|
|
@@ -81,26 +91,20 @@ SECCipherAESCipherBlockChaining.definePropertiesFromExtensions({
|
|
|
81
91
|
return 'AES-256-CBC';
|
|
82
92
|
}
|
|
83
93
|
return null;
|
|
84
|
-
},
|
|
94
|
+
}),
|
|
85
95
|
|
|
86
96
|
encrypt: function(data, key, completion, target){
|
|
87
97
|
if (!completion){
|
|
88
98
|
completion = Promise.completion(Promise.resolveNonNull);
|
|
89
99
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
return;
|
|
99
|
-
}
|
|
100
|
-
var cipher = crypto.createCipheriv(name, key.keyData, iv);
|
|
101
|
-
var chunks = [iv, cipher.update(data), cipher.final()];
|
|
102
|
-
completion.call(target, JSData.initWithChunks(chunks));
|
|
103
|
-
});
|
|
100
|
+
if (this.nodeCipherName === null){
|
|
101
|
+
JSRunLoop.main.schedule(completion, target, null);
|
|
102
|
+
return completion.promise;
|
|
103
|
+
}
|
|
104
|
+
var iv = this.iv !== null ? this.iv : this.randomIV();
|
|
105
|
+
var cipher = crypto.createCipheriv(this.nodeCipherName, key.nodeKeyObject, iv);
|
|
106
|
+
var chunks = [iv, cipher.update(data), cipher.final()];
|
|
107
|
+
JSRunLoop.main.schedule(completion, target, JSData.initWithChunks(chunks));
|
|
104
108
|
return completion.promise;
|
|
105
109
|
},
|
|
106
110
|
|
|
@@ -109,14 +113,14 @@ SECCipherAESCipherBlockChaining.definePropertiesFromExtensions({
|
|
|
109
113
|
completion = Promise.completion(Promise.resolveNonNull);
|
|
110
114
|
}
|
|
111
115
|
try{
|
|
112
|
-
|
|
113
|
-
if (name === null){
|
|
116
|
+
if (this.nodeCipherName === null){
|
|
114
117
|
JSRunLoop.main.schedule(completion, target, null);
|
|
115
118
|
return completion.promise;
|
|
116
119
|
}
|
|
117
|
-
var iv = data.subdataInRange(JSRange(0,
|
|
118
|
-
var
|
|
119
|
-
var
|
|
120
|
+
var iv = data.subdataInRange(JSRange(0, this.ivByteLength));
|
|
121
|
+
var ciphertext = data.subdataInRange(JSRange(this.ivByteLength, data.length - this.ivByteLength));
|
|
122
|
+
var cipher = crypto.createDecipheriv(this.nodeCipherName, key.nodeKeyObject, iv);
|
|
123
|
+
var chunks = [cipher.update(ciphertext), cipher.final()];
|
|
120
124
|
JSRunLoop.main.schedule(completion, target, JSData.initWithChunks(chunks));
|
|
121
125
|
}catch (e){
|
|
122
126
|
JSRunLoop.main.schedule(completion, target, null);
|
|
@@ -128,8 +132,8 @@ SECCipherAESCipherBlockChaining.definePropertiesFromExtensions({
|
|
|
128
132
|
|
|
129
133
|
SECCipherAESCounter.definePropertiesFromExtensions({
|
|
130
134
|
|
|
131
|
-
|
|
132
|
-
switch (
|
|
135
|
+
nodeCipherName: JSLazyInitProperty(function(){
|
|
136
|
+
switch (this.keyByteLength){
|
|
133
137
|
case 16:
|
|
134
138
|
return 'AES-128-CTR';
|
|
135
139
|
case 24:
|
|
@@ -138,7 +142,7 @@ SECCipherAESCounter.definePropertiesFromExtensions({
|
|
|
138
142
|
return 'AES-256-CTR';
|
|
139
143
|
}
|
|
140
144
|
return null;
|
|
141
|
-
},
|
|
145
|
+
}),
|
|
142
146
|
|
|
143
147
|
encrypt: function(data, key, completion, target){
|
|
144
148
|
if (!completion){
|
|
@@ -148,8 +152,7 @@ SECCipherAESCounter.definePropertiesFromExtensions({
|
|
|
148
152
|
JSRunLoop.main.schedule(completion, target, null);
|
|
149
153
|
return completion.promise;
|
|
150
154
|
}
|
|
151
|
-
|
|
152
|
-
if (name === null){
|
|
155
|
+
if (this.nodeCipherName === null){
|
|
153
156
|
JSRunLoop.main.schedule(completion, target, null);
|
|
154
157
|
return completion.promise;
|
|
155
158
|
}
|
|
@@ -165,7 +168,7 @@ SECCipherAESCounter.definePropertiesFromExtensions({
|
|
|
165
168
|
]);
|
|
166
169
|
var iv = JSData.initWithLength(16);
|
|
167
170
|
nonce.copyTo(iv, 0);
|
|
168
|
-
var cipher = crypto.createCipheriv(
|
|
171
|
+
var cipher = crypto.createCipheriv(this.nodeCipherName, key.nodeKeyObject, iv);
|
|
169
172
|
var chunks = [nonce, cipher.update(data), cipher.final()];
|
|
170
173
|
JSRunLoop.main.schedule(completion, target, JSData.initWithChunks(chunks));
|
|
171
174
|
return completion.promise;
|
|
@@ -176,15 +179,14 @@ SECCipherAESCounter.definePropertiesFromExtensions({
|
|
|
176
179
|
completion = Promise.completion(Promise.resolveNonNull);
|
|
177
180
|
}
|
|
178
181
|
try{
|
|
179
|
-
|
|
180
|
-
if (name === null){
|
|
182
|
+
if (this.nodeCipherName === null){
|
|
181
183
|
JSRunLoop.main.schedule(completion, target, null);
|
|
182
184
|
return completion.promise;
|
|
183
185
|
}
|
|
184
186
|
var nonce = data.subdataInRange(JSRange(0, 8));
|
|
185
187
|
var iv = JSData.initWithLength(16);
|
|
186
188
|
nonce.copyTo(iv, 0);
|
|
187
|
-
var cipher = crypto.createDecipheriv(
|
|
189
|
+
var cipher = crypto.createDecipheriv(this.nodeCipherName, key.nodeKeyObject, iv);
|
|
188
190
|
var chunks = [cipher.update(data.subdataInRange(JSRange(8, data.length - 8))), cipher.final()];
|
|
189
191
|
JSRunLoop.main.schedule(completion, target, JSData.initWithChunks(chunks));
|
|
190
192
|
}catch (e){
|
|
@@ -197,8 +199,8 @@ SECCipherAESCounter.definePropertiesFromExtensions({
|
|
|
197
199
|
|
|
198
200
|
SECCipherAESGaloisCounterMode.definePropertiesFromExtensions({
|
|
199
201
|
|
|
200
|
-
|
|
201
|
-
switch (
|
|
202
|
+
nodeCipherName: JSLazyInitProperty(function(){
|
|
203
|
+
switch (this.keyByteLength){
|
|
202
204
|
case 16:
|
|
203
205
|
return 'id-aes128-GCM';
|
|
204
206
|
case 24:
|
|
@@ -207,53 +209,47 @@ SECCipherAESGaloisCounterMode.definePropertiesFromExtensions({
|
|
|
207
209
|
return 'id-aes256-GCM';
|
|
208
210
|
}
|
|
209
211
|
return null;
|
|
210
|
-
},
|
|
212
|
+
}),
|
|
211
213
|
|
|
212
|
-
|
|
214
|
+
encrypt: function(data, key, completion, target){
|
|
213
215
|
if (!completion){
|
|
214
216
|
completion = Promise.completion(Promise.resolveNonNull);
|
|
215
217
|
}
|
|
216
|
-
|
|
217
|
-
if (name === null){
|
|
218
|
+
if (this.nodeCipherName === null){
|
|
218
219
|
JSRunLoop.main.schedule(completion, target, null);
|
|
219
220
|
return completion.promise;
|
|
220
221
|
}
|
|
221
|
-
|
|
222
|
-
|
|
222
|
+
var iv = this.iv !== null ? this.iv : this.randomIV();
|
|
223
|
+
var cipher = crypto.createCipheriv(this.nodeCipherName, key.nodeKeyObject, iv);
|
|
224
|
+
if (this.additionalData){
|
|
225
|
+
cipher.setAAD(this.additionalData);
|
|
223
226
|
}
|
|
224
|
-
var
|
|
225
|
-
|
|
226
|
-
var cipher = crypto.createCipheriv(name, key.keyData, iv);
|
|
227
|
-
var chunks = [nonce, cipher.update(data), cipher.final()];
|
|
228
|
-
var tagLength = 16;
|
|
229
|
-
var tag = JSData.initWithLength(tagLength);
|
|
227
|
+
var chunks = [iv, cipher.update(data), cipher.final()];
|
|
228
|
+
var tag = JSData.initWithLength(this.tagByteLength);
|
|
230
229
|
cipher.getAuthTag().copyTo(tag, 0);
|
|
231
230
|
chunks.push(tag);
|
|
232
231
|
JSRunLoop.main.schedule(completion, target, JSData.initWithChunks(chunks));
|
|
233
232
|
return completion.promise;
|
|
234
233
|
},
|
|
235
234
|
|
|
236
|
-
|
|
235
|
+
decrypt: function(data, key, completion, target){
|
|
237
236
|
if (!completion){
|
|
238
237
|
completion = Promise.completion(Promise.resolveNonNull);
|
|
239
238
|
}
|
|
240
239
|
try{
|
|
241
|
-
|
|
242
|
-
if (name === null){
|
|
240
|
+
if (this.nodeCipherName === null){
|
|
243
241
|
JSRunLoop.main.schedule(completion, target, null);
|
|
244
242
|
return completion.promise;
|
|
245
243
|
}
|
|
246
|
-
var
|
|
247
|
-
|
|
248
|
-
|
|
244
|
+
var iv = data.subdataInRange(JSRange(0, this.ivByteLength));
|
|
245
|
+
var ciphertext = data.subdataInRange(JSRange(this.ivByteLength, data.length - this.ivByteLength - this.tagByteLength));
|
|
246
|
+
var tag = data.subdataInRange(JSRange(data.length - this.tagByteLength, this.tagByteLength));
|
|
247
|
+
var cipher = crypto.createDecipheriv(this.nodeCipherName, key.nodeKeyObject, iv);
|
|
248
|
+
if (this.additionalData){
|
|
249
|
+
cipher.setAAD(this.additionalData);
|
|
249
250
|
}
|
|
250
|
-
var iv = JSData.initWithLength(_ivLength);
|
|
251
|
-
nonce.copyTo(iv, 0);
|
|
252
|
-
var cipher = crypto.createDecipheriv(name, key.keyData, iv);
|
|
253
|
-
var tagLength = 16;
|
|
254
|
-
var tag = data.subdataInRange(JSRange(data.length - tagLength, tagLength));
|
|
255
251
|
cipher.setAuthTag(tag);
|
|
256
|
-
var chunks = [cipher.update(
|
|
252
|
+
var chunks = [cipher.update(ciphertext), cipher.final()];
|
|
257
253
|
JSRunLoop.main.schedule(completion, target, JSData.initWithChunks(chunks));
|
|
258
254
|
}catch(e){
|
|
259
255
|
JSRunLoop.main.schedule(completion, target, null);
|
|
@@ -263,6 +259,105 @@ SECCipherAESGaloisCounterMode.definePropertiesFromExtensions({
|
|
|
263
259
|
|
|
264
260
|
});
|
|
265
261
|
|
|
262
|
+
SECCipherRSAOAEP.definePropertiesFromExtensions({
|
|
263
|
+
|
|
264
|
+
encrypt: function(data, key, completion, target){
|
|
265
|
+
if (!completion){
|
|
266
|
+
completion = Promise.completion(Promise.resolveNonNull);
|
|
267
|
+
}
|
|
268
|
+
var options = {
|
|
269
|
+
key: key.nodeKeyObject,
|
|
270
|
+
oaepHash: this.hash
|
|
271
|
+
};
|
|
272
|
+
if (this.label !== null){
|
|
273
|
+
options.oaepLabel = this.label;
|
|
274
|
+
}
|
|
275
|
+
var encryptedBuffer = crypto.publicEncrypt(options, data);
|
|
276
|
+
JSRunLoop.main.schedule(completion, target, JSData.initWithNodeBuffer(encryptedBuffer));
|
|
277
|
+
return completion.promise;
|
|
278
|
+
},
|
|
279
|
+
|
|
280
|
+
decrypt: function(data, key, completion, target){
|
|
281
|
+
if (!completion){
|
|
282
|
+
completion = Promise.completion(Promise.resolveNonNull);
|
|
283
|
+
}
|
|
284
|
+
var options = {
|
|
285
|
+
key: key.nodeKeyObject,
|
|
286
|
+
oaepHash: this.hash
|
|
287
|
+
};
|
|
288
|
+
if (this.label !== null){
|
|
289
|
+
options.oaepLabel = this.label;
|
|
290
|
+
}
|
|
291
|
+
var decryptedBuffer = crypto.privateDecrypt(options, data);
|
|
292
|
+
JSRunLoop.main.schedule(completion, target, JSData.initWithNodeBuffer(decryptedBuffer));
|
|
293
|
+
return completion.promise;
|
|
294
|
+
},
|
|
295
|
+
|
|
296
|
+
createKey: function(completion, target){
|
|
297
|
+
if (!completion){
|
|
298
|
+
completion = Promise.completion(Promise.resolveNonNull);
|
|
299
|
+
}
|
|
300
|
+
var options = {
|
|
301
|
+
modulusLength: this.modulusLength,
|
|
302
|
+
publicExponent: this.publicExponent
|
|
303
|
+
};
|
|
304
|
+
crypto.generateKeyPair("rsa", options, function(err, publicNodeKey, privateNodeKey){
|
|
305
|
+
if (err){
|
|
306
|
+
completion.call(target, null);
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
var privateKey = SECNodeKey.initWithNodeKeyObject(privateNodeKey, {alg: SECJSONWebAlgorithms.Algorithm.rsaOAEP});
|
|
310
|
+
privateKey.publicKey = SECNodeKey.initWithNodeKeyObject(publicNodeKey, {alg: SECJSONWebAlgorithms.Algorithm.rsaOAEP});
|
|
311
|
+
privateKey.id = privateKey.publicKey.id = JSSHA1Hash(UUID.init().bytes).base64URLStringRepresentation();
|
|
312
|
+
completion.call(target, privateKey);
|
|
313
|
+
});
|
|
314
|
+
return completion.promise;
|
|
315
|
+
},
|
|
316
|
+
|
|
317
|
+
createKeyWithData: function(data, completion, target){
|
|
318
|
+
if (!completion){
|
|
319
|
+
completion = Promise.completion(Promise.resolveNonNull);
|
|
320
|
+
}
|
|
321
|
+
var parser;
|
|
322
|
+
var key;
|
|
323
|
+
try{
|
|
324
|
+
parser = SECASN1Parser.initWithPEM(data, "RSA PRIVATE KEY");
|
|
325
|
+
key = crypto.createPrivateKey({key: parser.der, format: "der"});
|
|
326
|
+
}catch (e){
|
|
327
|
+
try {
|
|
328
|
+
parser = SECASN1Parser.initWithPEM(data, "RSA PUBLIC KEY");
|
|
329
|
+
key = crypto.createPublicKey({key: parser.der, format: "der"});
|
|
330
|
+
}catch (e){
|
|
331
|
+
parser = SECASN1Parser.initWithDER(data);
|
|
332
|
+
var sequence = parser.parse();
|
|
333
|
+
if (sequence.length > 2){
|
|
334
|
+
key = crypto.createPrivateKey({key: parser.der, format: "der"});
|
|
335
|
+
}else{
|
|
336
|
+
key = crypto.createPublicKey({key: parser.der, format: "der"});
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
JSRunLoop.main.schedule(completion, target, SECNodeKey.initWithNodeKeyObject(key));
|
|
341
|
+
return completion.promise;
|
|
342
|
+
},
|
|
343
|
+
|
|
344
|
+
createKeyFromJWK: function(jwk, completion, target){
|
|
345
|
+
if (!completion){
|
|
346
|
+
completion = Promise.completion(Promise.resolveNonNull);
|
|
347
|
+
}
|
|
348
|
+
var key = null;
|
|
349
|
+
if (jwk.d){
|
|
350
|
+
key = crypto.createPrivateKey({key: jwk, format: "jwk"});
|
|
351
|
+
}else{
|
|
352
|
+
key = crypto.createPublicKey({key: jwk, format: "jwk"});
|
|
353
|
+
}
|
|
354
|
+
key.id = jwk.kid || null;
|
|
355
|
+
JSRunLoop.main.schedule(completion, target, SECNodeKey.initWithNodeKeyObject(key));
|
|
356
|
+
return completion.promise;
|
|
357
|
+
},
|
|
358
|
+
|
|
359
|
+
});
|
|
360
|
+
|
|
266
361
|
SECCipher.getRandomData = function(length){
|
|
267
362
|
return JSData.initWithNodeBuffer(crypto.randomBytes(length));
|
|
268
363
|
};
|
|
@@ -21,31 +21,34 @@
|
|
|
21
21
|
|
|
22
22
|
JSClass("SECCipher", JSObject, {
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
algorithm: null,
|
|
25
|
+
|
|
26
|
+
initWithAlgorithm: function(algorithm, options){
|
|
27
|
+
if (options === undefined){
|
|
28
|
+
options = {};
|
|
29
|
+
}else if (typeof(options) === "number"){
|
|
30
|
+
options = {
|
|
31
|
+
keyBitLength: options
|
|
32
|
+
};
|
|
27
33
|
}
|
|
28
|
-
if (keyBitLength % 8 !== 0){
|
|
34
|
+
if (options.keyBitLength !== undefined && (options.keyBitLength % 8 !== 0)){
|
|
29
35
|
throw new Error("Invalid keyBitLength, must be a multiple of 8");
|
|
30
36
|
}
|
|
31
37
|
switch (algorithm){
|
|
32
38
|
case SECCipher.Algorithm.aesCipherBlockChaining:
|
|
33
|
-
return SECCipherAESCipherBlockChaining.
|
|
39
|
+
return SECCipherAESCipherBlockChaining.initWithOptions(options);
|
|
34
40
|
case SECCipher.Algorithm.aesCounter:
|
|
35
|
-
return SECCipherAESCounter.
|
|
41
|
+
return SECCipherAESCounter.initWithOptions(options);
|
|
36
42
|
case SECCipher.Algorithm.aesGaloisCounterMode:
|
|
37
|
-
return SECCipherAESGaloisCounterMode.
|
|
43
|
+
return SECCipherAESGaloisCounterMode.initWithOptions(options);
|
|
38
44
|
case SECCipher.Algorithm.rivestCipher4:
|
|
39
|
-
return SECCipherRC4.
|
|
45
|
+
return SECCipherRC4.init();
|
|
46
|
+
case SECCipher.Algorithm.rsaOAEP:
|
|
47
|
+
return SECCipherRSAOAEP.initWithOptions(options);
|
|
40
48
|
}
|
|
41
49
|
return null;
|
|
42
50
|
},
|
|
43
51
|
|
|
44
|
-
initWithKeyBitLength: function(keyBitLength){
|
|
45
|
-
this.keyBitLength = keyBitLength;
|
|
46
|
-
this.keyByteLength = keyBitLength >> 3;
|
|
47
|
-
},
|
|
48
|
-
|
|
49
52
|
encrypt: function(data, key, completion, target){
|
|
50
53
|
// Implemented in subclasses
|
|
51
54
|
if (!completion){
|
|
@@ -122,6 +125,53 @@ JSClass("SECCipher", JSObject, {
|
|
|
122
125
|
return completion.promise;
|
|
123
126
|
},
|
|
124
127
|
|
|
128
|
+
createKeyFromJWK: function(jwk, completion, target){
|
|
129
|
+
// Implemented in subclasses
|
|
130
|
+
if (!completion){
|
|
131
|
+
completion = Promise.completion(Promise.resolveNonNull);
|
|
132
|
+
}
|
|
133
|
+
JSRunLoop.main.schedule(completion, target, null);
|
|
134
|
+
return completion.promise;
|
|
135
|
+
},
|
|
136
|
+
|
|
137
|
+
createKeyFromKeystore: function(keystore, kid, completion, target){
|
|
138
|
+
// Implemented in subclasses
|
|
139
|
+
if (!completion){
|
|
140
|
+
completion = Promise.completion(Promise.resolveNonNull);
|
|
141
|
+
}
|
|
142
|
+
JSRunLoop.main.schedule(completion, target, null);
|
|
143
|
+
return completion.promise;
|
|
144
|
+
},
|
|
145
|
+
|
|
146
|
+
createKeyWithPassphrase: function(passphrase, salt, iterations, hash, completion, target){
|
|
147
|
+
// Implemented in subclasses
|
|
148
|
+
if (!completion){
|
|
149
|
+
completion = Promise.completion(Promise.resolveNonNull);
|
|
150
|
+
}
|
|
151
|
+
JSRunLoop.main.schedule(completion, target, null);
|
|
152
|
+
return completion.promise;
|
|
153
|
+
},
|
|
154
|
+
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
SECCipher.Algorithm = {
|
|
158
|
+
aesCipherBlockChaining: 'aes_cbc',
|
|
159
|
+
aesCounter: 'aes_ctr',
|
|
160
|
+
aesGaloisCounterMode: 'aes_gcm',
|
|
161
|
+
rivestCipher4: 'rc4',
|
|
162
|
+
rsaOAEP: "rsa_oaep"
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
JSClass("SECCipherAES", SECCipher, {
|
|
166
|
+
|
|
167
|
+
keyBitLength: null,
|
|
168
|
+
keyByteLength: null,
|
|
169
|
+
|
|
170
|
+
initWithOptions: function(options){
|
|
171
|
+
this.keyBitLength = options.keyBitLength || 256;
|
|
172
|
+
this.keyByteLength = this.keyBitLength >> 3;
|
|
173
|
+
},
|
|
174
|
+
|
|
125
175
|
createKeyFromJWK: function(jwk, completion, target){
|
|
126
176
|
if (!completion){
|
|
127
177
|
completion = Promise.completion(Promise.resolveNonNull);
|
|
@@ -184,11 +234,29 @@ JSClass("SECCipher", JSObject, {
|
|
|
184
234
|
|
|
185
235
|
});
|
|
186
236
|
|
|
187
|
-
JSClass("SECCipherAESCipherBlockChaining",
|
|
237
|
+
JSClass("SECCipherAESCipherBlockChaining", SECCipherAES, {
|
|
238
|
+
|
|
239
|
+
algorithm: SECCipher.Algorithm.aesCipherBlockChaining,
|
|
240
|
+
ivByteLength: 16,
|
|
241
|
+
iv: null,
|
|
242
|
+
|
|
243
|
+
initWithOptions: function(options){
|
|
244
|
+
SECCipherAESCipherBlockChaining.$super.initWithOptions.call(this, options);
|
|
245
|
+
if (options.iv){
|
|
246
|
+
this.iv = options.iv;
|
|
247
|
+
this.ivByteLength = this.iv.length;
|
|
248
|
+
}
|
|
249
|
+
},
|
|
250
|
+
|
|
251
|
+
randomIV: function(){
|
|
252
|
+
return SECCipher.getRandomData(this.ivByteLength);
|
|
253
|
+
},
|
|
254
|
+
|
|
188
255
|
});
|
|
189
256
|
|
|
190
|
-
JSClass("SECCipherAESCounter",
|
|
257
|
+
JSClass("SECCipherAESCounter", SECCipherAES, {
|
|
191
258
|
|
|
259
|
+
algorithm: SECCipher.Algorithm.aesCounter,
|
|
192
260
|
encryptedMessageId: 0,
|
|
193
261
|
|
|
194
262
|
ensureUniqueMessageID: function(){
|
|
@@ -201,49 +269,57 @@ JSClass("SECCipherAESCounter", SECCipher, {
|
|
|
201
269
|
|
|
202
270
|
});
|
|
203
271
|
|
|
204
|
-
JSClass("SECCipherAESGaloisCounterMode",
|
|
272
|
+
JSClass("SECCipherAESGaloisCounterMode", SECCipherAES, {
|
|
205
273
|
|
|
206
|
-
|
|
274
|
+
algorithm: SECCipher.Algorithm.aesGaloisCounterMode,
|
|
275
|
+
iv: null,
|
|
276
|
+
ivByteLength: 16,
|
|
277
|
+
tagByteLength: 16,
|
|
278
|
+
additionalData: null,
|
|
207
279
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
280
|
+
initWithOptions: function(options){
|
|
281
|
+
SECCipherAESGaloisCounterMode.$super.initWithOptions.call(this, options);
|
|
282
|
+
if (options.tagByteLength){
|
|
283
|
+
this.tagByteLength = options.tagByteLength;
|
|
211
284
|
}
|
|
212
|
-
|
|
213
|
-
|
|
285
|
+
if (options.additionalData){
|
|
286
|
+
this.additionalData = options.additionalData;
|
|
287
|
+
}
|
|
288
|
+
if (options.iv){
|
|
289
|
+
this.iv = options.iv;
|
|
290
|
+
this.ivByteLength = this.iv.length;
|
|
291
|
+
}else if (options.ivByteLength){
|
|
292
|
+
this.ivByteLength = options.ivByteLength;
|
|
293
|
+
}
|
|
294
|
+
},
|
|
295
|
+
|
|
296
|
+
randomIV: function(){
|
|
297
|
+
return SECCipher.getRandomData(this.ivByteLength);
|
|
214
298
|
},
|
|
215
299
|
|
|
216
300
|
encrypt: function(data, key, completion, target){
|
|
217
|
-
if (!completion){
|
|
218
|
-
completion = Promise.completion(Promise.resolveNonNull);
|
|
219
|
-
}
|
|
220
|
-
if (!this.ensureUniqueMessageID()){
|
|
221
|
-
JSRunLoop.main.schedule(completion, target, null);
|
|
222
|
-
return completion.promise;
|
|
223
|
-
}
|
|
224
|
-
var nonce = JSData.initWithArray([
|
|
225
|
-
1,
|
|
226
|
-
((this.encryptedMessageId / 0x100000000) >> 16) & 0xFF,
|
|
227
|
-
((this.encryptedMessageId / 0x100000000) >> 8) & 0xFF,
|
|
228
|
-
(this.encryptedMessageId / 0x100000000) & 0xFF,
|
|
229
|
-
(this.encryptedMessageId >> 24) & 0xFF,
|
|
230
|
-
(this.encryptedMessageId >> 16) & 0xFF,
|
|
231
|
-
(this.encryptedMessageId >> 8) & 0xFF,
|
|
232
|
-
this.encryptedMessageId & 0xF
|
|
233
|
-
]);
|
|
234
|
-
this.encryptWithNonce(nonce, data, key, completion, target, 16);
|
|
235
|
-
return completion.promise;
|
|
236
301
|
},
|
|
237
302
|
|
|
238
303
|
decrypt: function(data, key, completion, target){
|
|
239
|
-
return this.decryptWithNonceLength(8, data, key, completion, target, 16);
|
|
240
304
|
},
|
|
241
305
|
|
|
242
|
-
|
|
243
|
-
},
|
|
306
|
+
});
|
|
244
307
|
|
|
245
|
-
|
|
246
|
-
|
|
308
|
+
JSClass("SECCipherRSAOAEP", SECCipher, {
|
|
309
|
+
|
|
310
|
+
hash: null,
|
|
311
|
+
label: null,
|
|
312
|
+
modulusLength: null,
|
|
313
|
+
publicExponent: null,
|
|
314
|
+
|
|
315
|
+
initWithOptions: function(options){
|
|
316
|
+
if (options.label){
|
|
317
|
+
this.label = options.label;
|
|
318
|
+
}
|
|
319
|
+
this.hash = options.hash || SECHash.Algorithm.sha1;
|
|
320
|
+
this.modulusLength = options.modulusLength || 2048;
|
|
321
|
+
this.publicExponent = options.publicExponent || 0x10001;
|
|
322
|
+
}
|
|
247
323
|
|
|
248
324
|
});
|
|
249
325
|
|
|
@@ -252,6 +328,8 @@ JSClass("SECCipherAESGaloisCounterMode", SECCipher, {
|
|
|
252
328
|
// to read the PDFs that already use it.
|
|
253
329
|
JSClass("SECCipherRC4", SECCipher, {
|
|
254
330
|
|
|
331
|
+
algorithm: SECCipher.Algorithm.rivestCipher4,
|
|
332
|
+
|
|
255
333
|
encrypt: function(data, key, completion, target){
|
|
256
334
|
if (!completion){
|
|
257
335
|
completion = Promise.completion(Promise.resolveNonNull);
|
|
@@ -265,7 +343,7 @@ JSClass("SECCipherRC4", SECCipher, {
|
|
|
265
343
|
var j = 0;
|
|
266
344
|
var tmp;
|
|
267
345
|
for (i = 0; i < 256; ++i){
|
|
268
|
-
j = (j + S[i] + key.
|
|
346
|
+
j = (j + S[i] + key.data[i % key.data.length]) & 0xFF;
|
|
269
347
|
tmp = S[i];
|
|
270
348
|
S[i] = S[j];
|
|
271
349
|
S[j] = tmp;
|
|
@@ -302,13 +380,6 @@ JSClass("SECCipherRC4", SECCipher, {
|
|
|
302
380
|
|
|
303
381
|
});
|
|
304
382
|
|
|
305
|
-
SECCipher.Algorithm = {
|
|
306
|
-
aesCipherBlockChaining: 'aes_cbc',
|
|
307
|
-
aesCounter: 'aes_ctr',
|
|
308
|
-
aesGaloisCounterMode: 'aes_gcm',
|
|
309
|
-
rivestCipher4: 'rc4'
|
|
310
|
-
};
|
|
311
|
-
|
|
312
383
|
SECCipher.getRandomData = function(length){
|
|
313
384
|
// Implemented in environment extensions
|
|
314
385
|
};
|
|
@@ -18,22 +18,23 @@
|
|
|
18
18
|
|
|
19
19
|
JSClass("SECDataKey", SECKey, {
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
data: null,
|
|
22
|
+
type: SECKey.KeyType.secret,
|
|
22
23
|
|
|
23
24
|
initWithData: function(data){
|
|
24
|
-
this.
|
|
25
|
+
this.data = JSData.initWithCopyOfData(data);
|
|
25
26
|
},
|
|
26
27
|
|
|
27
28
|
getData: function(completion, target){
|
|
28
29
|
if (!completion){
|
|
29
30
|
completion = Promise.completion(Promise.resolveNonNull);
|
|
30
31
|
}
|
|
31
|
-
JSRunLoop.main.schedule(completion, target, this.
|
|
32
|
+
JSRunLoop.main.schedule(completion, target, this.data);
|
|
32
33
|
return completion.promise;
|
|
33
34
|
},
|
|
34
35
|
|
|
35
36
|
destroy: function(){
|
|
36
|
-
this.
|
|
37
|
+
this.data.zero();
|
|
37
38
|
}
|
|
38
39
|
|
|
39
40
|
});
|