public override void Serialize(Stream aStream, object aObject)
{
/* check for required parameters */
if (aStream == null) {
throw new ArgumentNullException("aStream");
}
if (aObject == null) {
throw new ArgumentNullException("aObject");
}
PasswordFinder pwFinder = null;
if (GetPassphraseCallbackMethod != null) {
pwFinder = new PasswordFinder(GetPassphraseCallbackMethod);
}
PinnedArray<char> passphrase = null;
if (pwFinder != null) {
passphrase = new PinnedArray<char>(0);
passphrase.Data = pwFinder.GetPassword();
}
byte cipherType;
if (passphrase == null || passphrase.Data.Length == 0) {
cipherType = SSH_CIPHER_NONE;
} else {
cipherType = SSH_CIPHER_3DES;
}
BlobBuilder builder = new BlobBuilder();
ISshKey sshKey = aObject as ISshKey;
RsaKeyParameters publicKeyParams = sshKey.GetPublicKeyParameters()
as RsaKeyParameters;
RsaPrivateCrtKeyParameters privateKeyParams = sshKey.GetPrivateKeyParameters()
as RsaPrivateCrtKeyParameters;
/* writing info headers */
builder.AddBytes(Encoding.ASCII.GetBytes(FILE_HEADER_LINE + "\n"));
builder.AddByte(0); //end of string
builder.AddByte(cipherType); //cipher
builder.AddInt(0); //reserved
/* writing public key */
builder.AddInt(sshKey.Size);
builder.AddSsh1BigIntBlob(publicKeyParams.Modulus);
builder.AddSsh1BigIntBlob(publicKeyParams.Exponent);
builder.AddStringBlob(sshKey.Comment);
/* writing private key */
BlobBuilder privateKeyBuilder = new BlobBuilder();
/* adding some control values */
Random random = new Random();
byte[] resultCheck = new byte[2];
random.NextBytes(resultCheck);
privateKeyBuilder.AddByte(resultCheck[0]);
privateKeyBuilder.AddByte(resultCheck[1]);
privateKeyBuilder.AddByte(resultCheck[0]);
privateKeyBuilder.AddByte(resultCheck[1]);
privateKeyBuilder.AddSsh1BigIntBlob(privateKeyParams.Exponent);
privateKeyBuilder.AddSsh1BigIntBlob(privateKeyParams.DQ);
privateKeyBuilder.AddSsh1BigIntBlob(privateKeyParams.P);
privateKeyBuilder.AddSsh1BigIntBlob(privateKeyParams.Q);
if (cipherType == SSH_CIPHER_NONE) {
/* plain-text */
builder.AddBytes(privateKeyBuilder.GetBlobAsPinnedByteArray().Data);
} else {
byte[] keydata;
using (MD5 md5 = MD5.Create()) {
keydata = md5.ComputeHash(Encoding.ASCII.GetBytes(passphrase.Data));
}
/* encryption */
DesSsh1Engine desEngine = new DesSsh1Engine();
desEngine.Init(true, new KeyParameter(keydata));
BufferedBlockCipher bufferedBlockCipher = new BufferedBlockCipher(desEngine);
byte[] ouputBuffer = bufferedBlockCipher.ProcessBytes(
privateKeyBuilder.GetBlobAsPinnedByteArray().Data);
builder.AddBytes(ouputBuffer);
passphrase.Dispose();
}
/* writing result to file */
var builderOutput = builder.GetBlobAsPinnedByteArray();
aStream.Write(builderOutput.Data, 0, builderOutput.Data.Length);
aStream.Close();
}