pkcs1.js 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  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. default:
  51. throw (new Error('Unknown key algo: ' + alg));
  52. }
  53. }
  54. function readPkcs1RSAPublic(der) {
  55. // modulus and exponent
  56. var n = readMPInt(der, 'modulus');
  57. var e = readMPInt(der, 'exponent');
  58. // now, make the key
  59. var key = {
  60. type: 'rsa',
  61. parts: [
  62. { name: 'e', data: e },
  63. { name: 'n', data: n }
  64. ]
  65. };
  66. return (new Key(key));
  67. }
  68. function readPkcs1RSAPrivate(der) {
  69. var version = readMPInt(der, 'version');
  70. assert.strictEqual(version[0], 0);
  71. // modulus then public exponent
  72. var n = readMPInt(der, 'modulus');
  73. var e = readMPInt(der, 'public exponent');
  74. var d = readMPInt(der, 'private exponent');
  75. var p = readMPInt(der, 'prime1');
  76. var q = readMPInt(der, 'prime2');
  77. var dmodp = readMPInt(der, 'exponent1');
  78. var dmodq = readMPInt(der, 'exponent2');
  79. var iqmp = readMPInt(der, 'iqmp');
  80. // now, make the key
  81. var key = {
  82. type: 'rsa',
  83. parts: [
  84. { name: 'n', data: n },
  85. { name: 'e', data: e },
  86. { name: 'd', data: d },
  87. { name: 'iqmp', data: iqmp },
  88. { name: 'p', data: p },
  89. { name: 'q', data: q },
  90. { name: 'dmodp', data: dmodp },
  91. { name: 'dmodq', data: dmodq }
  92. ]
  93. };
  94. return (new PrivateKey(key));
  95. }
  96. function readPkcs1DSAPrivate(der) {
  97. var version = readMPInt(der, 'version');
  98. assert.strictEqual(version.readUInt8(0), 0);
  99. var p = readMPInt(der, 'p');
  100. var q = readMPInt(der, 'q');
  101. var g = readMPInt(der, 'g');
  102. var y = readMPInt(der, 'y');
  103. var x = readMPInt(der, 'x');
  104. // now, make the key
  105. var key = {
  106. type: 'dsa',
  107. parts: [
  108. { name: 'p', data: p },
  109. { name: 'q', data: q },
  110. { name: 'g', data: g },
  111. { name: 'y', data: y },
  112. { name: 'x', data: x }
  113. ]
  114. };
  115. return (new PrivateKey(key));
  116. }
  117. function readPkcs1DSAPublic(der) {
  118. var y = readMPInt(der, 'y');
  119. var p = readMPInt(der, 'p');
  120. var q = readMPInt(der, 'q');
  121. var g = readMPInt(der, 'g');
  122. var key = {
  123. type: 'dsa',
  124. parts: [
  125. { name: 'y', data: y },
  126. { name: 'p', data: p },
  127. { name: 'q', data: q },
  128. { name: 'g', data: g }
  129. ]
  130. };
  131. return (new Key(key));
  132. }
  133. function readPkcs1ECDSAPublic(der) {
  134. der.readSequence();
  135. var oid = der.readOID();
  136. assert.strictEqual(oid, '1.2.840.10045.2.1', 'must be ecPublicKey');
  137. var curveOid = der.readOID();
  138. var curve;
  139. var curves = Object.keys(algs.curves);
  140. for (var j = 0; j < curves.length; ++j) {
  141. var c = curves[j];
  142. var cd = algs.curves[c];
  143. if (cd.pkcs8oid === curveOid) {
  144. curve = c;
  145. break;
  146. }
  147. }
  148. assert.string(curve, 'a known ECDSA named curve');
  149. var Q = der.readString(asn1.Ber.BitString, true);
  150. Q = utils.ecNormalize(Q);
  151. var key = {
  152. type: 'ecdsa',
  153. parts: [
  154. { name: 'curve', data: new Buffer(curve) },
  155. { name: 'Q', data: Q }
  156. ]
  157. };
  158. return (new Key(key));
  159. }
  160. function readPkcs1ECDSAPrivate(der) {
  161. var version = readMPInt(der, 'version');
  162. assert.strictEqual(version.readUInt8(0), 1);
  163. // private key
  164. var d = der.readString(asn1.Ber.OctetString, true);
  165. der.readSequence(0xa0);
  166. var curve = readECDSACurve(der);
  167. assert.string(curve, 'a known elliptic curve');
  168. der.readSequence(0xa1);
  169. var Q = der.readString(asn1.Ber.BitString, true);
  170. Q = utils.ecNormalize(Q);
  171. var key = {
  172. type: 'ecdsa',
  173. parts: [
  174. { name: 'curve', data: new Buffer(curve) },
  175. { name: 'Q', data: Q },
  176. { name: 'd', data: d }
  177. ]
  178. };
  179. return (new PrivateKey(key));
  180. }
  181. function writePkcs1(der, key) {
  182. der.startSequence();
  183. switch (key.type) {
  184. case 'rsa':
  185. if (PrivateKey.isPrivateKey(key))
  186. writePkcs1RSAPrivate(der, key);
  187. else
  188. writePkcs1RSAPublic(der, key);
  189. break;
  190. case 'dsa':
  191. if (PrivateKey.isPrivateKey(key))
  192. writePkcs1DSAPrivate(der, key);
  193. else
  194. writePkcs1DSAPublic(der, key);
  195. break;
  196. case 'ecdsa':
  197. if (PrivateKey.isPrivateKey(key))
  198. writePkcs1ECDSAPrivate(der, key);
  199. else
  200. writePkcs1ECDSAPublic(der, key);
  201. break;
  202. default:
  203. throw (new Error('Unknown key algo: ' + key.type));
  204. }
  205. der.endSequence();
  206. }
  207. function writePkcs1RSAPublic(der, key) {
  208. der.writeBuffer(key.part.n.data, asn1.Ber.Integer);
  209. der.writeBuffer(key.part.e.data, asn1.Ber.Integer);
  210. }
  211. function writePkcs1RSAPrivate(der, key) {
  212. var ver = new Buffer(1);
  213. ver[0] = 0;
  214. der.writeBuffer(ver, asn1.Ber.Integer);
  215. der.writeBuffer(key.part.n.data, asn1.Ber.Integer);
  216. der.writeBuffer(key.part.e.data, asn1.Ber.Integer);
  217. der.writeBuffer(key.part.d.data, asn1.Ber.Integer);
  218. der.writeBuffer(key.part.p.data, asn1.Ber.Integer);
  219. der.writeBuffer(key.part.q.data, asn1.Ber.Integer);
  220. if (!key.part.dmodp || !key.part.dmodq)
  221. utils.addRSAMissing(key);
  222. der.writeBuffer(key.part.dmodp.data, asn1.Ber.Integer);
  223. der.writeBuffer(key.part.dmodq.data, asn1.Ber.Integer);
  224. der.writeBuffer(key.part.iqmp.data, asn1.Ber.Integer);
  225. }
  226. function writePkcs1DSAPrivate(der, key) {
  227. var ver = new Buffer(1);
  228. ver[0] = 0;
  229. der.writeBuffer(ver, asn1.Ber.Integer);
  230. der.writeBuffer(key.part.p.data, asn1.Ber.Integer);
  231. der.writeBuffer(key.part.q.data, asn1.Ber.Integer);
  232. der.writeBuffer(key.part.g.data, asn1.Ber.Integer);
  233. der.writeBuffer(key.part.y.data, asn1.Ber.Integer);
  234. der.writeBuffer(key.part.x.data, asn1.Ber.Integer);
  235. }
  236. function writePkcs1DSAPublic(der, key) {
  237. der.writeBuffer(key.part.y.data, asn1.Ber.Integer);
  238. der.writeBuffer(key.part.p.data, asn1.Ber.Integer);
  239. der.writeBuffer(key.part.q.data, asn1.Ber.Integer);
  240. der.writeBuffer(key.part.g.data, asn1.Ber.Integer);
  241. }
  242. function writePkcs1ECDSAPublic(der, key) {
  243. der.startSequence();
  244. der.writeOID('1.2.840.10045.2.1'); /* ecPublicKey */
  245. var curve = key.part.curve.data.toString();
  246. var curveOid = algs.curves[curve].pkcs8oid;
  247. assert.string(curveOid, 'a known ECDSA named curve');
  248. der.writeOID(curveOid);
  249. der.endSequence();
  250. var Q = utils.ecNormalize(key.part.Q.data, true);
  251. der.writeBuffer(Q, asn1.Ber.BitString);
  252. }
  253. function writePkcs1ECDSAPrivate(der, key) {
  254. var ver = new Buffer(1);
  255. ver[0] = 1;
  256. der.writeBuffer(ver, asn1.Ber.Integer);
  257. der.writeBuffer(key.part.d.data, asn1.Ber.OctetString);
  258. der.startSequence(0xa0);
  259. var curve = key.part.curve.data.toString();
  260. var curveOid = algs.curves[curve].pkcs8oid;
  261. assert.string(curveOid, 'a known ECDSA named curve');
  262. der.writeOID(curveOid);
  263. der.endSequence();
  264. der.startSequence(0xa1);
  265. var Q = utils.ecNormalize(key.part.Q.data, true);
  266. der.writeBuffer(Q, asn1.Ber.BitString);
  267. der.endSequence();
  268. }