Example #1
0
    public void WritePrivatePartInSECSHStyleFile(Stream dest, string comment,
                                                 SecureString passphrase)
    {
      //step1 key body
      SSH2DataWriter wr = new SSH2DataWriter();
      wr.WriteInt32(0); //this field is filled later
      if (_keypair.Algorithm == PublicKeyAlgorithm.RSA)
      {
        RSAKeyPair rsa = (RSAKeyPair)_keypair;
        RSAPublicKey pub = (RSAPublicKey)_keypair.PublicKey;
        wr.WriteBigIntWithBits(pub.Exponent);
        wr.WriteBigIntWithBits(rsa.D);
        wr.WriteBigIntWithBits(pub.Modulus);
        wr.WriteBigIntWithBits(rsa.U);
        wr.WriteBigIntWithBits(rsa.P);
        wr.WriteBigIntWithBits(rsa.Q);
      }
      else
      {
        DSAKeyPair dsa = (DSAKeyPair)_keypair;
        DSAPublicKey pub = (DSAPublicKey)_keypair.PublicKey;
        wr.WriteInt32(0);
        wr.WriteBigIntWithBits(pub.P);
        wr.WriteBigIntWithBits(pub.G);
        wr.WriteBigIntWithBits(pub.Q);
        wr.WriteBigIntWithBits(pub.Y);
        wr.WriteBigIntWithBits(dsa.X);
      }

      int padding_len = 0;
      if (passphrase != null)
      {
        padding_len = 8 - (int)wr.Length%8;
        wr.Write(new byte[padding_len]);
      }
      byte[] encrypted_body = wr.ToByteArray();
      SSHUtil.WriteIntToByteArray(encrypted_body, 0,
                                  encrypted_body.Length - padding_len - 4);

      //encrypt if necessary
      if (passphrase != null)
      {
        var c = CipherFactory.CreateCipher(SSHProtocol.SSH2, CipherAlgorithm.TripleDES,
                                           PassphraseToKey(passphrase, 24));
        Debug.Assert(encrypted_body.Length%8 == 0);
        var tmp = new byte[encrypted_body.Length];
        c.Encrypt(encrypted_body, 0, encrypted_body.Length, tmp, 0);
        encrypted_body = tmp;
      }

      //step2 make binary key data
      wr = new SSH2DataWriter();
      wr.WriteInt32(MAGIC_VAL);
      wr.WriteInt32(0); //for total size
      wr.WriteString(_keypair.Algorithm == PublicKeyAlgorithm.RSA
        ? "if-modn{sign{rsa-pkcs1-sha1},encrypt{rsa-pkcs1v2-oaep}}"
        : "dl-modp{sign{dsa-nist-sha1},dh{plain}}");

      wr.WriteString(passphrase == null ? "none" : "3des-cbc");
      wr.WriteAsString(encrypted_body);

      var rawdata = wr.ToByteArray();
      SSHUtil.WriteIntToByteArray(rawdata, 4, rawdata.Length); //fix total length

      //step3 write final data
      var sw = new StreamWriter(dest, Encoding.ASCII);
      sw.WriteLine("---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----");
      if (comment != null)
        WriteKeyFileBlock(sw, "Comment: " + comment, true);
      WriteKeyFileBlock(sw, Encoding.ASCII.GetString(Base64.Encode(rawdata)), false);
      sw.WriteLine("---- END SSH2 ENCRYPTED PRIVATE KEY ----");
      sw.Close();
    }