source: trip-planner-front/node_modules/sshpk/lib/formats/pkcs8.js@ 6a80231

Last change on this file since 6a80231 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 14.2 KB
Line 
1// Copyright 2018 Joyent, Inc.
2
3module.exports = {
4 read: read,
5 readPkcs8: readPkcs8,
6 write: write,
7 writePkcs8: writePkcs8,
8 pkcs8ToBuffer: pkcs8ToBuffer,
9
10 readECDSACurve: readECDSACurve,
11 writeECDSACurve: writeECDSACurve
12};
13
14var assert = require('assert-plus');
15var asn1 = require('asn1');
16var Buffer = require('safer-buffer').Buffer;
17var algs = require('../algs');
18var utils = require('../utils');
19var Key = require('../key');
20var PrivateKey = require('../private-key');
21var pem = require('./pem');
22
23function read(buf, options) {
24 return (pem.read(buf, options, 'pkcs8'));
25}
26
27function write(key, options) {
28 return (pem.write(key, options, 'pkcs8'));
29}
30
31/* Helper to read in a single mpint */
32function readMPInt(der, nm) {
33 assert.strictEqual(der.peek(), asn1.Ber.Integer,
34 nm + ' is not an Integer');
35 return (utils.mpNormalize(der.readString(asn1.Ber.Integer, true)));
36}
37
38function readPkcs8(alg, type, der) {
39 /* Private keys in pkcs#8 format have a weird extra int */
40 if (der.peek() === asn1.Ber.Integer) {
41 assert.strictEqual(type, 'private',
42 'unexpected Integer at start of public key');
43 der.readString(asn1.Ber.Integer, true);
44 }
45
46 der.readSequence();
47 var next = der.offset + der.length;
48
49 var oid = der.readOID();
50 switch (oid) {
51 case '1.2.840.113549.1.1.1':
52 der._offset = next;
53 if (type === 'public')
54 return (readPkcs8RSAPublic(der));
55 else
56 return (readPkcs8RSAPrivate(der));
57 case '1.2.840.10040.4.1':
58 if (type === 'public')
59 return (readPkcs8DSAPublic(der));
60 else
61 return (readPkcs8DSAPrivate(der));
62 case '1.2.840.10045.2.1':
63 if (type === 'public')
64 return (readPkcs8ECDSAPublic(der));
65 else
66 return (readPkcs8ECDSAPrivate(der));
67 case '1.3.101.112':
68 if (type === 'public') {
69 return (readPkcs8EdDSAPublic(der));
70 } else {
71 return (readPkcs8EdDSAPrivate(der));
72 }
73 case '1.3.101.110':
74 if (type === 'public') {
75 return (readPkcs8X25519Public(der));
76 } else {
77 return (readPkcs8X25519Private(der));
78 }
79 default:
80 throw (new Error('Unknown key type OID ' + oid));
81 }
82}
83
84function readPkcs8RSAPublic(der) {
85 // bit string sequence
86 der.readSequence(asn1.Ber.BitString);
87 der.readByte();
88 der.readSequence();
89
90 // modulus
91 var n = readMPInt(der, 'modulus');
92 var e = readMPInt(der, 'exponent');
93
94 // now, make the key
95 var key = {
96 type: 'rsa',
97 source: der.originalInput,
98 parts: [
99 { name: 'e', data: e },
100 { name: 'n', data: n }
101 ]
102 };
103
104 return (new Key(key));
105}
106
107function readPkcs8RSAPrivate(der) {
108 der.readSequence(asn1.Ber.OctetString);
109 der.readSequence();
110
111 var ver = readMPInt(der, 'version');
112 assert.equal(ver[0], 0x0, 'unknown RSA private key version');
113
114 // modulus then public exponent
115 var n = readMPInt(der, 'modulus');
116 var e = readMPInt(der, 'public exponent');
117 var d = readMPInt(der, 'private exponent');
118 var p = readMPInt(der, 'prime1');
119 var q = readMPInt(der, 'prime2');
120 var dmodp = readMPInt(der, 'exponent1');
121 var dmodq = readMPInt(der, 'exponent2');
122 var iqmp = readMPInt(der, 'iqmp');
123
124 // now, make the key
125 var key = {
126 type: 'rsa',
127 parts: [
128 { name: 'n', data: n },
129 { name: 'e', data: e },
130 { name: 'd', data: d },
131 { name: 'iqmp', data: iqmp },
132 { name: 'p', data: p },
133 { name: 'q', data: q },
134 { name: 'dmodp', data: dmodp },
135 { name: 'dmodq', data: dmodq }
136 ]
137 };
138
139 return (new PrivateKey(key));
140}
141
142function readPkcs8DSAPublic(der) {
143 der.readSequence();
144
145 var p = readMPInt(der, 'p');
146 var q = readMPInt(der, 'q');
147 var g = readMPInt(der, 'g');
148
149 // bit string sequence
150 der.readSequence(asn1.Ber.BitString);
151 der.readByte();
152
153 var y = readMPInt(der, 'y');
154
155 // now, make the key
156 var key = {
157 type: 'dsa',
158 parts: [
159 { name: 'p', data: p },
160 { name: 'q', data: q },
161 { name: 'g', data: g },
162 { name: 'y', data: y }
163 ]
164 };
165
166 return (new Key(key));
167}
168
169function readPkcs8DSAPrivate(der) {
170 der.readSequence();
171
172 var p = readMPInt(der, 'p');
173 var q = readMPInt(der, 'q');
174 var g = readMPInt(der, 'g');
175
176 der.readSequence(asn1.Ber.OctetString);
177 var x = readMPInt(der, 'x');
178
179 /* The pkcs#8 format does not include the public key */
180 var y = utils.calculateDSAPublic(g, p, x);
181
182 var key = {
183 type: 'dsa',
184 parts: [
185 { name: 'p', data: p },
186 { name: 'q', data: q },
187 { name: 'g', data: g },
188 { name: 'y', data: y },
189 { name: 'x', data: x }
190 ]
191 };
192
193 return (new PrivateKey(key));
194}
195
196function readECDSACurve(der) {
197 var curveName, curveNames;
198 var j, c, cd;
199
200 if (der.peek() === asn1.Ber.OID) {
201 var oid = der.readOID();
202
203 curveNames = Object.keys(algs.curves);
204 for (j = 0; j < curveNames.length; ++j) {
205 c = curveNames[j];
206 cd = algs.curves[c];
207 if (cd.pkcs8oid === oid) {
208 curveName = c;
209 break;
210 }
211 }
212
213 } else {
214 // ECParameters sequence
215 der.readSequence();
216 var version = der.readString(asn1.Ber.Integer, true);
217 assert.strictEqual(version[0], 1, 'ECDSA key not version 1');
218
219 var curve = {};
220
221 // FieldID sequence
222 der.readSequence();
223 var fieldTypeOid = der.readOID();
224 assert.strictEqual(fieldTypeOid, '1.2.840.10045.1.1',
225 'ECDSA key is not from a prime-field');
226 var p = curve.p = utils.mpNormalize(
227 der.readString(asn1.Ber.Integer, true));
228 /*
229 * p always starts with a 1 bit, so count the zeros to get its
230 * real size.
231 */
232 curve.size = p.length * 8 - utils.countZeros(p);
233
234 // Curve sequence
235 der.readSequence();
236 curve.a = utils.mpNormalize(
237 der.readString(asn1.Ber.OctetString, true));
238 curve.b = utils.mpNormalize(
239 der.readString(asn1.Ber.OctetString, true));
240 if (der.peek() === asn1.Ber.BitString)
241 curve.s = der.readString(asn1.Ber.BitString, true);
242
243 // Combined Gx and Gy
244 curve.G = der.readString(asn1.Ber.OctetString, true);
245 assert.strictEqual(curve.G[0], 0x4,
246 'uncompressed G is required');
247
248 curve.n = utils.mpNormalize(
249 der.readString(asn1.Ber.Integer, true));
250 curve.h = utils.mpNormalize(
251 der.readString(asn1.Ber.Integer, true));
252 assert.strictEqual(curve.h[0], 0x1, 'a cofactor=1 curve is ' +
253 'required');
254
255 curveNames = Object.keys(algs.curves);
256 var ks = Object.keys(curve);
257 for (j = 0; j < curveNames.length; ++j) {
258 c = curveNames[j];
259 cd = algs.curves[c];
260 var equal = true;
261 for (var i = 0; i < ks.length; ++i) {
262 var k = ks[i];
263 if (cd[k] === undefined)
264 continue;
265 if (typeof (cd[k]) === 'object' &&
266 cd[k].equals !== undefined) {
267 if (!cd[k].equals(curve[k])) {
268 equal = false;
269 break;
270 }
271 } else if (Buffer.isBuffer(cd[k])) {
272 if (cd[k].toString('binary')
273 !== curve[k].toString('binary')) {
274 equal = false;
275 break;
276 }
277 } else {
278 if (cd[k] !== curve[k]) {
279 equal = false;
280 break;
281 }
282 }
283 }
284 if (equal) {
285 curveName = c;
286 break;
287 }
288 }
289 }
290 return (curveName);
291}
292
293function readPkcs8ECDSAPrivate(der) {
294 var curveName = readECDSACurve(der);
295 assert.string(curveName, 'a known elliptic curve');
296
297 der.readSequence(asn1.Ber.OctetString);
298 der.readSequence();
299
300 var version = readMPInt(der, 'version');
301 assert.equal(version[0], 1, 'unknown version of ECDSA key');
302
303 var d = der.readString(asn1.Ber.OctetString, true);
304 var Q;
305
306 if (der.peek() == 0xa0) {
307 der.readSequence(0xa0);
308 der._offset += der.length;
309 }
310 if (der.peek() == 0xa1) {
311 der.readSequence(0xa1);
312 Q = der.readString(asn1.Ber.BitString, true);
313 Q = utils.ecNormalize(Q);
314 }
315
316 if (Q === undefined) {
317 var pub = utils.publicFromPrivateECDSA(curveName, d);
318 Q = pub.part.Q.data;
319 }
320
321 var key = {
322 type: 'ecdsa',
323 parts: [
324 { name: 'curve', data: Buffer.from(curveName) },
325 { name: 'Q', data: Q },
326 { name: 'd', data: d }
327 ]
328 };
329
330 return (new PrivateKey(key));
331}
332
333function readPkcs8ECDSAPublic(der) {
334 var curveName = readECDSACurve(der);
335 assert.string(curveName, 'a known elliptic curve');
336
337 var Q = der.readString(asn1.Ber.BitString, true);
338 Q = utils.ecNormalize(Q);
339
340 var key = {
341 type: 'ecdsa',
342 parts: [
343 { name: 'curve', data: Buffer.from(curveName) },
344 { name: 'Q', data: Q }
345 ]
346 };
347
348 return (new Key(key));
349}
350
351function readPkcs8EdDSAPublic(der) {
352 if (der.peek() === 0x00)
353 der.readByte();
354
355 var A = utils.readBitString(der);
356
357 var key = {
358 type: 'ed25519',
359 parts: [
360 { name: 'A', data: utils.zeroPadToLength(A, 32) }
361 ]
362 };
363
364 return (new Key(key));
365}
366
367function readPkcs8X25519Public(der) {
368 var A = utils.readBitString(der);
369
370 var key = {
371 type: 'curve25519',
372 parts: [
373 { name: 'A', data: utils.zeroPadToLength(A, 32) }
374 ]
375 };
376
377 return (new Key(key));
378}
379
380function readPkcs8EdDSAPrivate(der) {
381 if (der.peek() === 0x00)
382 der.readByte();
383
384 der.readSequence(asn1.Ber.OctetString);
385 var k = der.readString(asn1.Ber.OctetString, true);
386 k = utils.zeroPadToLength(k, 32);
387
388 var A;
389 if (der.peek() === asn1.Ber.BitString) {
390 A = utils.readBitString(der);
391 A = utils.zeroPadToLength(A, 32);
392 } else {
393 A = utils.calculateED25519Public(k);
394 }
395
396 var key = {
397 type: 'ed25519',
398 parts: [
399 { name: 'A', data: utils.zeroPadToLength(A, 32) },
400 { name: 'k', data: utils.zeroPadToLength(k, 32) }
401 ]
402 };
403
404 return (new PrivateKey(key));
405}
406
407function readPkcs8X25519Private(der) {
408 if (der.peek() === 0x00)
409 der.readByte();
410
411 der.readSequence(asn1.Ber.OctetString);
412 var k = der.readString(asn1.Ber.OctetString, true);
413 k = utils.zeroPadToLength(k, 32);
414
415 var A = utils.calculateX25519Public(k);
416
417 var key = {
418 type: 'curve25519',
419 parts: [
420 { name: 'A', data: utils.zeroPadToLength(A, 32) },
421 { name: 'k', data: utils.zeroPadToLength(k, 32) }
422 ]
423 };
424
425 return (new PrivateKey(key));
426}
427
428function pkcs8ToBuffer(key) {
429 var der = new asn1.BerWriter();
430 writePkcs8(der, key);
431 return (der.buffer);
432}
433
434function writePkcs8(der, key) {
435 der.startSequence();
436
437 if (PrivateKey.isPrivateKey(key)) {
438 var sillyInt = Buffer.from([0]);
439 der.writeBuffer(sillyInt, asn1.Ber.Integer);
440 }
441
442 der.startSequence();
443 switch (key.type) {
444 case 'rsa':
445 der.writeOID('1.2.840.113549.1.1.1');
446 if (PrivateKey.isPrivateKey(key))
447 writePkcs8RSAPrivate(key, der);
448 else
449 writePkcs8RSAPublic(key, der);
450 break;
451 case 'dsa':
452 der.writeOID('1.2.840.10040.4.1');
453 if (PrivateKey.isPrivateKey(key))
454 writePkcs8DSAPrivate(key, der);
455 else
456 writePkcs8DSAPublic(key, der);
457 break;
458 case 'ecdsa':
459 der.writeOID('1.2.840.10045.2.1');
460 if (PrivateKey.isPrivateKey(key))
461 writePkcs8ECDSAPrivate(key, der);
462 else
463 writePkcs8ECDSAPublic(key, der);
464 break;
465 case 'ed25519':
466 der.writeOID('1.3.101.112');
467 if (PrivateKey.isPrivateKey(key))
468 throw (new Error('Ed25519 private keys in pkcs8 ' +
469 'format are not supported'));
470 writePkcs8EdDSAPublic(key, der);
471 break;
472 default:
473 throw (new Error('Unsupported key type: ' + key.type));
474 }
475
476 der.endSequence();
477}
478
479function writePkcs8RSAPrivate(key, der) {
480 der.writeNull();
481 der.endSequence();
482
483 der.startSequence(asn1.Ber.OctetString);
484 der.startSequence();
485
486 var version = Buffer.from([0]);
487 der.writeBuffer(version, asn1.Ber.Integer);
488
489 der.writeBuffer(key.part.n.data, asn1.Ber.Integer);
490 der.writeBuffer(key.part.e.data, asn1.Ber.Integer);
491 der.writeBuffer(key.part.d.data, asn1.Ber.Integer);
492 der.writeBuffer(key.part.p.data, asn1.Ber.Integer);
493 der.writeBuffer(key.part.q.data, asn1.Ber.Integer);
494 if (!key.part.dmodp || !key.part.dmodq)
495 utils.addRSAMissing(key);
496 der.writeBuffer(key.part.dmodp.data, asn1.Ber.Integer);
497 der.writeBuffer(key.part.dmodq.data, asn1.Ber.Integer);
498 der.writeBuffer(key.part.iqmp.data, asn1.Ber.Integer);
499
500 der.endSequence();
501 der.endSequence();
502}
503
504function writePkcs8RSAPublic(key, der) {
505 der.writeNull();
506 der.endSequence();
507
508 der.startSequence(asn1.Ber.BitString);
509 der.writeByte(0x00);
510
511 der.startSequence();
512 der.writeBuffer(key.part.n.data, asn1.Ber.Integer);
513 der.writeBuffer(key.part.e.data, asn1.Ber.Integer);
514 der.endSequence();
515
516 der.endSequence();
517}
518
519function writePkcs8DSAPrivate(key, der) {
520 der.startSequence();
521 der.writeBuffer(key.part.p.data, asn1.Ber.Integer);
522 der.writeBuffer(key.part.q.data, asn1.Ber.Integer);
523 der.writeBuffer(key.part.g.data, asn1.Ber.Integer);
524 der.endSequence();
525
526 der.endSequence();
527
528 der.startSequence(asn1.Ber.OctetString);
529 der.writeBuffer(key.part.x.data, asn1.Ber.Integer);
530 der.endSequence();
531}
532
533function writePkcs8DSAPublic(key, der) {
534 der.startSequence();
535 der.writeBuffer(key.part.p.data, asn1.Ber.Integer);
536 der.writeBuffer(key.part.q.data, asn1.Ber.Integer);
537 der.writeBuffer(key.part.g.data, asn1.Ber.Integer);
538 der.endSequence();
539 der.endSequence();
540
541 der.startSequence(asn1.Ber.BitString);
542 der.writeByte(0x00);
543 der.writeBuffer(key.part.y.data, asn1.Ber.Integer);
544 der.endSequence();
545}
546
547function writeECDSACurve(key, der) {
548 var curve = algs.curves[key.curve];
549 if (curve.pkcs8oid) {
550 /* This one has a name in pkcs#8, so just write the oid */
551 der.writeOID(curve.pkcs8oid);
552
553 } else {
554 // ECParameters sequence
555 der.startSequence();
556
557 var version = Buffer.from([1]);
558 der.writeBuffer(version, asn1.Ber.Integer);
559
560 // FieldID sequence
561 der.startSequence();
562 der.writeOID('1.2.840.10045.1.1'); // prime-field
563 der.writeBuffer(curve.p, asn1.Ber.Integer);
564 der.endSequence();
565
566 // Curve sequence
567 der.startSequence();
568 var a = curve.p;
569 if (a[0] === 0x0)
570 a = a.slice(1);
571 der.writeBuffer(a, asn1.Ber.OctetString);
572 der.writeBuffer(curve.b, asn1.Ber.OctetString);
573 der.writeBuffer(curve.s, asn1.Ber.BitString);
574 der.endSequence();
575
576 der.writeBuffer(curve.G, asn1.Ber.OctetString);
577 der.writeBuffer(curve.n, asn1.Ber.Integer);
578 var h = curve.h;
579 if (!h) {
580 h = Buffer.from([1]);
581 }
582 der.writeBuffer(h, asn1.Ber.Integer);
583
584 // ECParameters
585 der.endSequence();
586 }
587}
588
589function writePkcs8ECDSAPublic(key, der) {
590 writeECDSACurve(key, der);
591 der.endSequence();
592
593 var Q = utils.ecNormalize(key.part.Q.data, true);
594 der.writeBuffer(Q, asn1.Ber.BitString);
595}
596
597function writePkcs8ECDSAPrivate(key, der) {
598 writeECDSACurve(key, der);
599 der.endSequence();
600
601 der.startSequence(asn1.Ber.OctetString);
602 der.startSequence();
603
604 var version = Buffer.from([1]);
605 der.writeBuffer(version, asn1.Ber.Integer);
606
607 der.writeBuffer(key.part.d.data, asn1.Ber.OctetString);
608
609 der.startSequence(0xa1);
610 var Q = utils.ecNormalize(key.part.Q.data, true);
611 der.writeBuffer(Q, asn1.Ber.BitString);
612 der.endSequence();
613
614 der.endSequence();
615 der.endSequence();
616}
617
618function writePkcs8EdDSAPublic(key, der) {
619 der.endSequence();
620
621 utils.writeBitString(der, key.part.A.data);
622}
623
624function writePkcs8EdDSAPrivate(key, der) {
625 der.endSequence();
626
627 var k = utils.mpNormalize(key.part.k.data, true);
628 der.startSequence(asn1.Ber.OctetString);
629 der.writeBuffer(k, asn1.Ber.OctetString);
630 der.endSequence();
631}
Note: See TracBrowser for help on using the repository browser.