fix EC padding

This commit is contained in:
AJ ONeal 2018-12-10 23:23:17 -07:00
parent afdd93b267
commit bcc503596f

View File

@ -66,17 +66,17 @@ SSH._packKey = function (opts) {
els.push(Enc.binToHex('ssh-rsa'));
if (jwk.d) {
// unswap n and e for private key format
els.push(SSH._padRsa(Enc.base64ToHex(jwk.n)));
els.push(SSH._padRsa(Enc.base64ToHex(jwk.e)));
els.push(SSH._padRsa(Enc.base64ToHex(jwk.d)));
els.push(SSH._padRsa(Enc.base64ToHex(jwk.qi)));
els.push(SSH._padRsa(Enc.base64ToHex(jwk.p)));
els.push(SSH._padRsa(Enc.base64ToHex(jwk.q)));
els.push(SSH._padBigInt(Enc.base64ToHex(jwk.n)));
els.push(SSH._padBigInt(Enc.base64ToHex(jwk.e)));
els.push(SSH._padBigInt(Enc.base64ToHex(jwk.d)));
els.push(SSH._padBigInt(Enc.base64ToHex(jwk.qi)));
els.push(SSH._padBigInt(Enc.base64ToHex(jwk.p)));
els.push(SSH._padBigInt(Enc.base64ToHex(jwk.q)));
els.push(Enc.binToHex(opts.comment || ''));
} else {
// swap n and e for public key format
els.push(SSH._padRsa(Enc.base64ToHex(jwk.e)));
els.push(SSH._padRsa(Enc.base64ToHex(jwk.n)));
els.push(SSH._padBigInt(Enc.base64ToHex(jwk.e)));
els.push(SSH._padBigInt(Enc.base64ToHex(jwk.n)));
}
return els;
}
@ -94,11 +94,16 @@ SSH._packKey = function (opts) {
}
els.push('04'
+ SSH._padEc(Enc.base64ToHex(jwk.x), len)
+ SSH._padEc(Enc.base64ToHex(jwk.y), len)
+ SSH._padBytes(Enc.base64ToHex(jwk.x), len)
+ SSH._padBytes(Enc.base64ToHex(jwk.y), len)
);
if (jwk.d) {
els.push(SSH._padEc(Enc.base64ToHex(jwk.d), len));
// I was able to empirically confirm that the leading 00 is expected for
// ambiguous BigInt negatives (0x80 set), and that the length can dip down
// to 31 bytes when the leading byte is 0x00. I suspect that if I had tried
// 65k iterations that I'd have seen at least one 30 byte number
els.push(SSH._padBigInt(Enc.base64ToHex(jwk.d)));
//console.warn('els:', els[els.length - 1]);
els.push(Enc.binToHex(opts.comment || ''));
}
@ -119,18 +124,20 @@ SSH._numToUint32Hex = function (num) {
return hex;
};
SSH._padRsa = function (hex) {
SSH._padBigInt = function (hex) {
// BigInt is negative if the high order bit 0x80 is set,
// so ASN1, SSH, and many other formats pad with '0x00'
// to signifiy a positive number.
var i = parseInt(hex.slice(0, 2), 16);
//console.warn('l', hex.length/2, 'i', i);
if (0x80 & i) {
//console.warn('0x80 true');
return '00' + hex;
}
return hex;
};
SSH._padEc = function (hex, len) {
SSH._padBytes = function (hex, len) {
while (hex.length < len * 2) {
hex = '00' + hex;
}