public override object Deserialize(Stream aStream)
{
/* check for required parameters */
if (aStream == null) {
throw new ArgumentNullException("aStream");
}
/* reading unencrypted part */
BlobParser parser = new BlobParser(aStream);
parser.ReadBytes((uint)FILE_HEADER_LINE.Length + 2); //Skipping header line
byte cipherType = parser.ReadByte();
if (cipherType != SSH_CIPHER_3DES && cipherType != SSH_CIPHER_NONE) {
//TripleDes is the only encryption supported
throw new KeyFormatterException("Unsupported cypherType: " + cipherType);
}
parser.ReadInt(); //reserved
/* reading public key */
AsymmetricKeyParameter aPublicKeyParameter =
parser.ReadSsh1PublicKeyData(false);
String keyComment = parser.ReadString();
/* reading private key */
byte[] inputBuffer = new byte[aStream.Length];
aStream.Read(inputBuffer, 0, inputBuffer.Length);
byte[] ouputBuffer;
try {
if (cipherType == 3) {
/* private key is 3DES encrypted */
PasswordFinder pwFinder = null;
if (GetPassphraseCallbackMethod != null) {
pwFinder = new PasswordFinder(GetPassphraseCallbackMethod);
}
byte[] keydata;
try {
using (MD5 md5 = MD5.Create()) {
char[] md5Buffer = pwFinder.GetPassword();
keydata = md5.ComputeHash(Encoding.ASCII.GetBytes(md5Buffer));
}
} catch (PasswordException ex) {
if (GetPassphraseCallbackMethod == null) {
throw new CallbackNullException();
}
throw new KeyFormatterException("see inner exception", ex);
}
/* decryption */
DesSsh1Engine desEngine = new DesSsh1Engine();
desEngine.Init(false, new KeyParameter(keydata));
BufferedBlockCipher bufferedBlockCipher = new BufferedBlockCipher(desEngine);
ouputBuffer = bufferedBlockCipher.ProcessBytes(inputBuffer);
} else {
/* private key is stored in plain text */
ouputBuffer = inputBuffer;
}
var privateKeyParser = new BlobParser(ouputBuffer);
/* checking result of decryption */
byte[] resultCheck = privateKeyParser.ReadBytes(4);
if (resultCheck[0] != resultCheck[2] || resultCheck[1] != resultCheck[3]) {
throw new KeyFormatterException("bad passphrase");
}
/* reading private key */
var keyPair = privateKeyParser.ReadSsh1KeyData(aPublicKeyParameter);
SshKey key = new SshKey(SshVersion.SSH1, keyPair);
key.Comment = keyComment;
return key;
} catch (KeyFormatterException) {
throw;
} catch (Exception ex) {
throw new KeyFormatterException("see inner exception", ex);
}
}