1 line
26 KiB
JSON
1 line
26 KiB
JSON
{"ast":null,"code":"// Copyright 2018 Joyent, Inc.\nmodule.exports = {\n read: read,\n write: write\n};\n\nvar assert = require('assert-plus');\n\nvar asn1 = require('asn1');\n\nvar crypto = require('crypto');\n\nvar Buffer = require('safer-buffer').Buffer;\n\nvar algs = require('../algs');\n\nvar utils = require('../utils');\n\nvar Key = require('../key');\n\nvar PrivateKey = require('../private-key');\n\nvar pkcs1 = require('./pkcs1');\n\nvar pkcs8 = require('./pkcs8');\n\nvar sshpriv = require('./ssh-private');\n\nvar rfc4253 = require('./rfc4253');\n\nvar errors = require('../errors');\n\nvar OID_PBES2 = '1.2.840.113549.1.5.13';\nvar OID_PBKDF2 = '1.2.840.113549.1.5.12';\nvar OID_TO_CIPHER = {\n '1.2.840.113549.3.7': '3des-cbc',\n '2.16.840.1.101.3.4.1.2': 'aes128-cbc',\n '2.16.840.1.101.3.4.1.42': 'aes256-cbc'\n};\nvar CIPHER_TO_OID = {};\nObject.keys(OID_TO_CIPHER).forEach(function (k) {\n CIPHER_TO_OID[OID_TO_CIPHER[k]] = k;\n});\nvar OID_TO_HASH = {\n '1.2.840.113549.2.7': 'sha1',\n '1.2.840.113549.2.9': 'sha256',\n '1.2.840.113549.2.11': 'sha512'\n};\nvar HASH_TO_OID = {};\nObject.keys(OID_TO_HASH).forEach(function (k) {\n HASH_TO_OID[OID_TO_HASH[k]] = k;\n});\n/*\n * For reading we support both PKCS#1 and PKCS#8. If we find a private key,\n * we just take the public component of it and use that.\n */\n\nfunction read(buf, options, forceType) {\n var input = buf;\n\n if (typeof buf !== 'string') {\n assert.buffer(buf, 'buf');\n buf = buf.toString('ascii');\n }\n\n var lines = buf.trim().split(/[\\r\\n]+/g);\n var m;\n var si = -1;\n\n while (!m && si < lines.length) {\n m = lines[++si].match(\n /*JSSTYLED*/\n /[-]+[ ]*BEGIN ([A-Z0-9][A-Za-z0-9]+ )?(PUBLIC|PRIVATE) KEY[ ]*[-]+/);\n }\n\n assert.ok(m, 'invalid PEM header');\n var m2;\n var ei = lines.length;\n\n while (!m2 && ei > 0) {\n m2 = lines[--ei].match(\n /*JSSTYLED*/\n /[-]+[ ]*END ([A-Z0-9][A-Za-z0-9]+ )?(PUBLIC|PRIVATE) KEY[ ]*[-]+/);\n }\n\n assert.ok(m2, 'invalid PEM footer');\n /* Begin and end banners must match key type */\n\n assert.equal(m[2], m2[2]);\n var type = m[2].toLowerCase();\n var alg;\n\n if (m[1]) {\n /* They also must match algorithms, if given */\n assert.equal(m[1], m2[1], 'PEM header and footer mismatch');\n alg = m[1].trim();\n }\n\n lines = lines.slice(si, ei + 1);\n var headers = {};\n\n while (true) {\n lines = lines.slice(1);\n m = lines[0].match(\n /*JSSTYLED*/\n /^([A-Za-z0-9-]+): (.+)$/);\n if (!m) break;\n headers[m[1].toLowerCase()] = m[2];\n }\n /* Chop off the first and last lines */\n\n\n lines = lines.slice(0, -1).join('');\n buf = Buffer.from(lines, 'base64');\n var cipher, key, iv;\n\n if (headers['proc-type']) {\n var parts = headers['proc-type'].split(',');\n\n if (parts[0] === '4' && parts[1] === 'ENCRYPTED') {\n if (typeof options.passphrase === 'string') {\n options.passphrase = Buffer.from(options.passphrase, 'utf-8');\n }\n\n if (!Buffer.isBuffer(options.passphrase)) {\n throw new errors.KeyEncryptedError(options.filename, 'PEM');\n } else {\n parts = headers['dek-info'].split(',');\n assert.ok(parts.length === 2);\n cipher = parts[0].toLowerCase();\n iv = Buffer.from(parts[1], 'hex');\n key = utils.opensslKeyDeriv(cipher, iv, options.passphrase, 1).key;\n }\n }\n }\n\n if (alg && alg.toLowerCase() === 'encrypted') {\n var eder = new asn1.BerReader(buf);\n var pbesEnd;\n eder.readSequence();\n eder.readSequence();\n pbesEnd = eder.offset + eder.length;\n var method = eder.readOID();\n\n if (method !== OID_PBES2) {\n throw new Error('Unsupported PEM/PKCS8 encryption ' + 'scheme: ' + method);\n }\n\n eder.readSequence();\n /* PBES2-params */\n\n eder.readSequence();\n /* keyDerivationFunc */\n\n var kdfEnd = eder.offset + eder.length;\n var kdfOid = eder.readOID();\n if (kdfOid !== OID_PBKDF2) throw new Error('Unsupported PBES2 KDF: ' + kdfOid);\n eder.readSequence();\n var salt = eder.readString(asn1.Ber.OctetString, true);\n var iterations = eder.readInt();\n var hashAlg = 'sha1';\n\n if (eder.offset < kdfEnd) {\n eder.readSequence();\n var hashAlgOid = eder.readOID();\n hashAlg = OID_TO_HASH[hashAlgOid];\n\n if (hashAlg === undefined) {\n throw new Error('Unsupported PBKDF2 hash: ' + hashAlgOid);\n }\n }\n\n eder._offset = kdfEnd;\n eder.readSequence();\n /* encryptionScheme */\n\n var cipherOid = eder.readOID();\n cipher = OID_TO_CIPHER[cipherOid];\n\n if (cipher === undefined) {\n throw new Error('Unsupported PBES2 cipher: ' + cipherOid);\n }\n\n iv = eder.readString(asn1.Ber.OctetString, true);\n eder._offset = pbesEnd;\n buf = eder.readString(asn1.Ber.OctetString, true);\n\n if (typeof options.passphrase === 'string') {\n options.passphrase = Buffer.from(options.passphrase, 'utf-8');\n }\n\n if (!Buffer.isBuffer(options.passphrase)) {\n throw new errors.KeyEncryptedError(options.filename, 'PEM');\n }\n\n var cinfo = utils.opensshCipherInfo(cipher);\n cipher = cinfo.opensslName;\n key = utils.pbkdf2(hashAlg, salt, iterations, cinfo.keySize, options.passphrase);\n alg = undefined;\n }\n\n if (cipher && key && iv) {\n var cipherStream = crypto.createDecipheriv(cipher, key, iv);\n var chunk,\n chunks = [];\n cipherStream.once('error', function (e) {\n if (e.toString().indexOf('bad decrypt') !== -1) {\n throw new Error('Incorrect passphrase ' + 'supplied, could not decrypt key');\n }\n\n throw e;\n });\n cipherStream.write(buf);\n cipherStream.end();\n\n while ((chunk = cipherStream.read()) !== null) chunks.push(chunk);\n\n buf = Buffer.concat(chunks);\n }\n /* The new OpenSSH internal format abuses PEM headers */\n\n\n if (alg && alg.toLowerCase() === 'openssh') return sshpriv.readSSHPrivate(type, buf, options);\n if (alg && alg.toLowerCase() === 'ssh2') return rfc4253.readType(type, buf, options);\n var der = new asn1.BerReader(buf);\n der.originalInput = input;\n /*\n * All of the PEM file types start with a sequence tag, so chop it\n * off here\n */\n\n der.readSequence();\n /* PKCS#1 type keys name an algorithm in the banner explicitly */\n\n if (alg) {\n if (forceType) assert.strictEqual(forceType, 'pkcs1');\n return pkcs1.readPkcs1(alg, type, der);\n } else {\n if (forceType) assert.strictEqual(forceType, 'pkcs8');\n return pkcs8.readPkcs8(alg, type, der);\n }\n}\n\nfunction write(key, options, type) {\n assert.object(key);\n var alg = {\n 'ecdsa': 'EC',\n 'rsa': 'RSA',\n 'dsa': 'DSA',\n 'ed25519': 'EdDSA'\n }[key.type];\n var header;\n var der = new asn1.BerWriter();\n\n if (PrivateKey.isPrivateKey(key)) {\n if (type && type === 'pkcs8') {\n header = 'PRIVATE KEY';\n pkcs8.writePkcs8(der, key);\n } else {\n if (type) assert.strictEqual(type, 'pkcs1');\n header = alg + ' PRIVATE KEY';\n pkcs1.writePkcs1(der, key);\n }\n } else if (Key.isKey(key)) {\n if (type && type === 'pkcs1') {\n header = alg + ' PUBLIC KEY';\n pkcs1.writePkcs1(der, key);\n } else {\n if (type) assert.strictEqual(type, 'pkcs8');\n header = 'PUBLIC KEY';\n pkcs8.writePkcs8(der, key);\n }\n } else {\n throw new Error('key is not a Key or PrivateKey');\n }\n\n var tmp = der.buffer.toString('base64');\n var len = tmp.length + tmp.length / 64 + 18 + 16 + header.length * 2 + 10;\n var buf = Buffer.alloc(len);\n var o = 0;\n o += buf.write('-----BEGIN ' + header + '-----\\n', o);\n\n for (var i = 0; i < tmp.length;) {\n var limit = i + 64;\n if (limit > tmp.length) limit = tmp.length;\n o += buf.write(tmp.slice(i, limit), o);\n buf[o++] = 10;\n i = limit;\n }\n\n o += buf.write('-----END ' + header + '-----\\n', o);\n return buf.slice(0, o);\n}","map":{"version":3,"sources":["/Users/tylerkoenig/Code/personal/react-scss2/node_modules/sshpk/lib/formats/pem.js"],"names":["module","exports","read","write","assert","require","asn1","crypto","Buffer","algs","utils","Key","PrivateKey","pkcs1","pkcs8","sshpriv","rfc4253","errors","OID_PBES2","OID_PBKDF2","OID_TO_CIPHER","CIPHER_TO_OID","Object","keys","forEach","k","OID_TO_HASH","HASH_TO_OID","buf","options","forceType","input","buffer","toString","lines","trim","split","m","si","length","match","ok","m2","ei","equal","type","toLowerCase","alg","slice","headers","join","from","cipher","key","iv","parts","passphrase","isBuffer","KeyEncryptedError","filename","opensslKeyDeriv","eder","BerReader","pbesEnd","readSequence","offset","method","readOID","Error","kdfEnd","kdfOid","salt","readString","Ber","OctetString","iterations","readInt","hashAlg","hashAlgOid","undefined","_offset","cipherOid","cinfo","opensshCipherInfo","opensslName","pbkdf2","keySize","cipherStream","createDecipheriv","chunk","chunks","once","e","indexOf","end","push","concat","readSSHPrivate","readType","der","originalInput","strictEqual","readPkcs1","readPkcs8","object","header","BerWriter","isPrivateKey","writePkcs8","writePkcs1","isKey","tmp","len","alloc","o","i","limit"],"mappings":"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","sourcesContent":["// Copyright 2018 Joyent, Inc.\n\nmodule.exports = {\n\tread: read,\n\twrite: write\n};\n\nvar assert = require('assert-plus');\nvar asn1 = require('asn1');\nvar crypto = require('crypto');\nvar Buffer = require('safer-buffer').Buffer;\nvar algs = require('../algs');\nvar utils = require('../utils');\nvar Key = require('../key');\nvar PrivateKey = require('../private-key');\n\nvar pkcs1 = require('./pkcs1');\nvar pkcs8 = require('./pkcs8');\nvar sshpriv = require('./ssh-private');\nvar rfc4253 = require('./rfc4253');\n\nvar errors = require('../errors');\n\nvar OID_PBES2 = '1.2.840.113549.1.5.13';\nvar OID_PBKDF2 = '1.2.840.113549.1.5.12';\n\nvar OID_TO_CIPHER = {\n\t'1.2.840.113549.3.7': '3des-cbc',\n\t'2.16.840.1.101.3.4.1.2': 'aes128-cbc',\n\t'2.16.840.1.101.3.4.1.42': 'aes256-cbc'\n};\nvar CIPHER_TO_OID = {};\nObject.keys(OID_TO_CIPHER).forEach(function (k) {\n\tCIPHER_TO_OID[OID_TO_CIPHER[k]] = k;\n});\n\nvar OID_TO_HASH = {\n\t'1.2.840.113549.2.7': 'sha1',\n\t'1.2.840.113549.2.9': 'sha256',\n\t'1.2.840.113549.2.11': 'sha512'\n};\nvar HASH_TO_OID = {};\nObject.keys(OID_TO_HASH).forEach(function (k) {\n\tHASH_TO_OID[OID_TO_HASH[k]] = k;\n});\n\n/*\n * For reading we support both PKCS#1 and PKCS#8. If we find a private key,\n * we just take the public component of it and use that.\n */\nfunction read(buf, options, forceType) {\n\tvar input = buf;\n\tif (typeof (buf) !== 'string') {\n\t\tassert.buffer(buf, 'buf');\n\t\tbuf = buf.toString('ascii');\n\t}\n\n\tvar lines = buf.trim().split(/[\\r\\n]+/g);\n\n\tvar m;\n\tvar si = -1;\n\twhile (!m && si < lines.length) {\n\t\tm = lines[++si].match(/*JSSTYLED*/\n\t\t /[-]+[ ]*BEGIN ([A-Z0-9][A-Za-z0-9]+ )?(PUBLIC|PRIVATE) KEY[ ]*[-]+/);\n\t}\n\tassert.ok(m, 'invalid PEM header');\n\n\tvar m2;\n\tvar ei = lines.length;\n\twhile (!m2 && ei > 0) {\n\t\tm2 = lines[--ei].match(/*JSSTYLED*/\n\t\t /[-]+[ ]*END ([A-Z0-9][A-Za-z0-9]+ )?(PUBLIC|PRIVATE) KEY[ ]*[-]+/);\n\t}\n\tassert.ok(m2, 'invalid PEM footer');\n\n\t/* Begin and end banners must match key type */\n\tassert.equal(m[2], m2[2]);\n\tvar type = m[2].toLowerCase();\n\n\tvar alg;\n\tif (m[1]) {\n\t\t/* They also must match algorithms, if given */\n\t\tassert.equal(m[1], m2[1], 'PEM header and footer mismatch');\n\t\talg = m[1].trim();\n\t}\n\n\tlines = lines.slice(si, ei + 1);\n\n\tvar headers = {};\n\twhile (true) {\n\t\tlines = lines.slice(1);\n\t\tm = lines[0].match(/*JSSTYLED*/\n\t\t /^([A-Za-z0-9-]+): (.+)$/);\n\t\tif (!m)\n\t\t\tbreak;\n\t\theaders[m[1].toLowerCase()] = m[2];\n\t}\n\n\t/* Chop off the first and last lines */\n\tlines = lines.slice(0, -1).join('');\n\tbuf = Buffer.from(lines, 'base64');\n\n\tvar cipher, key, iv;\n\tif (headers['proc-type']) {\n\t\tvar parts = headers['proc-type'].split(',');\n\t\tif (parts[0] === '4' && parts[1] === 'ENCRYPTED') {\n\t\t\tif (typeof (options.passphrase) === 'string') {\n\t\t\t\toptions.passphrase = Buffer.from(\n\t\t\t\t options.passphrase, 'utf-8');\n\t\t\t}\n\t\t\tif (!Buffer.isBuffer(options.passphrase)) {\n\t\t\t\tthrow (new errors.KeyEncryptedError(\n\t\t\t\t options.filename, 'PEM'));\n\t\t\t} else {\n\t\t\t\tparts = headers['dek-info'].split(',');\n\t\t\t\tassert.ok(parts.length === 2);\n\t\t\t\tcipher = parts[0].toLowerCase();\n\t\t\t\tiv = Buffer.from(parts[1], 'hex');\n\t\t\t\tkey = utils.opensslKeyDeriv(cipher, iv,\n\t\t\t\t options.passphrase, 1).key;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (alg && alg.toLowerCase() === 'encrypted') {\n\t\tvar eder = new asn1.BerReader(buf);\n\t\tvar pbesEnd;\n\t\teder.readSequence();\n\n\t\teder.readSequence();\n\t\tpbesEnd = eder.offset + eder.length;\n\n\t\tvar method = eder.readOID();\n\t\tif (method !== OID_PBES2) {\n\t\t\tthrow (new Error('Unsupported PEM/PKCS8 encryption ' +\n\t\t\t 'scheme: ' + method));\n\t\t}\n\n\t\teder.readSequence();\t/* PBES2-params */\n\n\t\teder.readSequence();\t/* keyDerivationFunc */\n\t\tvar kdfEnd = eder.offset + eder.length;\n\t\tvar kdfOid = eder.readOID();\n\t\tif (kdfOid !== OID_PBKDF2)\n\t\t\tthrow (new Error('Unsupported PBES2 KDF: ' + kdfOid));\n\t\teder.readSequence();\n\t\tvar salt = eder.readString(asn1.Ber.OctetString, true);\n\t\tvar iterations = eder.readInt();\n\t\tvar hashAlg = 'sha1';\n\t\tif (eder.offset < kdfEnd) {\n\t\t\teder.readSequence();\n\t\t\tvar hashAlgOid = eder.readOID();\n\t\t\thashAlg = OID_TO_HASH[hashAlgOid];\n\t\t\tif (hashAlg === undefined) {\n\t\t\t\tthrow (new Error('Unsupported PBKDF2 hash: ' +\n\t\t\t\t hashAlgOid));\n\t\t\t}\n\t\t}\n\t\teder._offset = kdfEnd;\n\n\t\teder.readSequence();\t/* encryptionScheme */\n\t\tvar cipherOid = eder.readOID();\n\t\tcipher = OID_TO_CIPHER[cipherOid];\n\t\tif (cipher === undefined) {\n\t\t\tthrow (new Error('Unsupported PBES2 cipher: ' +\n\t\t\t cipherOid));\n\t\t}\n\t\tiv = eder.readString(asn1.Ber.OctetString, true);\n\n\t\teder._offset = pbesEnd;\n\t\tbuf = eder.readString(asn1.Ber.OctetString, true);\n\n\t\tif (typeof (options.passphrase) === 'string') {\n\t\t\toptions.passphrase = Buffer.from(\n\t\t\t options.passphrase, 'utf-8');\n\t\t}\n\t\tif (!Buffer.isBuffer(options.passphrase)) {\n\t\t\tthrow (new errors.KeyEncryptedError(\n\t\t\t options.filename, 'PEM'));\n\t\t}\n\n\t\tvar cinfo = utils.opensshCipherInfo(cipher);\n\n\t\tcipher = cinfo.opensslName;\n\t\tkey = utils.pbkdf2(hashAlg, salt, iterations, cinfo.keySize,\n\t\t options.passphrase);\n\t\talg = undefined;\n\t}\n\n\tif (cipher && key && iv) {\n\t\tvar cipherStream = crypto.createDecipheriv(cipher, key, iv);\n\t\tvar chunk, chunks = [];\n\t\tcipherStream.once('error', function (e) {\n\t\t\tif (e.toString().indexOf('bad decrypt') !== -1) {\n\t\t\t\tthrow (new Error('Incorrect passphrase ' +\n\t\t\t\t 'supplied, could not decrypt key'));\n\t\t\t}\n\t\t\tthrow (e);\n\t\t});\n\t\tcipherStream.write(buf);\n\t\tcipherStream.end();\n\t\twhile ((chunk = cipherStream.read()) !== null)\n\t\t\tchunks.push(chunk);\n\t\tbuf = Buffer.concat(chunks);\n\t}\n\n\t/* The new OpenSSH internal format abuses PEM headers */\n\tif (alg && alg.toLowerCase() === 'openssh')\n\t\treturn (sshpriv.readSSHPrivate(type, buf, options));\n\tif (alg && alg.toLowerCase() === 'ssh2')\n\t\treturn (rfc4253.readType(type, buf, options));\n\n\tvar der = new asn1.BerReader(buf);\n\tder.originalInput = input;\n\n\t/*\n\t * All of the PEM file types start with a sequence tag, so chop it\n\t * off here\n\t */\n\tder.readSequence();\n\n\t/* PKCS#1 type keys name an algorithm in the banner explicitly */\n\tif (alg) {\n\t\tif (forceType)\n\t\t\tassert.strictEqual(forceType, 'pkcs1');\n\t\treturn (pkcs1.readPkcs1(alg, type, der));\n\t} else {\n\t\tif (forceType)\n\t\t\tassert.strictEqual(forceType, 'pkcs8');\n\t\treturn (pkcs8.readPkcs8(alg, type, der));\n\t}\n}\n\nfunction write(key, options, type) {\n\tassert.object(key);\n\n\tvar alg = {\n\t 'ecdsa': 'EC',\n\t 'rsa': 'RSA',\n\t 'dsa': 'DSA',\n\t 'ed25519': 'EdDSA'\n\t}[key.type];\n\tvar header;\n\n\tvar der = new asn1.BerWriter();\n\n\tif (PrivateKey.isPrivateKey(key)) {\n\t\tif (type && type === 'pkcs8') {\n\t\t\theader = 'PRIVATE KEY';\n\t\t\tpkcs8.writePkcs8(der, key);\n\t\t} else {\n\t\t\tif (type)\n\t\t\t\tassert.strictEqual(type, 'pkcs1');\n\t\t\theader = alg + ' PRIVATE KEY';\n\t\t\tpkcs1.writePkcs1(der, key);\n\t\t}\n\n\t} else if (Key.isKey(key)) {\n\t\tif (type && type === 'pkcs1') {\n\t\t\theader = alg + ' PUBLIC KEY';\n\t\t\tpkcs1.writePkcs1(der, key);\n\t\t} else {\n\t\t\tif (type)\n\t\t\t\tassert.strictEqual(type, 'pkcs8');\n\t\t\theader = 'PUBLIC KEY';\n\t\t\tpkcs8.writePkcs8(der, key);\n\t\t}\n\n\t} else {\n\t\tthrow (new Error('key is not a Key or PrivateKey'));\n\t}\n\n\tvar tmp = der.buffer.toString('base64');\n\tvar len = tmp.length + (tmp.length / 64) +\n\t 18 + 16 + header.length*2 + 10;\n\tvar buf = Buffer.alloc(len);\n\tvar o = 0;\n\to += buf.write('-----BEGIN ' + header + '-----\\n', o);\n\tfor (var i = 0; i < tmp.length; ) {\n\t\tvar limit = i + 64;\n\t\tif (limit > tmp.length)\n\t\t\tlimit = tmp.length;\n\t\to += buf.write(tmp.slice(i, limit), o);\n\t\tbuf[o++] = 10;\n\t\ti = limit;\n\t}\n\to += buf.write('-----END ' + header + '-----\\n', o);\n\n\treturn (buf.slice(0, o));\n}\n"]},"metadata":{},"sourceType":"script"} |