@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
|
@@ -46,306 +46,131 @@ SECSign.definePropertiesFromExtensions({
|
|
|
46
46
|
if (this.nodeAlgorithm.name == "rsa"){
|
|
47
47
|
nodeOptions.modulusLength = options.modulusLength || 2048;
|
|
48
48
|
nodeOptions.publicExponent = options.publicExponent || 0x10001;
|
|
49
|
-
nodeOptions.publicKeyEncoding = {
|
|
50
|
-
type: 'pkcs1',
|
|
51
|
-
format: 'pem'
|
|
52
|
-
};
|
|
53
|
-
nodeOptions.privateKeyEncoding = {
|
|
54
|
-
type: 'pkcs1',
|
|
55
|
-
format: 'pem'
|
|
56
|
-
};
|
|
57
49
|
}else if (this.nodeAlgorithm.name == "ec"){
|
|
58
50
|
if (options.namedCurve){
|
|
59
51
|
nodeOptions.namedCurve = nodeNamedCurves[options.namedCurve];
|
|
60
52
|
}else{
|
|
61
53
|
nodeOptions.namedCurve = this.nodeAlgorithm.namedCurve;
|
|
62
54
|
}
|
|
63
|
-
nodeOptions.publicKeyEncoding = {
|
|
64
|
-
type: "spki",
|
|
65
|
-
format: "pem"
|
|
66
|
-
};
|
|
67
|
-
nodeOptions.privateKeyEncoding = {
|
|
68
|
-
type: "sec1",
|
|
69
|
-
format: "pem"
|
|
70
|
-
};
|
|
71
55
|
}
|
|
72
|
-
crypto.generateKeyPair(this.nodeAlgorithm.name, nodeOptions, function(err,
|
|
56
|
+
crypto.generateKeyPair(this.nodeAlgorithm.name, nodeOptions, function(err, publicKey, privateKey){
|
|
73
57
|
if (err){
|
|
74
58
|
completion.call(target, null);
|
|
75
59
|
return;
|
|
76
60
|
}
|
|
77
61
|
var pair = {
|
|
78
|
-
public: SECNodeKey.
|
|
79
|
-
private: SECNodeKey.
|
|
62
|
+
public: SECNodeKey.initWithNodeKeyObject(publicKey),
|
|
63
|
+
private: SECNodeKey.initWithNodeKeyObject(privateKey),
|
|
80
64
|
};
|
|
65
|
+
pair.public.id = pair.private.id = JSSHA1Hash(UUID.init().bytes).base64URLStringRepresentation();
|
|
81
66
|
completion.call(target, pair);
|
|
82
67
|
});
|
|
83
68
|
return completion.promise;
|
|
84
69
|
},
|
|
85
70
|
|
|
86
|
-
createJWKPair: function(options, completion, target){
|
|
87
|
-
if (!completion){
|
|
88
|
-
completion = Promise.completion(Promise.resolveNonNull);
|
|
89
|
-
}
|
|
90
|
-
this.createKeyPair(options, function(pair){
|
|
91
|
-
if (pair === null){
|
|
92
|
-
completion.call(target, null);
|
|
93
|
-
return;
|
|
94
|
-
}
|
|
95
|
-
var jwkPair = null;
|
|
96
|
-
try{
|
|
97
|
-
var kid = JSSHA1Hash(UUID.init().bytes).base64URLStringRepresentation();
|
|
98
|
-
var alg = null;
|
|
99
|
-
var kty = null;
|
|
100
|
-
switch (this.algorithm){
|
|
101
|
-
case SECSign.Algorithm.rsaSHA256:
|
|
102
|
-
alg = SECJSONWebAlgorithms.Algorithm.rsaSHA256;
|
|
103
|
-
kty = SECJSONWebAlgorithms.KeyType.rsa;
|
|
104
|
-
break;
|
|
105
|
-
case SECSign.Algorithm.rsaSHA384:
|
|
106
|
-
alg = SECJSONWebAlgorithms.Algorithm.rsaSHA384;
|
|
107
|
-
kty = SECJSONWebAlgorithms.KeyType.rsa;
|
|
108
|
-
break;
|
|
109
|
-
case SECSign.Algorithm.rsaSHA512:
|
|
110
|
-
alg = SECJSONWebAlgorithms.Algorithm.rsaSHA512;
|
|
111
|
-
kty = SECJSONWebAlgorithms.KeyType.rsa;
|
|
112
|
-
break;
|
|
113
|
-
case SECSign.Algorithm.ellipticCurveSHA256:
|
|
114
|
-
alg = SECJSONWebAlgorithms.Algorithm.ellipticCurveSHA256;
|
|
115
|
-
kty = SECJSONWebAlgorithms.KeyType.ellipticCurve;
|
|
116
|
-
break;
|
|
117
|
-
case SECSign.Algorithm.ellipticCurveSHA384:
|
|
118
|
-
alg = SECJSONWebAlgorithms.Algorithm.ellipticCurveSHA384;
|
|
119
|
-
kty = SECJSONWebAlgorithms.KeyType.ellipticCurve;
|
|
120
|
-
break;
|
|
121
|
-
case SECSign.Algorithm.ellipticCurveSHA512:
|
|
122
|
-
alg = SECJSONWebAlgorithms.Algorithm.ellipticCurveSHA512;
|
|
123
|
-
kty = SECJSONWebAlgorithms.KeyType.ellipticCurve;
|
|
124
|
-
break;
|
|
125
|
-
default:
|
|
126
|
-
throw new Error("Unable to map SECSign algorithm to JWK");
|
|
127
|
-
}
|
|
128
|
-
var publicJWK = {
|
|
129
|
-
kid: kid,
|
|
130
|
-
kty: kty,
|
|
131
|
-
alg: alg,
|
|
132
|
-
key_ops: ["verify"]
|
|
133
|
-
};
|
|
134
|
-
var privateJWK = {
|
|
135
|
-
kid: kid,
|
|
136
|
-
kty: kty,
|
|
137
|
-
alg: alg,
|
|
138
|
-
key_ops: ["sign"]
|
|
139
|
-
};
|
|
140
|
-
var pem;
|
|
141
|
-
var parser;
|
|
142
|
-
var sequence;
|
|
143
|
-
if (kty == SECJSONWebAlgorithms.KeyType.rsa){
|
|
144
|
-
pem = pair.public.keyData;
|
|
145
|
-
parser = SECASN1Parser.initWithPEM(pem, "RSA PUBLIC KEY");
|
|
146
|
-
sequence = parser.parse();
|
|
147
|
-
publicJWK.n = sequence.values[0].data.base64URLStringRepresentation();
|
|
148
|
-
publicJWK.e = sequence.values[1].data.base64URLStringRepresentation();
|
|
149
|
-
|
|
150
|
-
pem = pair.private.keyData;
|
|
151
|
-
parser = SECASN1Parser.initWithPEM(pem, "RSA PRIVATE KEY");
|
|
152
|
-
sequence = parser.parse();
|
|
153
|
-
privateJWK.n = sequence.values[1].data.base64URLStringRepresentation();
|
|
154
|
-
privateJWK.e = sequence.values[2].data.base64URLStringRepresentation();
|
|
155
|
-
privateJWK.d = sequence.values[3].data.base64URLStringRepresentation();
|
|
156
|
-
if (sequence.values.length >= 9){
|
|
157
|
-
privateJWK.p = sequence.values[4].data.base64URLStringRepresentation();
|
|
158
|
-
privateJWK.q = sequence.values[5].data.base64URLStringRepresentation();
|
|
159
|
-
privateJWK.dp = sequence.values[6].data.base64URLStringRepresentation();
|
|
160
|
-
privateJWK.dq = sequence.values[7].data.base64URLStringRepresentation();
|
|
161
|
-
privateJWK.qi = sequence.values[8].data.base64URLStringRepresentation();
|
|
162
|
-
}
|
|
163
|
-
}else if (kty == SECJSONWebAlgorithms.KeyType.ellipticCurve){
|
|
164
|
-
pem = pair.public.keyData;
|
|
165
|
-
parser = SECASN1Parser.initWithPEM(pem, "PUBLIC KEY");
|
|
166
|
-
sequence = parser.parse();
|
|
167
|
-
if (sequence.values[0].values[0].stringValue != "1.2.840.10045.2.1"){
|
|
168
|
-
throw new Error("Expecting id-ecPublicKey");
|
|
169
|
-
}
|
|
170
|
-
var derCurve = sequence.values[0].values[1].stringValue;
|
|
171
|
-
var pointLength;
|
|
172
|
-
switch (derCurve){
|
|
173
|
-
case derNamedCurves[SECSign.EllipticCurve.p256]:
|
|
174
|
-
publicJWK.crv = SECJSONWebAlgorithms.EllipticCurve.p256;
|
|
175
|
-
pointLength = 32;
|
|
176
|
-
break;
|
|
177
|
-
case derNamedCurves[SECSign.EllipticCurve.p384]:
|
|
178
|
-
publicJWK.crv = SECJSONWebAlgorithms.EllipticCurve.p384;
|
|
179
|
-
pointLength = 48;
|
|
180
|
-
break;
|
|
181
|
-
case derNamedCurves[SECSign.EllipticCurve.p521]:
|
|
182
|
-
publicJWK.crv = SECJSONWebAlgorithms.EllipticCurve.p521;
|
|
183
|
-
pointLength = 66;
|
|
184
|
-
break;
|
|
185
|
-
default:
|
|
186
|
-
throw new Error("Unknown elliptic curve");
|
|
187
|
-
}
|
|
188
|
-
var points = sequence.values[1].data;
|
|
189
|
-
if (points[0] != 0x4){
|
|
190
|
-
throw new Error("Compressed points not implemented");
|
|
191
|
-
}
|
|
192
|
-
if (points.length != pointLength + pointLength + 1){
|
|
193
|
-
throw new Error("Unexpected point length");
|
|
194
|
-
}
|
|
195
|
-
publicJWK.x = points.subdataInRange(JSRange(1, pointLength)).base64URLStringRepresentation();
|
|
196
|
-
publicJWK.y = points.subdataInRange(JSRange(1 + pointLength, pointLength)).base64URLStringRepresentation();
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
pem = pair.private.keyData;
|
|
200
|
-
parser = SECASN1Parser.initWithPEM(pem, "EC PRIVATE KEY");
|
|
201
|
-
sequence = parser.parse();
|
|
202
|
-
var version = sequence.values[0].data[0];
|
|
203
|
-
if (version != 1){
|
|
204
|
-
throw new Error("Unexpected EC private key version");
|
|
205
|
-
}
|
|
206
|
-
privateJWK.d = sequence.values[1].data.base64URLStringRepresentation();
|
|
207
|
-
var optional = sequence.values[2];
|
|
208
|
-
if (optional.classNumber !== 0){
|
|
209
|
-
throw new Error("Expecting EC named curve");
|
|
210
|
-
}
|
|
211
|
-
derCurve = optional.value.stringValue;
|
|
212
|
-
switch (derCurve){
|
|
213
|
-
case derNamedCurves[SECSign.EllipticCurve.p256]:
|
|
214
|
-
privateJWK.crv = SECJSONWebAlgorithms.EllipticCurve.p256;
|
|
215
|
-
pointLength = 32;
|
|
216
|
-
break;
|
|
217
|
-
case derNamedCurves[SECSign.EllipticCurve.p384]:
|
|
218
|
-
privateJWK.crv = SECJSONWebAlgorithms.EllipticCurve.p384;
|
|
219
|
-
pointLength = 48;
|
|
220
|
-
break;
|
|
221
|
-
case derNamedCurves[SECSign.EllipticCurve.p521]:
|
|
222
|
-
privateJWK.crv = SECJSONWebAlgorithms.EllipticCurve.p521;
|
|
223
|
-
pointLength = 66;
|
|
224
|
-
break;
|
|
225
|
-
default:
|
|
226
|
-
throw new Error("Unknown elliptic curve");
|
|
227
|
-
}
|
|
228
|
-
optional = sequence.values[3];
|
|
229
|
-
if (optional.classNumber !== 1){
|
|
230
|
-
throw new Error("Expecting EC point");
|
|
231
|
-
}
|
|
232
|
-
points = optional.value.data;
|
|
233
|
-
if (points[0] != 0x4){
|
|
234
|
-
throw new Error("Compressed points not implemented");
|
|
235
|
-
}
|
|
236
|
-
if (points.length != pointLength + pointLength + 1){
|
|
237
|
-
throw new Error("Unexpected point length");
|
|
238
|
-
}
|
|
239
|
-
privateJWK.x = points.subdataInRange(JSRange(1, pointLength)).base64URLStringRepresentation();
|
|
240
|
-
privateJWK.y = points.subdataInRange(JSRange(1 + pointLength, pointLength)).base64URLStringRepresentation();
|
|
241
|
-
}
|
|
242
|
-
jwkPair = {
|
|
243
|
-
public: publicJWK,
|
|
244
|
-
private: privateJWK
|
|
245
|
-
};
|
|
246
|
-
}catch (e){
|
|
247
|
-
}
|
|
248
|
-
completion.call(target, jwkPair);
|
|
249
|
-
}, this);
|
|
250
|
-
return completion.promise;
|
|
251
|
-
},
|
|
252
|
-
|
|
253
71
|
createKeyFromJWK: function(jwk, completion, target){
|
|
254
72
|
if (!completion){
|
|
255
73
|
completion = Promise.completion();
|
|
256
74
|
}
|
|
257
|
-
var der, base64, pem, key;
|
|
258
|
-
if (jwk.kty
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
// publicExponent INTEGER, -- e
|
|
264
|
-
// privateExponent INTEGER, -- d
|
|
265
|
-
// prime1 INTEGER, -- p
|
|
266
|
-
// prime2 INTEGER, -- q
|
|
267
|
-
// exponent1 INTEGER, -- d mod (p-1)
|
|
268
|
-
// exponent2 INTEGER, -- d mod (q-1)
|
|
269
|
-
// coefficient INTEGER, -- (inverse of q) mod p
|
|
270
|
-
// otherPrimeInfos OtherPrimeInfos OPTIONAL
|
|
271
|
-
// }
|
|
272
|
-
//
|
|
273
|
-
if (typeof(jwk.n) == "string" && typeof(jwk.e) == "string" && typeof(jwk.d) == "string"){
|
|
274
|
-
try{
|
|
275
|
-
var values = [
|
|
276
|
-
SECASN1Integer.initWithData(JSData.initWithArray([0])),
|
|
277
|
-
SECASN1Integer.initWithData(jwk.n.dataByDecodingBase64URL()),
|
|
278
|
-
SECASN1Integer.initWithData(jwk.e.dataByDecodingBase64URL()),
|
|
279
|
-
SECASN1Integer.initWithData(jwk.d.dataByDecodingBase64URL()),
|
|
280
|
-
];
|
|
281
|
-
|
|
282
|
-
if (typeof(jwk.p) == "string" && typeof(jwk.q) == "string" && typeof(jwk.dp) == "string" && typeof(jwk.dq) == "string" && typeof(jwk.qi) == "string"){
|
|
283
|
-
values.push(SECASN1Integer.initWithData(jwk.p.dataByDecodingBase64URL()));
|
|
284
|
-
values.push(SECASN1Integer.initWithData(jwk.q.dataByDecodingBase64URL()));
|
|
285
|
-
values.push(SECASN1Integer.initWithData(jwk.dp.dataByDecodingBase64URL()));
|
|
286
|
-
values.push(SECASN1Integer.initWithData(jwk.dq.dataByDecodingBase64URL()));
|
|
287
|
-
values.push(SECASN1Integer.initWithData(jwk.qi.dataByDecodingBase64URL()));
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
if (jwk.oth){
|
|
291
|
-
JSRunLoop.main.schedule(completion, target, null);
|
|
292
|
-
return completion.promise;
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
var rsaPrivateKey = SECASN1Sequence.initWithValues(values);
|
|
296
|
-
pem = rsaPrivateKey.pemRepresentation("RSA PRIVATE KEY");
|
|
297
|
-
key = SECNodeKey.initWithData(pem.utf8());
|
|
298
|
-
JSRunLoop.main.schedule(completion, target, key);
|
|
299
|
-
}catch (e){
|
|
300
|
-
JSRunLoop.main.schedule(completion, target, null);
|
|
301
|
-
}
|
|
302
|
-
}else{
|
|
303
|
-
JSRunLoop.main.schedule(completion, target, null);
|
|
304
|
-
}
|
|
305
|
-
}else if (jwk.kty == SECJSONWebAlgorithms.KeyType.ellipticCurve){
|
|
306
|
-
// ECPrivateKey ::= SEQUENCE {
|
|
307
|
-
// version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
|
|
308
|
-
// privateKey OCTET STRING,
|
|
309
|
-
// parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
|
|
310
|
-
// publicKey [1] BIT STRING OPTIONAL
|
|
311
|
-
// }
|
|
312
|
-
try{
|
|
313
|
-
var namedCurve;
|
|
314
|
-
switch (jwk.crv){
|
|
315
|
-
case SECJSONWebAlgorithms.EllipticCurve.p256:
|
|
316
|
-
namedCurve = derNamedCurves[SECSign.EllipticCurve.p256];
|
|
317
|
-
break;
|
|
318
|
-
case SECJSONWebAlgorithms.EllipticCurve.p384:
|
|
319
|
-
namedCurve = derNamedCurves[SECSign.EllipticCurve.p384];
|
|
320
|
-
break;
|
|
321
|
-
case SECJSONWebAlgorithms.EllipticCurve.p521:
|
|
322
|
-
namedCurve = derNamedCurves[SECSign.EllipticCurve.p521];
|
|
323
|
-
break;
|
|
324
|
-
default:
|
|
325
|
-
throw new Error("Unsupported curve name");
|
|
326
|
-
}
|
|
327
|
-
var privateKey = SECASN1Sequence.initWithValues([
|
|
328
|
-
SECASN1Integer.initWithData(JSData.initWithArray([1])),
|
|
329
|
-
SECASN1OctetString.initWithData(jwk.d.dataByDecodingBase64URL()),
|
|
330
|
-
SECASN1Optional.initWithValue(
|
|
331
|
-
SECASN1ObjectIdentifier.initWithString(namedCurve),
|
|
332
|
-
0
|
|
333
|
-
),
|
|
334
|
-
SECASN1Optional.initWithValue(
|
|
335
|
-
SECASN1BitString.initWithData(JSData.initWithChunks([
|
|
336
|
-
JSData.initWithArray([0x04]), // uncompressed
|
|
337
|
-
jwk.x.dataByDecodingBase64URL(),
|
|
338
|
-
jwk.y.dataByDecodingBase64URL()
|
|
339
|
-
]), 0),
|
|
340
|
-
1
|
|
341
|
-
)
|
|
342
|
-
]);
|
|
343
|
-
pem = privateKey.pemRepresentation("EC PRIVATE KEY");
|
|
344
|
-
key = SECNodeKey.initWithData(pem.utf8());
|
|
345
|
-
JSRunLoop.main.schedule(completion, target, key);
|
|
346
|
-
}catch (e){
|
|
347
|
-
JSRunLoop.main.schedule(completion, target, null);
|
|
75
|
+
var der, base64, pem, nodeKeyObject, key;
|
|
76
|
+
if (jwk.kty === SECJSONWebAlgorithms.KeyType.rsa || jwk.kty === SECJSONWebAlgorithms.KeyType.ellipticCurve){
|
|
77
|
+
nodeKeyObject = crypto.createPrivateKey({key: jwk, format: "jwk"});
|
|
78
|
+
key = SECNodeKey.initWithNodeKeyObject(nodeKeyObject);
|
|
79
|
+
if (key !== null){
|
|
80
|
+
key.id = jwk.kid || null;
|
|
348
81
|
}
|
|
82
|
+
JSRunLoop.main.schedule(completion, target, key);
|
|
83
|
+
// if (jwk.kty == SECJSONWebAlgorithms.KeyType.rsa){
|
|
84
|
+
// // RSA private key ASN.1 syntax:
|
|
85
|
+
// // RSAPrivateKey ::= SEQUENCE {
|
|
86
|
+
// // version Version,
|
|
87
|
+
// // modulus INTEGER, -- n
|
|
88
|
+
// // publicExponent INTEGER, -- e
|
|
89
|
+
// // privateExponent INTEGER, -- d
|
|
90
|
+
// // prime1 INTEGER, -- p
|
|
91
|
+
// // prime2 INTEGER, -- q
|
|
92
|
+
// // exponent1 INTEGER, -- d mod (p-1)
|
|
93
|
+
// // exponent2 INTEGER, -- d mod (q-1)
|
|
94
|
+
// // coefficient INTEGER, -- (inverse of q) mod p
|
|
95
|
+
// // otherPrimeInfos OtherPrimeInfos OPTIONAL
|
|
96
|
+
// // }
|
|
97
|
+
// //
|
|
98
|
+
// if (typeof(jwk.n) == "string" && typeof(jwk.e) == "string" && typeof(jwk.d) == "string"){
|
|
99
|
+
// try{
|
|
100
|
+
// var values = [
|
|
101
|
+
// SECASN1Integer.initWithData(JSData.initWithArray([0])),
|
|
102
|
+
// SECASN1Integer.initWithData(jwk.n.dataByDecodingBase64URL()),
|
|
103
|
+
// SECASN1Integer.initWithData(jwk.e.dataByDecodingBase64URL()),
|
|
104
|
+
// SECASN1Integer.initWithData(jwk.d.dataByDecodingBase64URL()),
|
|
105
|
+
// ];
|
|
106
|
+
|
|
107
|
+
// if (typeof(jwk.p) == "string" && typeof(jwk.q) == "string" && typeof(jwk.dp) == "string" && typeof(jwk.dq) == "string" && typeof(jwk.qi) == "string"){
|
|
108
|
+
// values.push(SECASN1Integer.initWithData(jwk.p.dataByDecodingBase64URL()));
|
|
109
|
+
// values.push(SECASN1Integer.initWithData(jwk.q.dataByDecodingBase64URL()));
|
|
110
|
+
// values.push(SECASN1Integer.initWithData(jwk.dp.dataByDecodingBase64URL()));
|
|
111
|
+
// values.push(SECASN1Integer.initWithData(jwk.dq.dataByDecodingBase64URL()));
|
|
112
|
+
// values.push(SECASN1Integer.initWithData(jwk.qi.dataByDecodingBase64URL()));
|
|
113
|
+
// }
|
|
114
|
+
|
|
115
|
+
// if (jwk.oth){
|
|
116
|
+
// JSRunLoop.main.schedule(completion, target, null);
|
|
117
|
+
// return completion.promise;
|
|
118
|
+
// }
|
|
119
|
+
|
|
120
|
+
// var rsaPrivateKey = SECASN1Sequence.initWithValues(values);
|
|
121
|
+
// pem = rsaPrivateKey.pemRepresentation("RSA PRIVATE KEY");
|
|
122
|
+
// key = SECNodeKey.initWithData(pem.utf8());
|
|
123
|
+
// JSRunLoop.main.schedule(completion, target, key);
|
|
124
|
+
// }catch (e){
|
|
125
|
+
// JSRunLoop.main.schedule(completion, target, null);
|
|
126
|
+
// }
|
|
127
|
+
// }else{
|
|
128
|
+
// JSRunLoop.main.schedule(completion, target, null);
|
|
129
|
+
// }
|
|
130
|
+
// }else if (jwk.kty == SECJSONWebAlgorithms.KeyType.ellipticCurve){
|
|
131
|
+
// // ECPrivateKey ::= SEQUENCE {
|
|
132
|
+
// // version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
|
|
133
|
+
// // privateKey OCTET STRING,
|
|
134
|
+
// // parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
|
|
135
|
+
// // publicKey [1] BIT STRING OPTIONAL
|
|
136
|
+
// // }
|
|
137
|
+
// try{
|
|
138
|
+
// var namedCurve;
|
|
139
|
+
// switch (jwk.crv){
|
|
140
|
+
// case SECJSONWebAlgorithms.EllipticCurve.p256:
|
|
141
|
+
// namedCurve = derNamedCurves[SECSign.EllipticCurve.p256];
|
|
142
|
+
// break;
|
|
143
|
+
// case SECJSONWebAlgorithms.EllipticCurve.p384:
|
|
144
|
+
// namedCurve = derNamedCurves[SECSign.EllipticCurve.p384];
|
|
145
|
+
// break;
|
|
146
|
+
// case SECJSONWebAlgorithms.EllipticCurve.p521:
|
|
147
|
+
// namedCurve = derNamedCurves[SECSign.EllipticCurve.p521];
|
|
148
|
+
// break;
|
|
149
|
+
// default:
|
|
150
|
+
// throw new Error("Unsupported curve name");
|
|
151
|
+
// }
|
|
152
|
+
// var privateKey = SECASN1Sequence.initWithValues([
|
|
153
|
+
// SECASN1Integer.initWithData(JSData.initWithArray([1])),
|
|
154
|
+
// SECASN1OctetString.initWithData(jwk.d.dataByDecodingBase64URL()),
|
|
155
|
+
// SECASN1Optional.initWithValue(
|
|
156
|
+
// SECASN1ObjectIdentifier.initWithString(namedCurve),
|
|
157
|
+
// 0
|
|
158
|
+
// ),
|
|
159
|
+
// SECASN1Optional.initWithValue(
|
|
160
|
+
// SECASN1BitString.initWithData(JSData.initWithChunks([
|
|
161
|
+
// JSData.initWithArray([0x04]), // uncompressed
|
|
162
|
+
// jwk.x.dataByDecodingBase64URL(),
|
|
163
|
+
// jwk.y.dataByDecodingBase64URL()
|
|
164
|
+
// ]), 0),
|
|
165
|
+
// 1
|
|
166
|
+
// )
|
|
167
|
+
// ]);
|
|
168
|
+
// pem = privateKey.pemRepresentation("EC PRIVATE KEY");
|
|
169
|
+
// key = SECNodeKey.initWithData(pem.utf8());
|
|
170
|
+
// JSRunLoop.main.schedule(completion, target, key);
|
|
171
|
+
// }catch (e){
|
|
172
|
+
// JSRunLoop.main.schedule(completion, target, null);
|
|
173
|
+
// }
|
|
349
174
|
}else{
|
|
350
175
|
JSRunLoop.main.schedule(completion, target, null);
|
|
351
176
|
}
|
|
@@ -361,7 +186,7 @@ SECSign.definePropertiesFromExtensions({
|
|
|
361
186
|
completion = Promise.completion();
|
|
362
187
|
}
|
|
363
188
|
this.nodeSign.end();
|
|
364
|
-
var signature = this.nodeSign.sign(key.
|
|
189
|
+
var signature = this.nodeSign.sign(key.nodeKeyObject);
|
|
365
190
|
completion.call(target, JSData.initWithNodeBuffer(signature));
|
|
366
191
|
return completion.promise;
|
|
367
192
|
}
|
|
@@ -38,6 +38,33 @@ JSClass("SECSign", JSObject, {
|
|
|
38
38
|
},
|
|
39
39
|
|
|
40
40
|
createJWKPair: function(options, completion, target){
|
|
41
|
+
if (!completion){
|
|
42
|
+
completion = Promise.completion(Promise.resolveNonNull);
|
|
43
|
+
}
|
|
44
|
+
this.createKeyPair(options, function(pair){
|
|
45
|
+
if (pair === null){
|
|
46
|
+
completion.call(target, null);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
pair.private.getJWK(function(privateJWK){
|
|
50
|
+
if (privateJWK === null){
|
|
51
|
+
completion.call(target, null);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
pair.public.getJWK(function(publicJWK){
|
|
55
|
+
if (publicJWK === null){
|
|
56
|
+
completion.call(target, null);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
var pair = {
|
|
60
|
+
public: publicJWK,
|
|
61
|
+
private: privateJWK
|
|
62
|
+
};
|
|
63
|
+
completion.call(target, pair);
|
|
64
|
+
}, this);
|
|
65
|
+
}, this);
|
|
66
|
+
}, this);
|
|
67
|
+
return completion.promise;
|
|
41
68
|
},
|
|
42
69
|
|
|
43
70
|
createKeyFromJWK: function(jwk, completion, target){
|
|
@@ -43,7 +43,7 @@ SECVerify.definePropertiesFromExtensions({
|
|
|
43
43
|
if (!completion){
|
|
44
44
|
completion = Promise.completion();
|
|
45
45
|
}
|
|
46
|
-
var verified = this.nodeVerify.verify(key.
|
|
46
|
+
var verified = this.nodeVerify.verify(key.nodeKeyObject, signature);
|
|
47
47
|
completion.call(target, verified);
|
|
48
48
|
return completion.promise;
|
|
49
49
|
},
|
|
@@ -53,63 +53,66 @@ SECVerify.definePropertiesFromExtensions({
|
|
|
53
53
|
completion = Promise.completion();
|
|
54
54
|
}
|
|
55
55
|
var der, base64, pem, key;
|
|
56
|
-
if (jwk.kty
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
56
|
+
if (jwk.kty === SECJSONWebAlgorithms.KeyType.rsa || jwk.kty === SECJSONWebAlgorithms.KeyType.ellipticCurve){
|
|
57
|
+
key = crypto.createPublicKey({key: jwk, format: "jwk"});
|
|
58
|
+
JSRunLoop.main.schedule(completion, target, SECNodeKey.initWithNodeKeyObject(key));
|
|
59
|
+
// if (jwk.kty == SECJSONWebAlgorithms.KeyType.rsa){
|
|
60
|
+
// // RSA public key ASN.1 syntax:
|
|
61
|
+
// // RSAPublicKey ::= SEQUENCE {
|
|
62
|
+
// // modulus INTEGER, -- n
|
|
63
|
+
// // publicExponent INTEGER -- e
|
|
64
|
+
// // }
|
|
65
|
+
// //
|
|
63
66
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
}else if (jwk.kty == SECJSONWebAlgorithms.KeyType.ellipticCurve){
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
67
|
+
// if (typeof(jwk.n) == "string" && typeof(jwk.e) == "string"){
|
|
68
|
+
// try{
|
|
69
|
+
// var rsaPublicKey = SECASN1Sequence.initWithValues([
|
|
70
|
+
// SECASN1Integer.initWithData(jwk.n.dataByDecodingBase64URL()),
|
|
71
|
+
// SECASN1Integer.initWithData(jwk.e.dataByDecodingBase64URL())
|
|
72
|
+
// ]);
|
|
73
|
+
// pem = rsaPublicKey.pemRepresentation("RSA PUBLIC KEY");
|
|
74
|
+
// key = SECNodeKey.initWithData(pem.utf8());
|
|
75
|
+
// JSRunLoop.main.schedule(completion, target, key);
|
|
76
|
+
// }catch (e){
|
|
77
|
+
// JSRunLoop.main.schedule(completion, target, null);
|
|
78
|
+
// }
|
|
79
|
+
// }else{
|
|
80
|
+
// JSRunLoop.main.schedule(completion, target, null);
|
|
81
|
+
// }
|
|
82
|
+
// }else if (jwk.kty == SECJSONWebAlgorithms.KeyType.ellipticCurve){
|
|
83
|
+
// // SPKI format
|
|
84
|
+
// try{
|
|
85
|
+
// var derCurve;
|
|
86
|
+
// switch (jwk.crv){
|
|
87
|
+
// case SECJSONWebAlgorithms.EllipticCurve.p256:
|
|
88
|
+
// derCurve = derNamedCurves[SECVerify.EllipticCurve.p256];
|
|
89
|
+
// break;
|
|
90
|
+
// case SECJSONWebAlgorithms.EllipticCurve.p384:
|
|
91
|
+
// derCurve = derNamedCurves[SECVerify.EllipticCurve.p384];
|
|
92
|
+
// break;
|
|
93
|
+
// case SECJSONWebAlgorithms.EllipticCurve.p384:
|
|
94
|
+
// derCurve = derNamedCurves[SECVerify.EllipticCurve.p384];
|
|
95
|
+
// break;
|
|
96
|
+
// default:
|
|
97
|
+
// throw new Error("Unknown jwk.crv");
|
|
98
|
+
// }
|
|
99
|
+
// var publicKey = SECASN1Sequence.initWithValues([
|
|
100
|
+
// SECASN1Sequence.initWithValues([
|
|
101
|
+
// SECASN1ObjectIdentifier.initWithString("1.2.840.10045.2.1"),
|
|
102
|
+
// SECASN1ObjectIdentifier.initWithString(derCurve),
|
|
103
|
+
// ]),
|
|
104
|
+
// SECASN1BitString.initWithData(JSData.initWithChunks([
|
|
105
|
+
// JSData.initWithArray([0x4]), // uncompressed
|
|
106
|
+
// jwk.x.dataByDecodingBase64URL(),
|
|
107
|
+
// jwk.y.dataByDecodingBase64URL()
|
|
108
|
+
// ]), 0)
|
|
109
|
+
// ]);
|
|
110
|
+
// pem = publicKey.pemRepresentation("PUBLIC KEY");
|
|
111
|
+
// key = SECNodeKey.initWithData(pem.utf8());
|
|
112
|
+
// JSRunLoop.main.schedule(completion, target, key);
|
|
113
|
+
// }catch (e){
|
|
114
|
+
// JSRunLoop.main.schedule(completion, target, null);
|
|
115
|
+
// }
|
|
113
116
|
}else{
|
|
114
117
|
JSRunLoop.main.schedule(completion, target, null);
|
|
115
118
|
}
|
|
@@ -3,7 +3,7 @@ JSBundle.bundles['io.breakside.JSKit.SecurityKit'] = {
|
|
|
3
3
|
"Info": {
|
|
4
4
|
"JSBundleType": "framework",
|
|
5
5
|
"JSBundleIdentifier": "io.breakside.JSKit.SecurityKit",
|
|
6
|
-
"JSBundleVersion": "2024.
|
|
6
|
+
"JSBundleVersion": "2024.40.0",
|
|
7
7
|
"JSDevelopmentLanguage": "en",
|
|
8
8
|
"JSCopyright": "Copyright © 2020 Breakside Inc.",
|
|
9
9
|
"JSBundleEnvironments": {
|
|
@@ -11,7 +11,7 @@ JSBundle.bundles['io.breakside.JSKit.SecurityKit'] = {
|
|
|
11
11
|
"node": "SecurityKit+Node.js"
|
|
12
12
|
},
|
|
13
13
|
"JSLicenseNotice": "Licensed under the Breakside Public License, Version 1.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nIf a copy of the License was not distributed with this file, you may\nobtain a copy at\n\n http://breakside.io/licenses/LICENSE-1.0.txt\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n",
|
|
14
|
-
"GitRevision": "
|
|
14
|
+
"GitRevision": "f17cafe60642c3c9674095789dec1d1803b72586"
|
|
15
15
|
},
|
|
16
16
|
"Resources": [],
|
|
17
17
|
"ResourceLookup": {
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
"SECHMAC.js",
|
|
15
15
|
"SECSign.js",
|
|
16
16
|
"SECJSONWebToken.js",
|
|
17
|
+
"SECJSONWebEncryption.js",
|
|
17
18
|
"SECPassword.js",
|
|
18
19
|
"SECASN1.js",
|
|
19
20
|
"SECASN1Parser.js",
|
|
@@ -29,9 +30,11 @@
|
|
|
29
30
|
"SECDataKey",
|
|
30
31
|
"SECJSONWebAlgorithms",
|
|
31
32
|
"SECCipher",
|
|
33
|
+
"SECCipherAES",
|
|
32
34
|
"SECCipherAESCipherBlockChaining",
|
|
33
35
|
"SECCipherAESCounter",
|
|
34
36
|
"SECCipherAESGaloisCounterMode",
|
|
37
|
+
"SECCipherRSAOAEP",
|
|
35
38
|
"SECCipherRC4",
|
|
36
39
|
"SECHash",
|
|
37
40
|
"SECVerify",
|
|
@@ -39,6 +42,7 @@
|
|
|
39
42
|
"SECHMAC",
|
|
40
43
|
"SECSign",
|
|
41
44
|
"SECJSONWebToken",
|
|
45
|
+
"SECJSONWebEncryption",
|
|
42
46
|
"SECPassword",
|
|
43
47
|
"SECASN1Value",
|
|
44
48
|
"SECASN1Boolean",
|
|
@@ -68,6 +72,7 @@
|
|
|
68
72
|
"SECSign+HTML.js",
|
|
69
73
|
"SECVerify+HTML.js",
|
|
70
74
|
"SECPassword+HTML.js",
|
|
75
|
+
"SECCOSE.js",
|
|
71
76
|
"SECHTMLDeviceAuthentication.js",
|
|
72
77
|
"SECHTMLKeychain.js",
|
|
73
78
|
"SecurityKit+HTML.js"
|
|
@@ -78,6 +83,7 @@
|
|
|
78
83
|
],
|
|
79
84
|
"globals": [
|
|
80
85
|
"SECHTMLKey",
|
|
86
|
+
"SECCOSE",
|
|
81
87
|
"SECHTMLDeviceAuthentication",
|
|
82
88
|
"SECHTMLPasswordCredentialKeychain"
|
|
83
89
|
]
|