pki.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625
  1. 'use strict';
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. // **Github:** https://github.com/fidm/x509
  4. //
  5. // **License:** MIT
  6. const util_1 = require("util");
  7. const crypto_1 = require("crypto");
  8. const tweetnacl_1 = require("tweetnacl");
  9. const asn1_1 = require("@fidm/asn1");
  10. const common_1 = require("./common");
  11. /**
  12. * ASN.1 Template for PKCS#8 Public Key.
  13. */
  14. exports.publicKeyValidator = {
  15. name: 'PublicKeyInfo',
  16. class: asn1_1.Class.UNIVERSAL,
  17. tag: asn1_1.Tag.SEQUENCE,
  18. capture: 'publicKeyInfo',
  19. value: [{
  20. name: 'PublicKeyInfo.AlgorithmIdentifier',
  21. class: asn1_1.Class.UNIVERSAL,
  22. tag: asn1_1.Tag.SEQUENCE,
  23. value: [{
  24. name: 'PublicKeyAlgorithmIdentifier.algorithm',
  25. class: asn1_1.Class.UNIVERSAL,
  26. tag: asn1_1.Tag.OID,
  27. capture: 'publicKeyOID',
  28. }],
  29. }, {
  30. name: 'PublicKeyInfo.PublicKey',
  31. class: asn1_1.Class.UNIVERSAL,
  32. tag: asn1_1.Tag.BITSTRING,
  33. capture: 'publicKey',
  34. }],
  35. };
  36. /**
  37. * ASN.1 Template for PKCS#8 Private Key. https://tools.ietf.org/html/rfc5208
  38. */
  39. exports.privateKeyValidator = {
  40. name: 'PrivateKeyInfo',
  41. class: asn1_1.Class.UNIVERSAL,
  42. tag: asn1_1.Tag.SEQUENCE,
  43. capture: 'privateKeyInfo',
  44. value: [{
  45. name: 'PrivateKeyInfo.Version',
  46. class: asn1_1.Class.UNIVERSAL,
  47. tag: asn1_1.Tag.INTEGER,
  48. capture: 'privateKeyVersion',
  49. }, {
  50. name: 'PrivateKeyInfo.AlgorithmIdentifier',
  51. class: asn1_1.Class.UNIVERSAL,
  52. tag: asn1_1.Tag.SEQUENCE,
  53. value: [{
  54. name: 'PrivateKeyAlgorithmIdentifier.algorithm',
  55. class: asn1_1.Class.UNIVERSAL,
  56. tag: asn1_1.Tag.OID,
  57. capture: 'privateKeyOID',
  58. }],
  59. }, {
  60. name: 'PrivateKeyInfo.PrivateKey',
  61. class: asn1_1.Class.UNIVERSAL,
  62. tag: asn1_1.Tag.OCTETSTRING,
  63. capture: 'privateKey',
  64. }],
  65. };
  66. // validator for an RSA public key
  67. const rsaPublicKeyValidator = {
  68. // RSAPublicKey
  69. name: 'RSAPublicKey',
  70. class: asn1_1.Class.UNIVERSAL,
  71. tag: asn1_1.Tag.SEQUENCE,
  72. value: [{
  73. // modulus (n)
  74. name: 'RSAPublicKey.modulus',
  75. class: asn1_1.Class.UNIVERSAL,
  76. tag: asn1_1.Tag.INTEGER,
  77. capture: 'publicKeyModulus',
  78. }, {
  79. // publicExponent (e)
  80. name: 'RSAPublicKey.exponent',
  81. class: asn1_1.Class.UNIVERSAL,
  82. tag: asn1_1.Tag.INTEGER,
  83. capture: 'publicKeyExponent',
  84. }],
  85. };
  86. const rsaPrivateKeyValidator = {
  87. // RSAPrivateKey
  88. name: 'RSAPrivateKey',
  89. class: asn1_1.Class.UNIVERSAL,
  90. tag: asn1_1.Tag.SEQUENCE,
  91. value: [{
  92. // Version (INTEGER)
  93. name: 'RSAPrivateKey.version',
  94. class: asn1_1.Class.UNIVERSAL,
  95. tag: asn1_1.Tag.INTEGER,
  96. capture: 'privateKeyVersion',
  97. }, {
  98. // modulus (n)
  99. name: 'RSAPrivateKey.modulus',
  100. class: asn1_1.Class.UNIVERSAL,
  101. tag: asn1_1.Tag.INTEGER,
  102. capture: 'privateKeyModulus',
  103. }, {
  104. // publicExponent (e)
  105. name: 'RSAPrivateKey.publicExponent',
  106. class: asn1_1.Class.UNIVERSAL,
  107. tag: asn1_1.Tag.INTEGER,
  108. capture: 'privateKeyPublicExponent',
  109. }, {
  110. // privateExponent (d)
  111. name: 'RSAPrivateKey.privateExponent',
  112. class: asn1_1.Class.UNIVERSAL,
  113. tag: asn1_1.Tag.INTEGER,
  114. capture: 'privateKeyPrivateExponent',
  115. }, {
  116. // prime1 (p)
  117. name: 'RSAPrivateKey.prime1',
  118. class: asn1_1.Class.UNIVERSAL,
  119. tag: asn1_1.Tag.INTEGER,
  120. capture: 'privateKeyPrime1',
  121. }, {
  122. // prime2 (q)
  123. name: 'RSAPrivateKey.prime2',
  124. class: asn1_1.Class.UNIVERSAL,
  125. tag: asn1_1.Tag.INTEGER,
  126. capture: 'privateKeyPrime2',
  127. }, {
  128. // exponent1 (d mod (p-1))
  129. name: 'RSAPrivateKey.exponent1',
  130. class: asn1_1.Class.UNIVERSAL,
  131. tag: asn1_1.Tag.INTEGER,
  132. capture: 'privateKeyExponent1',
  133. }, {
  134. // exponent2 (d mod (q-1))
  135. name: 'RSAPrivateKey.exponent2',
  136. class: asn1_1.Class.UNIVERSAL,
  137. tag: asn1_1.Tag.INTEGER,
  138. capture: 'privateKeyExponent2',
  139. }, {
  140. // coefficient ((inverse of q) mod p)
  141. name: 'RSAPrivateKey.coefficient',
  142. class: asn1_1.Class.UNIVERSAL,
  143. tag: asn1_1.Tag.INTEGER,
  144. capture: 'privateKeyCoefficient',
  145. }],
  146. };
  147. const EdDSAPrivateKeyOIDs = [
  148. // https://tools.ietf.org/html/draft-ietf-curdle-pkix-10
  149. common_1.getOID('X25519'),
  150. common_1.getOID('X448'),
  151. common_1.getOID('Ed25519'),
  152. common_1.getOID('Ed448'),
  153. ];
  154. /**
  155. * PKCS#8 Public Key
  156. */
  157. class PublicKey {
  158. constructor(obj) {
  159. const captures = {};
  160. const err = obj.validate(exports.publicKeyValidator, captures);
  161. if (err != null) {
  162. throw new Error('Cannot read X.509 public key: ' + err.message);
  163. }
  164. this.oid = asn1_1.ASN1.parseOID(captures.publicKeyOID.bytes);
  165. this.algo = common_1.getOIDName(this.oid);
  166. this._pkcs8 = obj;
  167. this._keyRaw = asn1_1.ASN1.parseBitString(captures.publicKey.bytes).buf;
  168. this._finalKey = this._keyRaw;
  169. this._finalPEM = '';
  170. }
  171. /**
  172. * Parse an PublicKey for X.509 certificate from PKCS#8 PEM formatted buffer or PKCS#1 RSA PEM formatted buffer.
  173. * @param pem PEM formatted buffer
  174. */
  175. static fromPEM(pem) {
  176. const msg = asn1_1.PEM.parse(pem)[0];
  177. if (msg.procType.includes('ENCRYPTED')) {
  178. throw new Error('Could not convert public key from PEM, PEM is encrypted.');
  179. }
  180. const obj = asn1_1.ASN1.fromDER(msg.body, true);
  181. switch (msg.type) {
  182. case 'PUBLIC KEY': // PKCS#8
  183. return new PublicKey(obj);
  184. case 'RSA PUBLIC KEY': // PKCS#1
  185. const _pkcs8 = asn1_1.ASN1.Seq([
  186. // AlgorithmIdentifier
  187. asn1_1.ASN1.Seq([
  188. // algorithm
  189. asn1_1.ASN1.OID(common_1.getOID('rsaEncryption')),
  190. // optional parameters
  191. asn1_1.ASN1.Null(),
  192. ]),
  193. // PublicKey
  194. asn1_1.ASN1.BitString(obj.DER),
  195. ]);
  196. return new PublicKey(_pkcs8);
  197. default:
  198. throw new Error('Could not convert public key from PEM, recommend PKCS#8 PEM');
  199. }
  200. }
  201. /**
  202. * Registers an external Verifier with object identifier.
  203. * Built-in verifiers: Ed25519, RSA, others see https://nodejs.org/api/crypto.html#crypto_class_verify
  204. * ```js
  205. * PublicKey.addVerifier(getOID('Ed25519'), function (this: PublicKey, data: Buffer, signature: Buffer): boolean {
  206. * return ed25519.detached.verify(data, signature, this.keyRaw)
  207. * })
  208. * ```
  209. * @param oid algorithm object identifier
  210. * @param fn Verifier function
  211. */
  212. static addVerifier(oid, fn) {
  213. oid = common_1.getOID(oid);
  214. if (oid === '') {
  215. throw new Error(`Invalid object identifier: ${oid}`);
  216. }
  217. if (PublicKey._verifiers[oid] != null) {
  218. throw new Error(`Verifier ${oid} exists`);
  219. }
  220. PublicKey._verifiers[oid] = fn;
  221. }
  222. /**
  223. * underlying key buffer
  224. */
  225. get keyRaw() {
  226. return this._finalKey;
  227. }
  228. /**
  229. * Returns true if the provided data and the given signature matched.
  230. * ```js
  231. * certificate.publicKey.verify(data, signature, 'sha256') // => true or false
  232. * ```
  233. * @param data data to verify
  234. * @param signature signature that signed by private key
  235. * @param hashAlgorithm hash algorithm, such as 'sha256', 'sha1'
  236. */
  237. verify(data, signature, hashAlgorithm) {
  238. const verifier = PublicKey._verifiers[this.oid];
  239. if (verifier != null) {
  240. const sum = crypto_1.createHash(hashAlgorithm).update(data).digest();
  241. return verifier.call(this, sum, signature);
  242. }
  243. const verify = crypto_1.createVerify(hashAlgorithm);
  244. verify.update(data);
  245. return verify.verify(this.toPEM(), signature);
  246. }
  247. /**
  248. * Returns the digest of the PublicKey with given hash algorithm.
  249. * ```js
  250. * certificate.publicKey.getFingerprint('sha1', 'PublicKey') // => Buffer
  251. * ```
  252. * @param hashAlgorithm hash algorithm, such as 'sha256', 'sha1'
  253. * @param type 'PublicKey' or 'PublicKeyInfo'
  254. */
  255. getFingerprint(hashAlgorithm, type = 'PublicKey') {
  256. let bytes;
  257. switch (type) {
  258. case 'PublicKeyInfo':
  259. bytes = this._pkcs8.DER;
  260. break;
  261. case 'PublicKey':
  262. bytes = this._keyRaw;
  263. break;
  264. default:
  265. throw new Error(`Unknown fingerprint type "${type}".`);
  266. }
  267. const hasher = crypto_1.createHash(hashAlgorithm);
  268. hasher.update(bytes);
  269. return hasher.digest();
  270. }
  271. /**
  272. * Returns an ASN.1 object of this PublicKey
  273. */
  274. toASN1() {
  275. return this._pkcs8;
  276. }
  277. /**
  278. * Returns an DER formatted buffer of this PublicKey
  279. */
  280. toDER() {
  281. return this._pkcs8.DER;
  282. }
  283. /**
  284. * Returns an PEM formatted string of this PublicKey
  285. */
  286. toPEM() {
  287. if (this._finalPEM === '') {
  288. this._finalPEM = new asn1_1.PEM('PUBLIC KEY', this._pkcs8.DER).toString();
  289. }
  290. return this._finalPEM;
  291. }
  292. /**
  293. * Return a friendly JSON object for debuging.
  294. */
  295. toJSON() {
  296. return {
  297. oid: this.oid,
  298. algo: this.algo,
  299. publicKey: this._keyRaw,
  300. };
  301. }
  302. [util_1.inspect.custom](_depth, options) {
  303. return `<${this.constructor.name} ${util_1.inspect(this.toJSON(), options)}>`;
  304. }
  305. }
  306. PublicKey._verifiers = Object.create(null);
  307. exports.PublicKey = PublicKey;
  308. /**
  309. * PKCS#8 Private Key
  310. */
  311. class PrivateKey {
  312. constructor(obj) {
  313. // get RSA params
  314. const captures = Object.create(null);
  315. const err = obj.validate(exports.privateKeyValidator, captures);
  316. if (err != null) {
  317. throw new Error('Cannot read X.509 private key: ' + err.message);
  318. }
  319. this.version = asn1_1.ASN1.parseIntegerNum(captures.privateKeyVersion.bytes) + 1;
  320. this.oid = asn1_1.ASN1.parseOID(captures.privateKeyOID.bytes);
  321. this.algo = common_1.getOIDName(this.oid);
  322. this._pkcs8 = obj;
  323. this._keyRaw = captures.privateKey.bytes;
  324. this._publicKeyRaw = null;
  325. this._finalKey = this._keyRaw;
  326. this._finalPEM = '';
  327. if (EdDSAPrivateKeyOIDs.includes(this.oid)) {
  328. this._finalKey = this._keyRaw = asn1_1.ASN1.parseDER(this._keyRaw, asn1_1.Class.UNIVERSAL, asn1_1.Tag.OCTETSTRING).bytes;
  329. if (this.oid === '1.3.101.112') {
  330. const keypair = tweetnacl_1.sign.keyPair.fromSeed(this._keyRaw);
  331. this._publicKeyRaw = Buffer.from(keypair.publicKey);
  332. this._finalKey = Buffer.from(keypair.secretKey);
  333. }
  334. else if (this.version === 2) {
  335. for (const val of obj.mustCompound()) {
  336. if (val.class === asn1_1.Class.CONTEXT_SPECIFIC && val.tag === 1) {
  337. this._publicKeyRaw = asn1_1.ASN1.parseBitString(val.bytes).buf;
  338. this._finalKey = Buffer.concat([this._keyRaw, this._publicKeyRaw]);
  339. }
  340. }
  341. }
  342. }
  343. }
  344. /**
  345. * Parse an PrivateKey for X.509 certificate from PKCS#8 PEM formatted buffer or PKCS#1 RSA PEM formatted buffer.
  346. * @param pem PEM formatted buffer
  347. */
  348. static fromPEM(pem) {
  349. const msg = asn1_1.PEM.parse(pem)[0];
  350. if (msg.procType.includes('ENCRYPTED')) {
  351. throw new Error('Could not convert private key from PEM, PEM is encrypted.');
  352. }
  353. let obj = asn1_1.ASN1.fromDER(msg.body, true);
  354. switch (msg.type) {
  355. case 'PRIVATE KEY': // PKCS#8
  356. return new PrivateKey(obj);
  357. case 'RSA PRIVATE KEY': // PKCS#1
  358. obj = asn1_1.ASN1.Seq([
  359. // Version (INTEGER)
  360. obj.value[0],
  361. // AlgorithmIdentifier
  362. asn1_1.ASN1.Seq([
  363. // algorithm
  364. asn1_1.ASN1.OID(common_1.getOID('rsaEncryption')),
  365. // optional parameters
  366. asn1_1.ASN1.Null(),
  367. ]),
  368. // PrivateKey
  369. new asn1_1.ASN1(asn1_1.Class.UNIVERSAL, asn1_1.Tag.OCTETSTRING, obj.DER),
  370. ]);
  371. return new PrivateKey(obj);
  372. default:
  373. throw new Error('Could not convert private key from PEM, recommend PKCS#8 PEM');
  374. }
  375. }
  376. /**
  377. * Registers an external Signer with object identifier.
  378. * Built-in verifiers: Ed25519, RSA, others see https://nodejs.org/api/crypto.html#crypto_class_sign
  379. * ```js
  380. * PrivateKey.addSigner(getOID('Ed25519'), function (this: PrivateKey, data: Buffer): Buffer {
  381. * const key = this.keyRaw
  382. * if (key.length !== 64) {
  383. * throw new Error('Invalid signing key.')
  384. * }
  385. * return Buffer.from(ed25519.detached(data, key))
  386. * })
  387. * ```
  388. * @param oid algorithm object identifier
  389. * @param fn Verifier function
  390. */
  391. static addSigner(oid, fn) {
  392. oid = common_1.getOID(oid);
  393. if (oid === '') {
  394. throw new Error(`Invalid object identifier: ${oid}`);
  395. }
  396. if (PrivateKey._signers[oid] != null) {
  397. throw new Error(`Signer ${oid} exists`);
  398. }
  399. PrivateKey._signers[oid] = fn;
  400. }
  401. /**
  402. * underlying key buffer
  403. */
  404. get keyRaw() {
  405. return this._finalKey;
  406. }
  407. /**
  408. * Returns publicKey buffer, it is used for Ed25519/Ed448.
  409. */
  410. get publicKeyRaw() {
  411. return this._publicKeyRaw;
  412. }
  413. /**
  414. * Returns signature for the given data and hash algorithm.
  415. * @param data
  416. * @param hashAlgorithm
  417. */
  418. sign(data, hashAlgorithm) {
  419. const signer = PrivateKey._signers[this.oid];
  420. if (signer != null) {
  421. const sum = crypto_1.createHash(hashAlgorithm).update(data).digest();
  422. return signer.call(this, sum);
  423. }
  424. const sign = crypto_1.createSign(hashAlgorithm);
  425. sign.update(data);
  426. return sign.sign(this.toPEM());
  427. }
  428. /**
  429. * Returns an ASN.1 object of this PrivateKey
  430. */
  431. toASN1() {
  432. return this._pkcs8;
  433. }
  434. /**
  435. * Returns an DER formatted buffer of this PrivateKey
  436. */
  437. toDER() {
  438. return this._pkcs8.DER;
  439. }
  440. /**
  441. * Returns an PEM formatted string of this PrivateKey
  442. */
  443. toPEM() {
  444. if (this._finalPEM === '') {
  445. this._finalPEM = new asn1_1.PEM('PRIVATE KEY', this._pkcs8.DER).toString();
  446. }
  447. return this._finalPEM;
  448. }
  449. /**
  450. * Return a friendly JSON object for debuging.
  451. */
  452. toJSON() {
  453. return {
  454. version: this.version,
  455. oid: this.oid,
  456. algo: this.algo,
  457. privateKey: this._keyRaw,
  458. publicKey: this._publicKeyRaw,
  459. };
  460. }
  461. [util_1.inspect.custom](_depth, options) {
  462. return `<${this.constructor.name} ${util_1.inspect(this.toJSON(), options)}>`;
  463. }
  464. }
  465. PrivateKey._signers = Object.create(null);
  466. exports.PrivateKey = PrivateKey;
  467. /**
  468. * PKCS#1 RSA Public Key
  469. */
  470. class RSAPublicKey extends PublicKey {
  471. static fromPublicKey(publicKey) {
  472. return new RSAPublicKey(publicKey.toASN1());
  473. }
  474. constructor(obj) {
  475. super(obj);
  476. if (common_1.getOID(this.oid) !== common_1.getOID('rsaEncryption')) {
  477. throw new Error(`Invalid RSA public key, unknown OID: ${this.oid}`);
  478. }
  479. // get RSA params
  480. const captures = Object.create(null);
  481. this._pkcs1 = asn1_1.ASN1.fromDER(this._keyRaw, true);
  482. const err = this._pkcs1.validate(rsaPublicKeyValidator, captures);
  483. if (err != null) {
  484. throw new Error('Cannot read RSA public key: ' + err.message);
  485. }
  486. this.modulus = asn1_1.ASN1.parseIntegerStr(captures.publicKeyModulus.bytes);
  487. this.exponent = asn1_1.ASN1.parseIntegerNum(captures.publicKeyExponent.bytes);
  488. }
  489. /**
  490. * Returns an PKCS#1 ASN.1 object of this RSAPublicKey
  491. */
  492. toASN1() {
  493. return this._pkcs1;
  494. }
  495. /**
  496. * Returns an PKCS#1 DER formatted buffer of this RSAPublicKey
  497. */
  498. toDER() {
  499. return this._keyRaw;
  500. }
  501. /**
  502. * Returns an PKCS#1 PEM formatted string of this RSAPublicKey
  503. */
  504. toPEM() {
  505. if (this._finalPEM === '') {
  506. this._finalPEM = new asn1_1.PEM('RSA PUBLIC KEY', this._keyRaw).toString();
  507. }
  508. return this._finalPEM;
  509. }
  510. /**
  511. * Returns an PKCS#8 PEM formatted string of this RSAPublicKey
  512. */
  513. toPublicKeyPEM() {
  514. return new asn1_1.PEM('PUBLIC KEY', this._pkcs8.DER).toString();
  515. }
  516. /**
  517. * Return a friendly JSON object for debuging.
  518. */
  519. toJSON() {
  520. return {
  521. oid: this.oid,
  522. algo: this.algo,
  523. modulus: trimLeadingZeroByte(this.modulus),
  524. exponent: this.exponent,
  525. };
  526. }
  527. [util_1.inspect.custom](_depth, options) {
  528. return `<${this.constructor.name} ${util_1.inspect(this.toJSON(), options)}>`;
  529. }
  530. }
  531. exports.RSAPublicKey = RSAPublicKey;
  532. /**
  533. * PKCS#1 RSA Private Key
  534. */
  535. class RSAPrivateKey extends PrivateKey {
  536. static fromPrivateKey(privateKey) {
  537. return new RSAPrivateKey(privateKey.toASN1());
  538. }
  539. constructor(obj) {
  540. super(obj);
  541. if (common_1.getOID(this.oid) !== common_1.getOID('rsaEncryption')) {
  542. throw new Error(`Invalid RSA private key, unknown OID: ${this.oid}`);
  543. }
  544. // get RSA params
  545. const captures = Object.create(null);
  546. this._pkcs1 = asn1_1.ASN1.fromDER(this._keyRaw, true);
  547. const err = this._pkcs1.validate(rsaPrivateKeyValidator, captures);
  548. if (err != null) {
  549. throw new Error('Cannot read RSA private key: ' + err.message);
  550. }
  551. this.publicExponent = asn1_1.ASN1.parseIntegerNum(captures.privateKeyPublicExponent.bytes);
  552. this.privateExponent = asn1_1.ASN1.parseIntegerStr(captures.privateKeyPrivateExponent.bytes);
  553. this.modulus = asn1_1.ASN1.parseIntegerStr(captures.privateKeyModulus.bytes);
  554. this.prime1 = asn1_1.ASN1.parseIntegerStr(captures.privateKeyPrime1.bytes);
  555. this.prime2 = asn1_1.ASN1.parseIntegerStr(captures.privateKeyPrime2.bytes);
  556. this.exponent1 = asn1_1.ASN1.parseIntegerStr(captures.privateKeyExponent1.bytes);
  557. this.exponent2 = asn1_1.ASN1.parseIntegerStr(captures.privateKeyExponent2.bytes);
  558. this.coefficient = asn1_1.ASN1.parseIntegerStr(captures.privateKeyCoefficient.bytes);
  559. }
  560. /**
  561. * Returns an PKCS#1 ASN.1 object of this RSAPrivateKey
  562. */
  563. toASN1() {
  564. return this._pkcs1;
  565. }
  566. /**
  567. * Returns an PKCS#1 DER formatted buffer of this RSAPrivateKey
  568. */
  569. toDER() {
  570. return this._keyRaw;
  571. }
  572. /**
  573. * Returns an PKCS#1 PEM formatted string of this RSAPrivateKey
  574. */
  575. toPEM() {
  576. if (this._finalPEM === '') {
  577. this._finalPEM = new asn1_1.PEM('RSA PRIVATE KEY', this._keyRaw).toString();
  578. }
  579. return this._finalPEM;
  580. }
  581. /**
  582. * Returns an PKCS#8 PEM formatted string of this RSAPrivateKey
  583. */
  584. toPrivateKeyPEM() {
  585. return new asn1_1.PEM('PRIVATE KEY', this._pkcs8.DER).toString();
  586. }
  587. /**
  588. * Return a friendly JSON object for debuging.
  589. */
  590. toJSON() {
  591. return {
  592. version: this.version,
  593. oid: this.oid,
  594. algo: this.algo,
  595. publicExponent: this.publicExponent,
  596. privateExponent: trimLeadingZeroByte(this.privateExponent),
  597. modulus: trimLeadingZeroByte(this.modulus),
  598. prime1: trimLeadingZeroByte(this.prime1),
  599. prime2: trimLeadingZeroByte(this.prime2),
  600. exponent1: trimLeadingZeroByte(this.exponent1),
  601. exponent2: trimLeadingZeroByte(this.exponent2),
  602. coefficient: trimLeadingZeroByte(this.coefficient),
  603. };
  604. }
  605. [util_1.inspect.custom](_depth, options) {
  606. return `<${this.constructor.name} ${util_1.inspect(this.toJSON(), options)}>`;
  607. }
  608. }
  609. exports.RSAPrivateKey = RSAPrivateKey;
  610. // leading 00 byte is signed representation for BigInteger
  611. // https://stackoverflow.com/questions/8515691/getting-1-byte-extra-in-the-modulus-rsa-key-and-sometimes-for-exponents-also
  612. function trimLeadingZeroByte(hex) {
  613. return (hex.length % 8 !== 0) && hex.startsWith('00') ? hex.slice(2) : hex;
  614. }
  615. PublicKey.addVerifier(common_1.getOID('Ed25519'), function (data, signature) {
  616. return tweetnacl_1.sign.detached.verify(data, signature, this.keyRaw);
  617. });
  618. PrivateKey.addSigner(common_1.getOID('Ed25519'), function (data) {
  619. const key = this.keyRaw;
  620. if (key.length !== 64) {
  621. throw new Error('Invalid signing key.');
  622. }
  623. return Buffer.from(tweetnacl_1.sign.detached(data, key));
  624. });
  625. //# sourceMappingURL=pki.js.map