hyperonecom / h1-cli

Command-line interface for HyperOne platform
MIT License
6 stars 4 forks source link

Drop node-rsa & node-forge #460

Open ad-m opened 4 years ago

ad-m commented 4 years ago

We use node-rsa in command vm passwordreset.

Public-API expect data:

NodeJS develop standard library for crypto in area of asymmetric cryptography. Upstream issue nodejs/node#30045 (see also nodejs/node#26854 ) exists to expose that information eg. as publicExponent.

ad-m commented 4 years ago

Until NodeJS expose exponent & modulus information drop node-forge is also tricky.

For Vault, we accept PEM certificates, but the public-API for a virtual machine verifies the key more accurately.

const KEY_TYPE = Buffer.from("000000077373682d727361", "hex");
const PUBLIC_EXPONENT = Buffer.from("0000000301000100000101", "hex");
const MAGIC_SSH_HEADER = Buffer.concat([
    KEY_TYPE, 
    PUBLIC_EXPONENT
]);
// Consists:
// * length of key type
// * key type as string
// * length of public exponent
// * public exponent as bytes
// * length of modulus
// See https://stackoverflow.com/a/12750816/4017156 for details 
const MAGIC_PEM_FOOTER = Buffer.from("0203010001", "hex");
// Consists:
// * length of public exponent
// * public exponent
// See https://crypto.stackexchange.com/questions/55887/why-do-rsa-public-keys-begin-with-3048024100 for details
const endsWith = (buf, searchvalue) => buf.slice(buf.length - searchvalue.length).compare(searchvalue) == 0;

const generateKeyPair = (comment) => {
    const publicExponent = 0x10001; // default public exponent in NodeJS
    return new Promise((resolve, reject) => crypto.generateKeyPair('rsa', {
        modulusLength: 4096,
        publicExponent,
        publicKeyEncoding: {
            type: 'spki',
            format: 'pem'
        },
        privateKeyEncoding: {
            type: 'pkcs8',
            format: 'pem'
        }
    }, (err, pub, privateKey) => {
        if (err) return reject(err);
        const body = Buffer.from(
            pub.split("\n").filter(x => !x.includes('-----')).join(''),
            'base64'
        );
        if (!endsWith(body, MAGIC_PEM_FOOTER)) {
            return reject(new Error('Unable to convert PEM to SSH key. Verify key size.'));
        }
        const modulus = body.slice(32, body.length - MAGIC_PEM_FOOTER.length)
        const publicKey = [
            'ssh-rsa',
            Buffer.concat([
                MAGIC_SSH_HEADER,
                modulus,
            ]).toString('base64'),
            comment
        ].join(' ');
        return resolve({ publicKey, privateKey })
    }));
};
fredericosilva commented 4 years ago

Check ssh2 utils, they might have solved it somehow.

On Tue, Oct 29, 2019, 00:04 Adam Dobrawy notifications@github.com wrote:

Until NodeJS expose exponent & modulus information drop node-forge is also tricky.

For Vault, we accept PEM certificates, but the public-API for a virtual machine verifies the key more accurately.

const KEY_TYPE = Buffer.from("000000077373682d727361", "hex");const PUBLIC_EXPONENT = Buffer.from("0000000301000100000101", "hex");const MAGIC_SSH_HEADER = Buffer.concat([ KEY_TYPE, PUBLIC_EXPONENT ]);// Consists:// length of key type// key type as string// length of public exponent// public exponent as bytes// length of modulus// See https://stackoverflow.com/a/12750816/4017156 for details const MAGIC_PEM_FOOTER = Buffer.from("0203010001", "hex");// Consists:// length of public exponent// * public exponent// See https://crypto.stackexchange.com/questions/55887/why-do-rsa-public-keys-begin-with-3048024100 for detailsconst endsWith = (buf, searchvalue) => buf.slice(buf.length - searchvalue.length).compare(searchvalue) == 0; const generateKeyPair = (comment) => { const publicExponent = 0x10001; // default public exponent in NodeJS return new Promise((resolve, reject) => crypto.generateKeyPair('rsa', { modulusLength: 4096, publicExponent, publicKeyEncoding: { type: 'spki', format: 'pem' }, privateKeyEncoding: { type: 'pkcs8', format: 'pem' } }, (err, pub, privateKey) => { if (err) return reject(err); const body = Buffer.from( pub.split("\n").filter(x => !x.includes('-----')).join(''), 'base64' ); if (!endsWith(body, MAGIC_PEM_FOOTER)) { return reject(new Error('Unable to convert PEM to SSH key. Verify key size.')); } const modulus = body.slice(32, body.length - MAGIC_PEM_FOOTER.length) const publicKey = [ 'ssh-rsa', Buffer.concat([ MAGIC_SSH_HEADER, modulus, ]).toString('base64'), comment ].join(' '); return resolve({ publicKey, privateKey }) })); };

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/hyperonecom/h1-cli/issues/460?email_source=notifications&email_token=AAHCO4I7OX4NQFPMYEQP4J3QQ5VZPA5CNFSM4JF27MIKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOECOVYYI#issuecomment-547183713, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAHCO4ILJFUBUFFO6QEPL6TQQ5VZPANCNFSM4JF27MIA .