fix EC padding
This commit is contained in:
parent
afdd93b267
commit
bcc503596f
@ -66,17 +66,17 @@ SSH._packKey = function (opts) {
|
|||||||
els.push(Enc.binToHex('ssh-rsa'));
|
els.push(Enc.binToHex('ssh-rsa'));
|
||||||
if (jwk.d) {
|
if (jwk.d) {
|
||||||
// unswap n and e for private key format
|
// unswap n and e for private key format
|
||||||
els.push(SSH._padRsa(Enc.base64ToHex(jwk.n)));
|
els.push(SSH._padBigInt(Enc.base64ToHex(jwk.n)));
|
||||||
els.push(SSH._padRsa(Enc.base64ToHex(jwk.e)));
|
els.push(SSH._padBigInt(Enc.base64ToHex(jwk.e)));
|
||||||
els.push(SSH._padRsa(Enc.base64ToHex(jwk.d)));
|
els.push(SSH._padBigInt(Enc.base64ToHex(jwk.d)));
|
||||||
els.push(SSH._padRsa(Enc.base64ToHex(jwk.qi)));
|
els.push(SSH._padBigInt(Enc.base64ToHex(jwk.qi)));
|
||||||
els.push(SSH._padRsa(Enc.base64ToHex(jwk.p)));
|
els.push(SSH._padBigInt(Enc.base64ToHex(jwk.p)));
|
||||||
els.push(SSH._padRsa(Enc.base64ToHex(jwk.q)));
|
els.push(SSH._padBigInt(Enc.base64ToHex(jwk.q)));
|
||||||
els.push(Enc.binToHex(opts.comment || ''));
|
els.push(Enc.binToHex(opts.comment || ''));
|
||||||
} else {
|
} else {
|
||||||
// swap n and e for public key format
|
// swap n and e for public key format
|
||||||
els.push(SSH._padRsa(Enc.base64ToHex(jwk.e)));
|
els.push(SSH._padBigInt(Enc.base64ToHex(jwk.e)));
|
||||||
els.push(SSH._padRsa(Enc.base64ToHex(jwk.n)));
|
els.push(SSH._padBigInt(Enc.base64ToHex(jwk.n)));
|
||||||
}
|
}
|
||||||
return els;
|
return els;
|
||||||
}
|
}
|
||||||
@ -94,11 +94,16 @@ SSH._packKey = function (opts) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
els.push('04'
|
els.push('04'
|
||||||
+ SSH._padEc(Enc.base64ToHex(jwk.x), len)
|
+ SSH._padBytes(Enc.base64ToHex(jwk.x), len)
|
||||||
+ SSH._padEc(Enc.base64ToHex(jwk.y), len)
|
+ SSH._padBytes(Enc.base64ToHex(jwk.y), len)
|
||||||
);
|
);
|
||||||
if (jwk.d) {
|
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 || ''));
|
els.push(Enc.binToHex(opts.comment || ''));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,18 +124,20 @@ SSH._numToUint32Hex = function (num) {
|
|||||||
return hex;
|
return hex;
|
||||||
};
|
};
|
||||||
|
|
||||||
SSH._padRsa = function (hex) {
|
SSH._padBigInt = function (hex) {
|
||||||
// BigInt is negative if the high order bit 0x80 is set,
|
// BigInt is negative if the high order bit 0x80 is set,
|
||||||
// so ASN1, SSH, and many other formats pad with '0x00'
|
// so ASN1, SSH, and many other formats pad with '0x00'
|
||||||
// to signifiy a positive number.
|
// to signifiy a positive number.
|
||||||
var i = parseInt(hex.slice(0, 2), 16);
|
var i = parseInt(hex.slice(0, 2), 16);
|
||||||
|
//console.warn('l', hex.length/2, 'i', i);
|
||||||
if (0x80 & i) {
|
if (0x80 & i) {
|
||||||
|
//console.warn('0x80 true');
|
||||||
return '00' + hex;
|
return '00' + hex;
|
||||||
}
|
}
|
||||||
return hex;
|
return hex;
|
||||||
};
|
};
|
||||||
|
|
||||||
SSH._padEc = function (hex, len) {
|
SSH._padBytes = function (hex, len) {
|
||||||
while (hex.length < len * 2) {
|
while (hex.length < len * 2) {
|
||||||
hex = '00' + hex;
|
hex = '00' + hex;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user