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