1 // Copyright 2015 Joyent, Inc.
10 var assert = require('assert-plus');
11 var asn1 = require('asn1');
12 var algs = require('../algs');
13 var utils = require('../utils');
15 var Key = require('../key');
16 var PrivateKey = require('../private-key');
17 var pem = require('./pem');
19 var pkcs8 = require('./pkcs8');
20 var readECDSACurve = pkcs8.readECDSACurve;
22 function read(buf, options) {
23 return (pem.read(buf, options, 'pkcs1'));
26 function write(key, options) {
27 return (pem.write(key, options, 'pkcs1'));
30 /* Helper to read in a single mpint */
31 function readMPInt(der, nm) {
32 assert.strictEqual(der.peek(), asn1.Ber.Integer,
33 nm + ' is not an Integer');
34 return (utils.mpNormalize(der.readString(asn1.Ber.Integer, true)));
37 function readPkcs1(alg, type, der) {
40 if (type === 'public')
41 return (readPkcs1RSAPublic(der));
42 else if (type === 'private')
43 return (readPkcs1RSAPrivate(der));
44 throw (new Error('Unknown key type: ' + type));
46 if (type === 'public')
47 return (readPkcs1DSAPublic(der));
48 else if (type === 'private')
49 return (readPkcs1DSAPrivate(der));
50 throw (new Error('Unknown key type: ' + type));
53 if (type === 'private')
54 return (readPkcs1ECDSAPrivate(der));
55 else if (type === 'public')
56 return (readPkcs1ECDSAPublic(der));
57 throw (new Error('Unknown key type: ' + type));
59 throw (new Error('Unknown key algo: ' + alg));
63 function readPkcs1RSAPublic(der) {
64 // modulus and exponent
65 var n = readMPInt(der, 'modulus');
66 var e = readMPInt(der, 'exponent');
72 { name: 'e', data: e },
73 { name: 'n', data: n }
77 return (new Key(key));
80 function readPkcs1RSAPrivate(der) {
81 var version = readMPInt(der, 'version');
82 assert.strictEqual(version[0], 0);
84 // modulus then public exponent
85 var n = readMPInt(der, 'modulus');
86 var e = readMPInt(der, 'public exponent');
87 var d = readMPInt(der, 'private exponent');
88 var p = readMPInt(der, 'prime1');
89 var q = readMPInt(der, 'prime2');
90 var dmodp = readMPInt(der, 'exponent1');
91 var dmodq = readMPInt(der, 'exponent2');
92 var iqmp = readMPInt(der, 'iqmp');
98 { name: 'n', data: n },
99 { name: 'e', data: e },
100 { name: 'd', data: d },
101 { name: 'iqmp', data: iqmp },
102 { name: 'p', data: p },
103 { name: 'q', data: q },
104 { name: 'dmodp', data: dmodp },
105 { name: 'dmodq', data: dmodq }
109 return (new PrivateKey(key));
112 function readPkcs1DSAPrivate(der) {
113 var version = readMPInt(der, 'version');
114 assert.strictEqual(version.readUInt8(0), 0);
116 var p = readMPInt(der, 'p');
117 var q = readMPInt(der, 'q');
118 var g = readMPInt(der, 'g');
119 var y = readMPInt(der, 'y');
120 var x = readMPInt(der, 'x');
126 { name: 'p', data: p },
127 { name: 'q', data: q },
128 { name: 'g', data: g },
129 { name: 'y', data: y },
130 { name: 'x', data: x }
134 return (new PrivateKey(key));
137 function readPkcs1DSAPublic(der) {
138 var y = readMPInt(der, 'y');
139 var p = readMPInt(der, 'p');
140 var q = readMPInt(der, 'q');
141 var g = readMPInt(der, 'g');
146 { name: 'y', data: y },
147 { name: 'p', data: p },
148 { name: 'q', data: q },
149 { name: 'g', data: g }
153 return (new Key(key));
156 function readPkcs1ECDSAPublic(der) {
159 var oid = der.readOID();
160 assert.strictEqual(oid, '1.2.840.10045.2.1', 'must be ecPublicKey');
162 var curveOid = der.readOID();
165 var curves = Object.keys(algs.curves);
166 for (var j = 0; j < curves.length; ++j) {
168 var cd = algs.curves[c];
169 if (cd.pkcs8oid === curveOid) {
174 assert.string(curve, 'a known ECDSA named curve');
176 var Q = der.readString(asn1.Ber.BitString, true);
177 Q = utils.ecNormalize(Q);
182 { name: 'curve', data: new Buffer(curve) },
183 { name: 'Q', data: Q }
187 return (new Key(key));
190 function readPkcs1ECDSAPrivate(der) {
191 var version = readMPInt(der, 'version');
192 assert.strictEqual(version.readUInt8(0), 1);
195 var d = der.readString(asn1.Ber.OctetString, true);
197 der.readSequence(0xa0);
198 var curve = readECDSACurve(der);
199 assert.string(curve, 'a known elliptic curve');
201 der.readSequence(0xa1);
202 var Q = der.readString(asn1.Ber.BitString, true);
203 Q = utils.ecNormalize(Q);
208 { name: 'curve', data: new Buffer(curve) },
209 { name: 'Q', data: Q },
210 { name: 'd', data: d }
214 return (new PrivateKey(key));
217 function writePkcs1(der, key) {
222 if (PrivateKey.isPrivateKey(key))
223 writePkcs1RSAPrivate(der, key);
225 writePkcs1RSAPublic(der, key);
228 if (PrivateKey.isPrivateKey(key))
229 writePkcs1DSAPrivate(der, key);
231 writePkcs1DSAPublic(der, key);
234 if (PrivateKey.isPrivateKey(key))
235 writePkcs1ECDSAPrivate(der, key);
237 writePkcs1ECDSAPublic(der, key);
240 throw (new Error('Unknown key algo: ' + key.type));
246 function writePkcs1RSAPublic(der, key) {
247 der.writeBuffer(key.part.n.data, asn1.Ber.Integer);
248 der.writeBuffer(key.part.e.data, asn1.Ber.Integer);
251 function writePkcs1RSAPrivate(der, key) {
252 var ver = new Buffer(1);
254 der.writeBuffer(ver, asn1.Ber.Integer);
256 der.writeBuffer(key.part.n.data, asn1.Ber.Integer);
257 der.writeBuffer(key.part.e.data, asn1.Ber.Integer);
258 der.writeBuffer(key.part.d.data, asn1.Ber.Integer);
259 der.writeBuffer(key.part.p.data, asn1.Ber.Integer);
260 der.writeBuffer(key.part.q.data, asn1.Ber.Integer);
261 if (!key.part.dmodp || !key.part.dmodq)
262 utils.addRSAMissing(key);
263 der.writeBuffer(key.part.dmodp.data, asn1.Ber.Integer);
264 der.writeBuffer(key.part.dmodq.data, asn1.Ber.Integer);
265 der.writeBuffer(key.part.iqmp.data, asn1.Ber.Integer);
268 function writePkcs1DSAPrivate(der, key) {
269 var ver = new Buffer(1);
271 der.writeBuffer(ver, asn1.Ber.Integer);
273 der.writeBuffer(key.part.p.data, asn1.Ber.Integer);
274 der.writeBuffer(key.part.q.data, asn1.Ber.Integer);
275 der.writeBuffer(key.part.g.data, asn1.Ber.Integer);
276 der.writeBuffer(key.part.y.data, asn1.Ber.Integer);
277 der.writeBuffer(key.part.x.data, asn1.Ber.Integer);
280 function writePkcs1DSAPublic(der, key) {
281 der.writeBuffer(key.part.y.data, asn1.Ber.Integer);
282 der.writeBuffer(key.part.p.data, asn1.Ber.Integer);
283 der.writeBuffer(key.part.q.data, asn1.Ber.Integer);
284 der.writeBuffer(key.part.g.data, asn1.Ber.Integer);
287 function writePkcs1ECDSAPublic(der, key) {
290 der.writeOID('1.2.840.10045.2.1'); /* ecPublicKey */
291 var curve = key.part.curve.data.toString();
292 var curveOid = algs.curves[curve].pkcs8oid;
293 assert.string(curveOid, 'a known ECDSA named curve');
294 der.writeOID(curveOid);
298 var Q = utils.ecNormalize(key.part.Q.data, true);
299 der.writeBuffer(Q, asn1.Ber.BitString);
302 function writePkcs1ECDSAPrivate(der, key) {
303 var ver = new Buffer(1);
305 der.writeBuffer(ver, asn1.Ber.Integer);
307 der.writeBuffer(key.part.d.data, asn1.Ber.OctetString);
309 der.startSequence(0xa0);
310 var curve = key.part.curve.data.toString();
311 var curveOid = algs.curves[curve].pkcs8oid;
312 assert.string(curveOid, 'a known ECDSA named curve');
313 der.writeOID(curveOid);
316 der.startSequence(0xa1);
317 var Q = utils.ecNormalize(key.part.Q.data, true);
318 der.writeBuffer(Q, asn1.Ber.BitString);