Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

System.NotSupportedException: Key 'OPENSSH' is not supported. #485

Copy link
Copy link
@mauroa

Description

@mauroa
Issue body actions

A NotSupportedException is thrown when generating SSH keys with the "ssh-keygen" command on a Mac with macOS Mojave 10.14.1. With lower versions it's working fine.

Exception:

System.NotSupportedException: Key 'OPENSSH' is not supported.
at Renci.SshNet.PrivateKeyFile.Open(Stream privateKey, String passPhrase)
at Renci.SshNet.PrivateKeyFile..ctor(String fileName, String passPhrase)

Inspecting the generated private key I can see that the header starts with:

"-----BEGIN OPENSSH PRIVATE KEY-----"

Also, If I inspect a private key generated in a Mac with a lower macOS version, I can see something like:

"-----BEGIN RSA PRIVATE KEY-----"

The following code in this repo tries to match a Regex to detect they key name and act based on it. For this reason, It doesn't recognize "OPENSSH" as a valid private key name and it fails:

switch (keyName)
{
case "RSA":
_key = new RsaKey(decryptedData);
HostKey = new KeyHostAlgorithm("ssh-rsa", _key);
break;
case "DSA":
_key = new DsaKey(decryptedData);
HostKey = new KeyHostAlgorithm("ssh-dss", _key);
break;
case "SSH2 ENCRYPTED":
var reader = new SshDataReader(decryptedData);
var magicNumber = reader.ReadUInt32();
if (magicNumber != 0x3f6ff9eb)
{
throw new SshException("Invalid SSH2 private key.");
}
reader.ReadUInt32(); // Read total bytes length including magic number
var keyType = reader.ReadString(SshData.Ascii);
var ssh2CipherName = reader.ReadString(SshData.Ascii);
var blobSize = (int)reader.ReadUInt32();
byte[] keyData;
if (ssh2CipherName == "none")
{
keyData = reader.ReadBytes(blobSize);
}
else if (ssh2CipherName == "3des-cbc")
{
if (string.IsNullOrEmpty(passPhrase))
throw new SshPassPhraseNullOrEmptyException("Private key is encrypted but passphrase is empty.");
var key = GetCipherKey(passPhrase, 192 / 8);
var ssh2Сipher = new TripleDesCipher(key, new CbcCipherMode(new byte[8]), new PKCS7Padding());
keyData = ssh2Сipher.Decrypt(reader.ReadBytes(blobSize));
}
else
{
throw new SshException(string.Format("Cipher method '{0}' is not supported.", cipherName));
}
// TODO: Create two specific data types to avoid using SshDataReader class
reader = new SshDataReader(keyData);
var decryptedLength = reader.ReadUInt32();
if (decryptedLength > blobSize - 4)
throw new SshException("Invalid passphrase.");
if (keyType == "if-modn{sign{rsa-pkcs1-sha1},encrypt{rsa-pkcs1v2-oaep}}")
{
var exponent = reader.ReadBigIntWithBits();//e
var d = reader.ReadBigIntWithBits();//d
var modulus = reader.ReadBigIntWithBits();//n
var inverseQ = reader.ReadBigIntWithBits();//u
var q = reader.ReadBigIntWithBits();//p
var p = reader.ReadBigIntWithBits();//q
_key = new RsaKey(modulus, exponent, d, p, q, inverseQ);
HostKey = new KeyHostAlgorithm("ssh-rsa", _key);
}
else if (keyType == "dl-modp{sign{dsa-nist-sha1},dh{plain}}")
{
var zero = reader.ReadUInt32();
if (zero != 0)
{
throw new SshException("Invalid private key");
}
var p = reader.ReadBigIntWithBits();
var g = reader.ReadBigIntWithBits();
var q = reader.ReadBigIntWithBits();
var y = reader.ReadBigIntWithBits();
var x = reader.ReadBigIntWithBits();
_key = new DsaKey(p, q, g, y, x);
HostKey = new KeyHostAlgorithm("ssh-dss", _key);
}
else
{
throw new NotSupportedException(string.Format("Key type '{0}' is not supported.", keyType));
}
break;
default:
throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "Key '{0}' is not supported.", keyName));

Thanks.

adrianorc, claudio-salvio and aliasadidev

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Morty Proxy This is a proxified and sanitized view of the page, visit original site.