pkcs1.js 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  1. // Copyright 2015 Joyent, Inc.
  2. module.exports = {
  3. read: read,
  4. readPkcs1: readPkcs1,
  5. write: write,
  6. writePkcs1: writePkcs1
  7. };
  8. var assert = require('assert-plus');
  9. var asn1 = require('asn1');
  10. var algs = require('../algs');
  11. var utils = require('../utils');
  12. var Key = require('../key');
  13. var PrivateKey = require('../private-key');
  14. var pem = require('./pem');
  15. var pkcs8 = require('./pkcs8');
  16. var readECDSACurve = pkcs8.readECDSACurve;
  17. function read(buf, options) {
  18. return (pem.read(buf, options, 'pkcs1'));
  19. }
  20. function write(key, options) {
  21. return (pem.write(key, options, 'pkcs1'));
  22. }
  23. /* Helper to read in a single mpint */
  24. function readMPInt(der, nm) {
  25. assert.strictEqual(der.peek(), asn1.Ber.Integer,
  26. nm + ' is not an Integer');
  27. return (utils.mpNormalize(der.readString(asn1.Ber.Integer, true)));
  28. }
  29. function readPkcs1(alg, type, der) {
  30. switch (alg) {
  31. case 'RSA':
  32. if (type === 'public')
  33. return (readPkcs1RSAPublic(der));
  34. else if (type === 'private')
  35. return (readPkcs1RSAPrivate(der));
  36. throw (new Error('Unknown key type: ' + type));
  37. case 'DSA':
  38. if (type === 'public')
  39. return (readPkcs1DSAPublic(der));
  40. else if (type === 'private')
  41. return (readPkcs1DSAPrivate(der));
  42. throw (new Error('Unknown key type: ' + type));
  43. case 'EC':
  44. case 'ECDSA':
  45. if (type === 'private')
  46. return (readPkcs1ECDSAPrivate(der));
  47. else if (type === 'public')
  48. return (readPkcs1ECDSAPublic(der));
  49. throw (new Error('Unknown key type: ' + type));
  50. case 'EDDSA':
  51. case 'EdDSA':
  52. if (type === 'private')
  53. return (readPkcs1EdDSAPrivate(der));
  54. throw (new Error(type + ' keys not supported with EdDSA'));
  55. default:
  56. throw (new Error('Unknown key algo: ' + alg));
  57. }
  58. }
  59. function readPkcs1RSAPublic(der) {
  60. // modulus and exponent
  61. var n = readMPInt(der, 'modulus');
  62. var e = readMPInt(der, 'exponent');
  63. // now, make the key
  64. var key = {
  65. type: 'rsa',
  66. parts: [
  67. { name: 'e', data: e },
  68. { name: 'n', data: n }
  69. ]
  70. };
  71. return (new Key(key));
  72. }
  73. function readPkcs1RSAPrivate(der) {
  74. var version = readMPInt(der, 'version');
  75. assert.strictEqual(version[0], 0);
  76. // modulus then public exponent
  77. var n = readMPInt(der, 'modulus');
  78. var e = readMPInt(der, 'public exponent');
  79. var d = readMPInt(der, 'private exponent');
  80. var p = readMPInt(der, 'prime1');
  81. var q = readMPInt(der, 'prime2');
  82. var dmodp = readMPInt(der, 'exponent1');
  83. var dmodq = readMPInt(der, 'exponent2');
  84. var iqmp = readMPInt(der, 'iqmp');
  85. // now, make the key
  86. var key = {
  87. type: 'rsa',
  88. parts: [
  89. { name: 'n', data: n },
  90. { name: 'e', data: e },
  91. { name: 'd', data: d },
  92. { name: 'iqmp', data: iqmp },
  93. { name: 'p', data: p },
  94. { name: 'q', data: q },
  95. { name: 'dmodp', data: dmodp },
  96. { name: 'dmodq', data: dmodq }
  97. ]
  98. };
  99. return (new PrivateKey(key));
  100. }
  101. function readPkcs1DSAPrivate(der) {
  102. var version = readMPInt(der, 'version');
  103. assert.strictEqual(version.readUInt8(0), 0);
  104. var p = readMPInt(der, 'p');
  105. var q = readMPInt(der, 'q');
  106. var g = readMPInt(der, 'g');
  107. var y = readMPInt(der, 'y');
  108. var x = readMPInt(der, 'x');
  109. // now, make the key
  110. var key = {
  111. type: 'dsa',
  112. parts: [
  113. { name: 'p', data: p },
  114. { name: 'q', data: q },
  115. { name: 'g', data: g },
  116. { name: 'y', data: y },
  117. { name: 'x', data: x }
  118. ]
  119. };
  120. return (new PrivateKey(key));
  121. }
  122. function readPkcs1EdDSAPrivate(der) {
  123. var version = readMPInt(der, 'version');
  124. assert.strictEqual(version.readUInt8(0), 1);
  125. // private key
  126. var k = der.readString(asn1.Ber.OctetString, true);
  127. der.readSequence(0xa0);
  128. var oid = der.readOID();
  129. assert.strictEqual(oid, '1.3.101.112', 'the ed25519 curve identifier');
  130. der.readSequence(0xa1);
  131. var A = utils.readBitString(der);
  132. var key = {
  133. type: 'ed25519',
  134. parts: [
  135. { name: 'A', data: utils.zeroPadToLength(A, 32) },
  136. { name: 'k', data: k }
  137. ]
  138. };
  139. return (new PrivateKey(key));
  140. }
  141. function readPkcs1DSAPublic(der) {
  142. var y = readMPInt(der, 'y');
  143. var p = readMPInt(der, 'p');
  144. var q = readMPInt(der, 'q');
  145. var g = readMPInt(der, 'g');
  146. var key = {
  147. type: 'dsa',
  148. parts: [
  149. { name: 'y', data: y },
  150. { name: 'p', data: p },
  151. { name: 'q', data: q },
  152. { name: 'g', data: g }
  153. ]
  154. };
  155. return (new Key(key));
  156. }
  157. function readPkcs1ECDSAPublic(der) {
  158. der.readSequence();
  159. var oid = der.readOID();
  160. assert.strictEqual(oid, '1.2.840.10045.2.1', 'must be ecPublicKey');
  161. var curveOid = der.readOID();
  162. var curve;
  163. var curves = Object.keys(algs.curves);
  164. for (var j = 0; j < curves.length; ++j) {
  165. var c = curves[j];
  166. var cd = algs.curves[c];
  167. if (cd.pkcs8oid === curveOid) {
  168. curve = c;
  169. break;
  170. }
  171. }
  172. assert.string(curve, 'a known ECDSA named curve');
  173. var Q = der.readString(asn1.Ber.BitString, true);
  174. Q = utils.ecNormalize(Q);
  175. var key = {
  176. type: 'ecdsa',
  177. parts: [
  178. { name: 'curve', data: new Buffer(curve) },
  179. { name: 'Q', data: Q }
  180. ]
  181. };
  182. return (new Key(key));
  183. }
  184. function readPkcs1ECDSAPrivate(der) {
  185. var version = readMPInt(der, 'version');
  186. assert.strictEqual(version.readUInt8(0), 1);
  187. // private key
  188. var d = der.readString(asn1.Ber.OctetString, true);
  189. der.readSequence(0xa0);
  190. var curve = readECDSACurve(der);
  191. assert.string(curve, 'a known elliptic curve');
  192. der.readSequence(0xa1);
  193. var Q = der.readString(asn1.Ber.BitString, true);
  194. Q = utils.ecNormalize(Q);
  195. var key = {
  196. type: 'ecdsa',
  197. parts: [
  198. { name: 'curve', data: new Buffer(curve) },
  199. { name: 'Q', data: Q },
  200. { name: 'd', data: d }
  201. ]
  202. };
  203. return (new PrivateKey(key));
  204. }
  205. function writePkcs1(der, key) {
  206. der.startSequence();
  207. switch (key.type) {
  208. case 'rsa':
  209. if (PrivateKey.isPrivateKey(key))
  210. writePkcs1RSAPrivate(der, key);
  211. else
  212. writePkcs1RSAPublic(der, key);
  213. break;
  214. case 'dsa':
  215. if (PrivateKey.isPrivateKey(key))
  216. writePkcs1DSAPrivate(der, key);
  217. else
  218. writePkcs1DSAPublic(der, key);
  219. break;
  220. case 'ecdsa':
  221. if (PrivateKey.isPrivateKey(key))
  222. writePkcs1ECDSAPrivate(der, key);
  223. else
  224. writePkcs1ECDSAPublic(der, key);
  225. break;
  226. case 'ed25519':
  227. if (PrivateKey.isPrivateKey(key))
  228. writePkcs1EdDSAPrivate(der, key);
  229. else
  230. writePkcs1EdDSAPublic(der, key);
  231. break;
  232. default:
  233. throw (new Error('Unknown key algo: ' + key.type));
  234. }
  235. der.endSequence();
  236. }
  237. function writePkcs1RSAPublic(der, key) {
  238. der.writeBuffer(key.part.n.data, asn1.Ber.Integer);
  239. der.writeBuffer(key.part.e.data, asn1.Ber.Integer);
  240. }
  241. function writePkcs1RSAPrivate(der, key) {
  242. var ver = new Buffer(1);
  243. ver[0] = 0;
  244. der.writeBuffer(ver, asn1.Ber.Integer);
  245. der.writeBuffer(key.part.n.data, asn1.Ber.Integer);
  246. der.writeBuffer(key.part.e.data, asn1.Ber.Integer);
  247. der.writeBuffer(key.part.d.data, asn1.Ber.Integer);
  248. der.writeBuffer(key.part.p.data, asn1.Ber.Integer);
  249. der.writeBuffer(key.part.q.data, asn1.Ber.Integer);
  250. if (!key.part.dmodp || !key.part.dmodq)
  251. utils.addRSAMissing(key);
  252. der.writeBuffer(key.part.dmodp.data, asn1.Ber.Integer);
  253. der.writeBuffer(key.part.dmodq.data, asn1.Ber.Integer);
  254. der.writeBuffer(key.part.iqmp.data, asn1.Ber.Integer);
  255. }
  256. function writePkcs1DSAPrivate(der, key) {
  257. var ver = new Buffer(1);
  258. ver[0] = 0;
  259. der.writeBuffer(ver, asn1.Ber.Integer);
  260. der.writeBuffer(key.part.p.data, asn1.Ber.Integer);
  261. der.writeBuffer(key.part.q.data, asn1.Ber.Integer);
  262. der.writeBuffer(key.part.g.data, asn1.Ber.Integer);
  263. der.writeBuffer(key.part.y.data, asn1.Ber.Integer);
  264. der.writeBuffer(key.part.x.data, asn1.Ber.Integer);
  265. }
  266. function writePkcs1DSAPublic(der, key) {
  267. der.writeBuffer(key.part.y.data, asn1.Ber.Integer);
  268. der.writeBuffer(key.part.p.data, asn1.Ber.Integer);
  269. der.writeBuffer(key.part.q.data, asn1.Ber.Integer);
  270. der.writeBuffer(key.part.g.data, asn1.Ber.Integer);
  271. }
  272. function writePkcs1ECDSAPublic(der, key) {
  273. der.startSequence();
  274. der.writeOID('1.2.840.10045.2.1'); /* ecPublicKey */
  275. var curve = key.part.curve.data.toString();
  276. var curveOid = algs.curves[curve].pkcs8oid;
  277. assert.string(curveOid, 'a known ECDSA named curve');
  278. der.writeOID(curveOid);
  279. der.endSequence();
  280. var Q = utils.ecNormalize(key.part.Q.data, true);
  281. der.writeBuffer(Q, asn1.Ber.BitString);
  282. }
  283. function writePkcs1ECDSAPrivate(der, key) {
  284. var ver = new Buffer(1);
  285. ver[0] = 1;
  286. der.writeBuffer(ver, asn1.Ber.Integer);
  287. der.writeBuffer(key.part.d.data, asn1.Ber.OctetString);
  288. der.startSequence(0xa0);
  289. var curve = key.part.curve.data.toString();
  290. var curveOid = algs.curves[curve].pkcs8oid;
  291. assert.string(curveOid, 'a known ECDSA named curve');
  292. der.writeOID(curveOid);
  293. der.endSequence();
  294. der.startSequence(0xa1);
  295. var Q = utils.ecNormalize(key.part.Q.data, true);
  296. der.writeBuffer(Q, asn1.Ber.BitString);
  297. der.endSequence();
  298. }
  299. function writePkcs1EdDSAPrivate(der, key) {
  300. var ver = new Buffer(1);
  301. ver[0] = 1;
  302. der.writeBuffer(ver, asn1.Ber.Integer);
  303. der.writeBuffer(key.part.k.data, asn1.Ber.OctetString);
  304. der.startSequence(0xa0);
  305. der.writeOID('1.3.101.112');
  306. der.endSequence();
  307. der.startSequence(0xa1);
  308. utils.writeBitString(der, key.part.A.data);
  309. der.endSequence();
  310. }
  311. function writePkcs1EdDSAPublic(der, key) {
  312. throw (new Error('Public keys are not supported for EdDSA PKCS#1'));
  313. }