Esempio n. 1
0
        public static DSAKeyPair GenKeyPair()
        {
            using (var provider = new DSACryptoServiceProvider())
            {
                var keyPair = new DSAKeyPair();
                keyPair.PrivateKey = provider.ExportCspBlob(true);
                keyPair.PublicKey  = provider.ExportCspBlob(false);

                return(keyPair);
            }
        }
Esempio n. 2
0
        private void EntryPoint()
        {
            _mouseMoveCount = 0;
            KeyPair kp;

            if (_algorithm == PublicKeyAlgorithm.DSA)
            {
                kp = DSAKeyPair.GenerateNew(_bits, _rnd);
            }
            else
            {
                kp = RSAKeyPair.GenerateNew(_bits, _rnd);
            }
            _parent.SetResultKey(new SSH2UserAuthKey(kp));
        }
Esempio n. 3
0
        //Tutorial: Generating a new DSA key for user authentication
        private static void GenerateDSAKey()
        {
            //DSA KEY GENERATION TEST
            byte[]     testdata = Encoding.ASCII.GetBytes("CHRISTIAN VIERI");
            DSAKeyPair kp       = DSAKeyPair.GenerateNew(2048, new Random());

            //sign and verify test
            byte[] sig = kp.Sign(testdata);
            kp.Verify(sig, testdata);

            //export / import test
            SSH2UserAuthKey key = new SSH2UserAuthKey(kp);

            key.WritePublicPartInOpenSSHStyle(new FileStream("newdsakey.pub", FileMode.Create));
            key.WritePrivatePartInSECSHStyleFile(new FileStream("newrsakey.bin", FileMode.Create), "comment", "passphrase");
            //read test
            SSH2UserAuthKey newpk = SSH2UserAuthKey.FromSECSHStyleFile("newrsakey.bin", "passphrase");
        }
        /// <summary>
        /// Read PuTTY SSH2 private key parameters.
        /// </summary>
        /// <param name="passphrase">passphrase for decrypt the key file</param>
        /// <param name="keyPair">key pair</param>
        /// <param name="comment">comment or empty if it didn't exist</param>
        public void Load(string passphrase, out KeyPair keyPair, out string comment)
        {
            if (keyFile == null)
            {
                throw new SSHException("A key file is not loaded yet");
            }

            int             version;
            string          keyTypeName;
            KeyType         keyType;
            string          encryptionName;
            CipherAlgorithm?encryption;

            byte[] publicBlob;
            byte[] privateBlob;
            string privateMac;
            string privateHash;

            using (StreamReader sreader = GetStreamReader()) {
                //*** Read header and key type
                ReadHeaderLine(sreader, out version, out keyTypeName);

                if (keyTypeName == "ssh-rsa")
                {
                    keyType = KeyType.RSA;
                }
                else if (keyTypeName == "ssh-dss")
                {
                    keyType = KeyType.DSA;
                }
                else
                {
                    throw new SSHException(Strings.GetString("NotValidPrivateKeyFile") + " (unexpected key type)");
                }

                //*** Read encryption
                ReadItemLine(sreader, "Encryption", out encryptionName);

                if (encryptionName == "aes256-cbc")
                {
                    encryption = CipherAlgorithm.AES256;
                }
                else if (encryptionName == "none")
                {
                    encryption = null;
                }
                else
                {
                    throw new SSHException(Strings.GetString("NotValidPrivateKeyFile") + " (unexpected encryption)");
                }

                //*** Read comment
                ReadItemLine(sreader, "Comment", out comment);

                //*** Read public lines
                string publicLinesStr;
                ReadItemLine(sreader, "Public-Lines", out publicLinesStr);
                int publicLines;
                if (!Int32.TryParse(publicLinesStr, out publicLines) || publicLines < 0)
                {
                    throw new SSHException(Strings.GetString("NotValidPrivateKeyFile") + " (invalid public lines)");
                }

                ReadBlob(sreader, publicLines, out publicBlob);

                //*** Read private lines
                string privateLinesStr;
                ReadItemLine(sreader, "Private-Lines", out privateLinesStr);
                int privateLines;
                if (!Int32.TryParse(privateLinesStr, out privateLines) || privateLines < 0)
                {
                    throw new SSHException(Strings.GetString("NotValidPrivateKeyFile") + " (invalid private lines)");
                }

                ReadBlob(sreader, privateLines, out privateBlob);

                //*** Read private MAC
                ReadPrivateMACLine(sreader, version, out privateMac, out privateHash);
            }

            if (encryption.HasValue)
            {
                byte[] key    = PuTTYPassphraseToKey(passphrase);
                byte[] iv     = new byte[16];
                Cipher cipher = CipherFactory.CreateCipher(SSHProtocol.SSH2, encryption.Value, key, iv);
                if (privateBlob.Length % cipher.BlockSize != 0)
                {
                    throw new SSHException(Strings.GetString("NotValidPrivateKeyFile") + " (invalid key data size)");
                }
                cipher.Decrypt(privateBlob, 0, privateBlob.Length, privateBlob, 0);
            }

            bool verified = Verify(version, privateMac, privateHash,
                                   passphrase, keyTypeName, encryptionName, comment, publicBlob, privateBlob);

            if (!verified)
            {
                if (encryption.HasValue)
                {
                    throw new SSHException(Strings.GetString("WrongPassphrase"));
                }
                else
                {
                    throw new SSHException(Strings.GetString("NotValidPrivateKeyFile") + " (HMAC verification failed)");
                }
            }

            if (keyType == KeyType.RSA)
            {
                SSH2DataReader reader = new SSH2DataReader(publicBlob);
                byte[]         magic  = reader.ReadString();
                if (!ByteArrayUtil.AreEqual(magic, Encoding.ASCII.GetBytes("ssh-rsa")))
                {
                    throw new SSHException(Strings.GetString("NotValidPrivateKeyFile") + " (missing magic)");
                }

                BigInteger e = reader.ReadMPInt();
                BigInteger n = reader.ReadMPInt();

                reader = new SSH2DataReader(privateBlob);
                BigInteger d    = reader.ReadMPInt();
                BigInteger p    = reader.ReadMPInt();
                BigInteger q    = reader.ReadMPInt();
                BigInteger iqmp = reader.ReadMPInt();

                BigInteger u = p.modInverse(q);

                keyPair = new RSAKeyPair(e, d, n, u, p, q);
            }
            else if (keyType == KeyType.DSA)
            {
                SSH2DataReader reader = new SSH2DataReader(publicBlob);
                byte[]         magic  = reader.ReadString();
                if (!ByteArrayUtil.AreEqual(magic, Encoding.ASCII.GetBytes("ssh-dss")))
                {
                    throw new SSHException(Strings.GetString("NotValidPrivateKeyFile") + " (missing magic)");
                }

                BigInteger p = reader.ReadMPInt();
                BigInteger q = reader.ReadMPInt();
                BigInteger g = reader.ReadMPInt();
                BigInteger y = reader.ReadMPInt();

                reader = new SSH2DataReader(privateBlob);
                BigInteger x = reader.ReadMPInt();

                keyPair = new DSAKeyPair(p, g, q, y, x);
            }
            else
            {
                throw new SSHException("Unknown file type. This should not happen.");
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Read OpenSSH SSH2 private key parameters.
        /// </summary>
        /// <param name="passphrase">passphrase for decrypt the key file</param>
        /// <param name="keyPair">key pair</param>
        /// <param name="comment">comment or empty if it didn't exist</param>
        public void Load(string passphrase, out KeyPair keyPair, out string comment)
        {
            if (keyFile == null)
            {
                throw new SSHException("A key file is not loaded yet");
            }

            KeyType         keyType;
            String          base64Text;
            bool            encrypted  = false;
            CipherAlgorithm?encryption = null;

            byte[] iv      = null;
            int    keySize = 0;
            int    ivSize  = 0;

            using (StreamReader sreader = GetStreamReader()) {
                string line = sreader.ReadLine();
                if (line == null)
                {
                    throw new SSHException(Strings.GetString("NotValidPrivateKeyFile") + " (unexpected eof)");
                }

                if (line == PrivateKeyFileHeader.SSH2_OPENSSH_HEADER_RSA)
                {
                    keyType = KeyType.RSA;
                }
                else if (line == PrivateKeyFileHeader.SSH2_OPENSSH_HEADER_DSA)
                {
                    keyType = KeyType.DSA;
                }
                else
                {
                    throw new SSHException(Strings.GetString("NotValidPrivateKeyFile") + " (unexpected key type)");
                }

                string footer = line.Replace("BEGIN", "END");

                StringBuilder buf = new StringBuilder();
                comment = String.Empty;
                while (true)
                {
                    line = sreader.ReadLine();
                    if (line == null)
                    {
                        throw new SSHException(Strings.GetString("NotValidPrivateKeyFile") + " (unexpected eof)");
                    }
                    if (line == footer)
                    {
                        break;
                    }
                    if (line.IndexOf(':') >= 0)
                    {
                        if (line.StartsWith("Proc-Type:"))
                        {
                            string[] w = line.Substring("Proc-Type:".Length).Trim().Split(',');
                            if (w.Length < 1)
                            {
                                throw new SSHException(Strings.GetString("NotValidPrivateKeyFile") + " (invalid Proc-Type)");
                            }
                            if (w[0] != "4")
                            {
                                throw new SSHException(Strings.GetString("UnsupportedPrivateKeyFormat")
                                                       + " (" + Strings.GetString("Reason_UnsupportedProcType") + ")");
                            }
                            if (w.Length >= 2 && w[1] == "ENCRYPTED")
                            {
                                encrypted = true;
                            }
                        }
                        else if (line.StartsWith("DEK-Info:"))
                        {
                            string[] w = line.Substring("DEK-Info:".Length).Trim().Split(',');
                            if (w.Length < 2)
                            {
                                throw new SSHException(Strings.GetString("NotValidPrivateKeyFile") + " (invalid DEK-Info)");
                            }
                            switch (w[0])
                            {
                            case "DES-EDE3-CBC":
                                encryption = CipherAlgorithm.TripleDES;
                                ivSize     = 8;
                                keySize    = 24;
                                break;

                            case "AES-128-CBC":
                                encryption = CipherAlgorithm.AES128;
                                ivSize     = 16;
                                keySize    = 16;
                                break;

                            default:
                                throw new SSHException(Strings.GetString("UnsupportedPrivateKeyFormat")
                                                       + " (" + Strings.GetString("Reason_UnsupportedEncryptionType") + ")");
                            }
                            iv = HexToByteArray(w[1]);
                            if (iv == null || iv.Length != ivSize)
                            {
                                throw new SSHException(Strings.GetString("NotValidPrivateKeyFile") + " (invalid IV)");
                            }
                        }
                    }
                    else
                    {
                        buf.Append(line);
                    }
                }
                base64Text = buf.ToString();
            }

            byte[] keydata = Base64.Decode(Encoding.ASCII.GetBytes(base64Text));

            if (encrypted)
            {
                if (!encryption.HasValue || iv == null)
                {
                    throw new SSHException(Strings.GetString("NotValidPrivateKeyFile") + " (missing encryption type or IV)");
                }
                byte[] key    = OpenSSHPassphraseToKey(passphrase, iv, keySize);
                Cipher cipher = CipherFactory.CreateCipher(SSHProtocol.SSH2, encryption.Value, key, iv);
                if (keydata.Length % cipher.BlockSize != 0)
                {
                    throw new SSHException(Strings.GetString("NotValidPrivateKeyFile") + " (invalid key data size)");
                }
                cipher.Decrypt(keydata, 0, keydata.Length, keydata, 0);
            }

            using (MemoryStream keyDataStream = new MemoryStream(keydata, false)) {
                BERReader reader = new BERReader(keyDataStream);
                if (!reader.ReadSequence())
                {
                    throw new SSHException(Strings.GetString("WrongPassphrase"));
                }
                if (keyType == KeyType.RSA)
                {
                    /* from OpenSSL rsa_asn1.c
                     *
                     * ASN1_SIMPLE(RSA, version, LONG),
                     * ASN1_SIMPLE(RSA, n, BIGNUM),
                     * ASN1_SIMPLE(RSA, e, BIGNUM),
                     * ASN1_SIMPLE(RSA, d, BIGNUM),
                     * ASN1_SIMPLE(RSA, p, BIGNUM),
                     * ASN1_SIMPLE(RSA, q, BIGNUM),
                     * ASN1_SIMPLE(RSA, dmp1, BIGNUM),
                     * ASN1_SIMPLE(RSA, dmq1, BIGNUM),
                     * ASN1_SIMPLE(RSA, iqmp, BIGNUM)
                     */
                    BigInteger v, n, e, d, p, q, dmp1, dmq1, iqmp;
                    if (!reader.ReadInteger(out v) ||
                        !reader.ReadInteger(out n) ||
                        !reader.ReadInteger(out e) ||
                        !reader.ReadInteger(out d) ||
                        !reader.ReadInteger(out p) ||
                        !reader.ReadInteger(out q) ||
                        !reader.ReadInteger(out dmp1) ||
                        !reader.ReadInteger(out dmq1) ||
                        !reader.ReadInteger(out iqmp))
                    {
                        throw new SSHException(Strings.GetString("WrongPassphrase"));
                    }

                    BigInteger u = p.modInverse(q);     // inverse of p mod q
                    keyPair = new RSAKeyPair(e, d, n, u, p, q);
                }
                else if (keyType == KeyType.DSA)
                {
                    /* from OpenSSL dsa_asn1.c
                     *
                     * ASN1_SIMPLE(DSA, version, LONG),
                     * ASN1_SIMPLE(DSA, p, BIGNUM),
                     * ASN1_SIMPLE(DSA, q, BIGNUM),
                     * ASN1_SIMPLE(DSA, g, BIGNUM),
                     * ASN1_SIMPLE(DSA, pub_key, BIGNUM),
                     * ASN1_SIMPLE(DSA, priv_key, BIGNUM)
                     */
                    BigInteger v, p, q, g, y, x;
                    if (!reader.ReadInteger(out v) ||
                        !reader.ReadInteger(out p) ||
                        !reader.ReadInteger(out q) ||
                        !reader.ReadInteger(out g) ||
                        !reader.ReadInteger(out y) ||
                        !reader.ReadInteger(out x))
                    {
                        throw new SSHException(Strings.GetString("WrongPassphrase"));
                    }
                    keyPair = new DSAKeyPair(p, g, q, y, x);
                }
                else
                {
                    throw new SSHException("Unknown file type. This should not happen.");
                }
            }
        }
        /// <summary>
        /// Read SSH.com SSH2 private key parameters.
        /// </summary>
        /// <param name="passphrase">passphrase for decrypt the key file</param>
        /// <param name="keyPair">key pair</param>
        /// <param name="comment">comment or empty if it didn't exist</param>
        /// <exception cref="SSHException">failed to parse</exception>
        public void Load(string passphrase, out KeyPair keyPair, out string comment)
        {
            if (keyFile == null)
            {
                throw new SSHException("A key file is not loaded yet");
            }

            String base64Text;

            using (StreamReader sreader = GetStreamReader()) {
                string line = sreader.ReadLine();
                if (line == null || line != PrivateKeyFileHeader.SSH2_SSHCOM_HEADER)
                {
                    throw new SSHException(Strings.GetString("NotValidPrivateKeyFile") + " (missing header)");
                }

                StringBuilder buf = new StringBuilder();
                comment = String.Empty;
                while (true)
                {
                    line = sreader.ReadLine();
                    if (line == null)
                    {
                        throw new SSHException(Strings.GetString("NotValidPrivateKeyFile") + " (unexpected eof)");
                    }
                    if (line == PrivateKeyFileHeader.SSH2_SSHCOM_FOOTER)
                    {
                        break;
                    }
                    if (line.IndexOf(':') >= 0)
                    {
                        if (line.StartsWith("Comment: "))
                        {
                            comment = line.Substring("Comment: ".Length);
                        }
                    }
                    else if (line[line.Length - 1] == '\\')
                    {
                        buf.Append(line, 0, line.Length - 1);
                    }
                    else
                    {
                        buf.Append(line);
                    }
                }
                base64Text = buf.ToString();
            }

            byte[] keydata = Base64.Decode(Encoding.ASCII.GetBytes(base64Text));
            //Debug.WriteLine(DebugUtil.DumpByteArray(keydata));

            SSH2DataReader reader = new SSH2DataReader(keydata);
            int            magic  = reader.ReadInt32();

            if (magic != MAGIC)
            {
                throw new SSHException(Strings.GetString("NotValidPrivateKeyFile") + " (magic code unmatched)");
            }
            int    privateKeyLen = reader.ReadInt32();
            string type          = Encoding.ASCII.GetString(reader.ReadString());

            string ciphername = Encoding.ASCII.GetString(reader.ReadString());
            int    bufLen     = reader.ReadInt32();

            if (ciphername != "none")
            {
                CipherAlgorithm algo = CipherFactory.SSH2NameToAlgorithm(ciphername);
                byte[]          key  = SSH2UserAuthKey.PassphraseToKey(passphrase, CipherFactory.GetKeySize(algo));
                Cipher          c    = CipherFactory.CreateCipher(SSHProtocol.SSH2, algo, key);
                byte[]          tmp  = new Byte[reader.Image.Length - reader.Offset];
                c.Decrypt(reader.Image, reader.Offset, reader.Image.Length - reader.Offset, tmp, 0);
                reader = new SSH2DataReader(tmp);
            }

            int parmLen = reader.ReadInt32();

            if (parmLen < 0 || parmLen > reader.Rest)
            {
                throw new SSHException(Strings.GetString("WrongPassphrase"));
            }

            if (type.IndexOf("if-modn") != -1)
            {
                //mindterm mistaken this order of BigIntegers
                BigInteger e = reader.ReadBigIntWithBits();
                BigInteger d = reader.ReadBigIntWithBits();
                BigInteger n = reader.ReadBigIntWithBits();
                BigInteger u = reader.ReadBigIntWithBits();
                BigInteger p = reader.ReadBigIntWithBits();
                BigInteger q = reader.ReadBigIntWithBits();
                keyPair = new RSAKeyPair(e, d, n, u, p, q);
            }
            else if (type.IndexOf("dl-modp") != -1)
            {
                if (reader.ReadInt32() != 0)
                {
                    throw new SSHException(Strings.GetString("UnsupportedPrivateKeyFormat")
                                           + " (" + Strings.GetString("Reason_UnsupportedDSAKeyFormat") + ")");
                }
                BigInteger p = reader.ReadBigIntWithBits();
                BigInteger g = reader.ReadBigIntWithBits();
                BigInteger q = reader.ReadBigIntWithBits();
                BigInteger y = reader.ReadBigIntWithBits();
                BigInteger x = reader.ReadBigIntWithBits();
                keyPair = new DSAKeyPair(p, g, q, y, x);
            }
            else
            {
                throw new SSHException(Strings.GetString("UnsupportedAuthenticationMethod"));
            }
        }
        public void WritePrivatePartInSECSHStyleFile(Stream dest, string comment, string passphrase)
        {
            //step1 key body
            SSH2DataWriter wr = new SSH2DataWriter();

            wr.Write(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.Write(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)
            {
                Cipher c = CipherFactory.CreateCipher(SSHProtocol.SSH2, CipherAlgorithm.TripleDES, PassphraseToKey(passphrase, 24));
                Debug.Assert(encrypted_body.Length % 8 == 0);
                byte[] 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.Write(MAGIC_VAL);
            wr.Write(0);             //for total size
            wr.Write(_keypair.Algorithm == PublicKeyAlgorithm.RSA?
                     "if-modn{sign{rsa-pkcs1-sha1},encrypt{rsa-pkcs1v2-oaep}}" :
                     "dl-modp{sign{dsa-nist-sha1},dh{plain}}");

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

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

            //step3 write final data
            StreamWriter 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();
        }
Esempio n. 8
0
        public byte[] ToByteArray(string passphrase)
        {
            //step1 key body
            SSH2DataWriter wr = new SSH2DataWriter();

            wr.Write(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.Write(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)
            {
                Cipher c = CipherFactory.CreateCipher(SSHProtocol.SSH2, CipherAlgorithm.TripleDES, PassphraseToKey(passphrase, 24));
                Debug.Assert(encrypted_body.Length % 8 == 0);
                byte[] 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.Write(MAGIC_VAL);
            wr.Write(0); //for total size
            wr.Write(_keypair.Algorithm == PublicKeyAlgorithm.RSA ?
                     "if-modn{sign{rsa-pkcs1-sha1},encrypt{rsa-pkcs1v2-oaep}}" :
                     "dl-modp{sign{dsa-nist-sha1},dh{plain}}");

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

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

            return(rawdata);
        }
Esempio n. 9
0
        static void Main(string[] args)
        {
            /*
             * string cn = System.Threading.Thread.CurrentThread.CurrentUICulture.Name;
             * string t1 = Routrek.SSHC.Strings.GetString("NotSSHServer");
             * System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("ja");
             * Routrek.SSHC.Strings.Reload();
             * string t2 = Routrek.SSHC.Strings.GetString("NotSSHServer");
             */

#if false //RSA keygen
            //RSA KEY GENERATION TEST
            byte[]     testdata = Encoding.ASCII.GetBytes("CHRISTIAN VIERI");
            RSAKeyPair kp       = RSAKeyPair.GenerateNew(2048, new Random());
            byte[]     sig      = kp.Sign(testdata);
            kp.Verify(sig, testdata);

            new SSH2UserAuthKey(kp).WritePublicPartInOpenSSHStyle(new FileStream("C:\\IOPort\\newrsakey", FileMode.Create));
            //SSH2UserAuthKey newpk = SSH2PrivateKey.FromSECSHStyleFile("C:\\IOPort\\newrsakey", "nedved");
#endif

#if false //DSA keygen
            //DSA KEY GENERATION TEST
            byte[]     testdata = Encoding.ASCII.GetBytes("CHRISTIAN VIERI 0000");
            DSAKeyPair kp       = DSAKeyPair.GenerateNew(2048, new Random());
            byte[]     sig      = kp.Sign(testdata);
            kp.Verify(sig, testdata);
            new SSH2UserAuthKey(kp).WritePublicPartInOpenSSHStyle(new FileStream("C:\\IOPort\\newdsakey", FileMode.Create));
            //SSH2PrivateKey newpk = SSH2PrivateKey.FromSECSHStyleFile("C:\\IOPort\\newdsakey", "nedved");
#endif

            SSHConnectionParameter f = new SSHConnectionParameter();
            f.UserName = "******";
#if false //SSH1
            //SSH1
            f.Password                   = "";
            f.Protocol                   = SSHProtocol.SSH2;
            f.AuthenticationType         = AuthenticationType.Password;
            f.PreferableCipherAlgorithms = new CipherAlgorithm[] { CipherAlgorithm.Blowfish, CipherAlgorithm.TripleDES };
#else //SSH2
            f.Password           = "";
            f.Protocol           = SSHProtocol.SSH2;
            f.AuthenticationType = AuthenticationType.Password;
            f.WindowSize         = 0x1000;
#endif
            Reader reader = new Reader();
            Socket s      = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //s.Blocking = false;
            s.Connect(new IPEndPoint(IPAddress.Parse("192.168.1.1"), 22));
            _conn        = SSHConnection.Connect(f, reader, s);
            reader._conn = _conn;
#if false   //Remote->Local
            _conn.ListenForwardedPort("0.0.0.0", 29472);
#elif false //Local->Remote
            SSHChannel ch = _conn.ForwardPort(reader, "www.yahoo.co.jp", 80, "localhost", 0);
            reader._pf = ch;
            while (!reader._ready)
            {
                System.Threading.Thread.Sleep(100);
            }
            reader._pf.Transmit(Encoding.ASCII.GetBytes("GET / HTTP/1.0\r\n\r\n"));
#elif false //SSH over SSH
            f.Password = "******";
            SSHConnection con2 = _conn.OpenPortForwardedAnotherConnection(f, reader, "kuromatsu", 22);
            reader._conn = con2;
            SSHChannel ch = con2.OpenShell(reader);
            reader._pf = ch;
#else //normal shell
            SSHChannel ch = _conn.OpenShell(reader);
            reader._pf = ch;
#endif

            //Debug.WriteLine(_conn.ConnectionInfo.DumpHostKeyInKnownHostsStyle());
            SSHConnectionInfo ci = _conn.ConnectionInfo;

            Thread.Sleep(1000);
            //((SSH2Connection)_conn).ReexchangeKeys();

            byte[] b = new byte[1];
            while (true)
            {
                int input = System.Console.Read();

                b[0] = (byte)input;
                //Debug.WriteLine(input);
                reader._pf.Transmit(b);
            }
        }
Esempio n. 10
0
        /// <summary>
        /// Read private key parameters.
        /// </summary>
        /// <param name="passphrase">passphrase for decrypt the key file</param>
        /// <param name="keyPair">key pair</param>
        /// <param name="comment">comment or empty if it didn't exist</param>
        public void Load(string passphrase, out KeyPair keyPair, out string comment)
        {
            PEMKeyType      keyType;
            String          base64Text;
            bool            encrypted  = false;
            CipherAlgorithm?encryption = null;

            byte[] iv      = null;
            int    keySize = 0;
            int    ivSize  = 0;

            using (StreamReader sreader = GetStreamReader()) {
                string line = sreader.ReadLine();
                if (line == null)
                {
                    throw new SSHException(Strings.GetString("NotValidPrivateKeyFile") + " (unexpected eof)");
                }

                if (line == PrivateKeyFileHeader.SSH2_OPENSSH_HEADER_RSA)
                {
                    keyType = PEMKeyType.RSA;
                }
                else if (line == PrivateKeyFileHeader.SSH2_OPENSSH_HEADER_DSA)
                {
                    keyType = PEMKeyType.DSA;
                }
                else if (line == PrivateKeyFileHeader.SSH2_OPENSSH_HEADER_ECDSA)
                {
                    keyType = PEMKeyType.ECDSA;
                }
                else
                {
                    throw new SSHException(Strings.GetString("NotValidPrivateKeyFile") + " (unexpected key type)");
                }

                string footer = line.Replace("BEGIN", "END");

                StringBuilder buf = new StringBuilder();
                comment = String.Empty;
                while (true)
                {
                    line = sreader.ReadLine();
                    if (line == null)
                    {
                        throw new SSHException(Strings.GetString("NotValidPrivateKeyFile") + " (unexpected eof)");
                    }
                    if (line == footer)
                    {
                        break;
                    }
                    if (line.IndexOf(':') >= 0)
                    {
                        if (line.StartsWith("Proc-Type:"))
                        {
                            string[] w = line.Substring("Proc-Type:".Length).Trim().Split(',');
                            if (w.Length < 1)
                            {
                                throw new SSHException(Strings.GetString("NotValidPrivateKeyFile") + " (invalid Proc-Type)");
                            }
                            if (w[0] != "4")
                            {
                                throw new SSHException(Strings.GetString("UnsupportedPrivateKeyFormat")
                                                       + " (" + Strings.GetString("Reason_UnsupportedProcType") + ")");
                            }
                            if (w.Length >= 2 && w[1] == "ENCRYPTED")
                            {
                                encrypted = true;
                            }
                        }
                        else if (line.StartsWith("DEK-Info:"))
                        {
                            string[] w = line.Substring("DEK-Info:".Length).Trim().Split(',');
                            if (w.Length < 2)
                            {
                                throw new SSHException(Strings.GetString("NotValidPrivateKeyFile") + " (invalid DEK-Info)");
                            }
                            switch (w[0])
                            {
                            case "DES-EDE3-CBC":
                                encryption = CipherAlgorithm.TripleDES;
                                ivSize     = 8;
                                keySize    = 24;
                                break;

                            case "AES-128-CBC":
                                encryption = CipherAlgorithm.AES128;
                                ivSize     = 16;
                                keySize    = 16;
                                break;

                            default:
                                throw new SSHException(Strings.GetString("UnsupportedPrivateKeyFormat")
                                                       + " (" + Strings.GetString("Reason_UnsupportedEncryptionType") + ")");
                            }
                            iv = HexToByteArray(w[1]);
                            if (iv == null || iv.Length != ivSize)
                            {
                                throw new SSHException(Strings.GetString("NotValidPrivateKeyFile") + " (invalid IV)");
                            }
                        }
                    }
                    else
                    {
                        buf.Append(line);
                    }
                }
                base64Text = buf.ToString();
            }

            byte[] keydata = Base64.Decode(Encoding.ASCII.GetBytes(base64Text));

            if (encrypted)
            {
                if (!encryption.HasValue || iv == null)
                {
                    throw new SSHException(Strings.GetString("NotValidPrivateKeyFile") + " (missing encryption type or IV)");
                }
                byte[] key    = PassphraseToKey(passphrase, iv, keySize);
                Cipher cipher = CipherFactory.CreateCipher(SSHProtocol.SSH2, encryption.Value, key, iv);
                if (keydata.Length % cipher.BlockSize != 0)
                {
                    throw new SSHException(Strings.GetString("NotValidPrivateKeyFile") + " (invalid key data size)");
                }
                cipher.Decrypt(keydata, 0, keydata.Length, keydata, 0);
            }

            using (MemoryStream keyDataStream = new MemoryStream(keydata, false)) {
                BERReader reader = new BERReader(keyDataStream);
                if (!reader.ReadSequence())
                {
                    throw new SSHException(Strings.GetString("WrongPassphrase"));
                }
                if (keyType == PEMKeyType.RSA)
                {
                    /* from OpenSSL rsa_asn1.c
                     *
                     * ASN1_SIMPLE(RSA, version, LONG),
                     * ASN1_SIMPLE(RSA, n, BIGNUM),
                     * ASN1_SIMPLE(RSA, e, BIGNUM),
                     * ASN1_SIMPLE(RSA, d, BIGNUM),
                     * ASN1_SIMPLE(RSA, p, BIGNUM),
                     * ASN1_SIMPLE(RSA, q, BIGNUM),
                     * ASN1_SIMPLE(RSA, dmp1, BIGNUM),
                     * ASN1_SIMPLE(RSA, dmq1, BIGNUM),
                     * ASN1_SIMPLE(RSA, iqmp, BIGNUM)
                     */
                    BigInteger v, n, e, d, p, q, dmp1, dmq1, iqmp;
                    if (!reader.ReadInteger(out v) ||
                        !reader.ReadInteger(out n) ||
                        !reader.ReadInteger(out e) ||
                        !reader.ReadInteger(out d) ||
                        !reader.ReadInteger(out p) ||
                        !reader.ReadInteger(out q) ||
                        !reader.ReadInteger(out dmp1) ||
                        !reader.ReadInteger(out dmq1) ||
                        !reader.ReadInteger(out iqmp))
                    {
                        throw new SSHException(Strings.GetString("WrongPassphrase"));
                    }

                    BigInteger u = p.ModInverse(q);     // inverse of p mod q
                    keyPair = new RSAKeyPair(e, d, n, u, p, q);
                }
                else if (keyType == PEMKeyType.DSA)
                {
                    /* from OpenSSL dsa_asn1.c
                     *
                     * ASN1_SIMPLE(DSA, version, LONG),
                     * ASN1_SIMPLE(DSA, p, BIGNUM),
                     * ASN1_SIMPLE(DSA, q, BIGNUM),
                     * ASN1_SIMPLE(DSA, g, BIGNUM),
                     * ASN1_SIMPLE(DSA, pub_key, BIGNUM),
                     * ASN1_SIMPLE(DSA, priv_key, BIGNUM)
                     */
                    BigInteger v, p, q, g, y, x;
                    if (!reader.ReadInteger(out v) ||
                        !reader.ReadInteger(out p) ||
                        !reader.ReadInteger(out q) ||
                        !reader.ReadInteger(out g) ||
                        !reader.ReadInteger(out y) ||
                        !reader.ReadInteger(out x))
                    {
                        throw new SSHException(Strings.GetString("WrongPassphrase"));
                    }
                    keyPair = new DSAKeyPair(p, g, q, y, x);
                }
                else if (keyType == PEMKeyType.ECDSA)
                {
                    /* from OpenSSL ec_asn1.c
                     *
                     * ASN1_SIMPLE(EC_PRIVATEKEY, version, LONG),
                     * ASN1_SIMPLE(EC_PRIVATEKEY, privateKey, ASN1_OCTET_STRING),
                     * ASN1_EXP_OPT(EC_PRIVATEKEY, parameters, ECPKPARAMETERS, 0),
                     *   ------
                     *   ASN1_SIMPLE(ECPKPARAMETERS, value.named_curve, ASN1_OBJECT),
                     *   ------
                     * ASN1_EXP_OPT(EC_PRIVATEKEY, publicKey, ASN1_BIT_STRING, 1)
                     */
                    int        len;
                    byte[]     privateKey;
                    byte[]     publicKey;
                    string     namedCurve;
                    BigInteger v;
                    if (!reader.ReadInteger(out v) ||
                        !reader.ReadOctetString(out privateKey) ||
                        !reader.ReadTag(BERReader.TagClass.ContextSpecific, true, 0, out len) ||
                        !reader.ReadObjectIdentifier(out namedCurve) ||
                        !reader.ReadTag(BERReader.TagClass.ContextSpecific, true, 1, out len) ||
                        !reader.ReadBitString(out publicKey))
                    {
                        throw new SSHException(Strings.GetString("WrongPassphrase"));
                    }

                    EllipticCurve curve = EllipticCurve.FindByOID(namedCurve);
                    if (curve == null)
                    {
                        throw new SSHException(Strings.GetString("UnsupportedEllipticCurveInKeyPair"));
                    }

                    ECPoint ecPublicKeyPoint;
                    if (!ECPoint.Parse(publicKey, curve, out ecPublicKeyPoint))
                    {
                        throw new SSHException(Strings.GetString("KeysAreBroken"));
                    }

                    var ecKeyPair = new ECDSAKeyPair(curve, new ECDSAPublicKey(curve, ecPublicKeyPoint), new BigInteger(privateKey));

                    if (!ecKeyPair.CheckKeyConsistency())
                    {
                        throw new SSHException(Strings.GetString("KeysAreBroken"));
                    }

                    keyPair = ecKeyPair;
                }
                else
                {
                    throw new SSHException("Unknown file type. This should not happen.");
                }
            }
        }
Esempio n. 11
0
        /// <summary>
        /// Read PuTTY SSH2 private key parameters.
        /// </summary>
        /// <param name="passphrase">passphrase for decrypt the key file</param>
        /// <param name="keyPair">key pair</param>
        /// <param name="comment">comment or empty if it didn't exist</param>
        public void Load(string passphrase, out KeyPair keyPair, out string comment)
        {
            if (keyFile == null)
            {
                throw new SSHException("A key file is not loaded yet");
            }

            int             version;
            string          keyTypeName;
            KeyType         keyType;
            string          encryptionName;
            CipherAlgorithm?encryption;

            byte[] publicBlob;
            byte[] privateBlob;
            string privateMac;
            string privateHash;

            using (StreamReader sreader = GetStreamReader())
            {
                //*** Read header and key type
                ReadHeaderLine(sreader, out version, out keyTypeName);

                if (keyTypeName == "ssh-rsa")
                {
                    keyType = KeyType.RSA;
                }
                else if (keyTypeName == "ssh-dss")
                {
                    keyType = KeyType.DSA;
                }
                else if (keyTypeName.StartsWith("ecdsa-sha2-"))
                {
                    keyType = KeyType.ECDSA;
                }
                else if (keyTypeName == "ssh-ed25519")
                {
                    keyType = KeyType.ED25519;
                }
                else
                {
                    throw new SSHException(Strings.GetString("NotValidPrivateKeyFile") + " (unexpected key type)");
                }

                //*** Read encryption
                ReadItemLine(sreader, "Encryption", out encryptionName);

                if (encryptionName == "aes256-cbc")
                {
                    encryption = CipherAlgorithm.AES256;
                }
                else if (encryptionName == "none")
                {
                    encryption = null;
                    passphrase = "";    // prevent HMAC error
                }
                else
                {
                    throw new SSHException(Strings.GetString("NotValidPrivateKeyFile") + " (unexpected encryption)");
                }

                //*** Read comment
                ReadItemLine(sreader, "Comment", out comment);

                //*** Read public lines
                string publicLinesStr;
                ReadItemLine(sreader, "Public-Lines", out publicLinesStr);
                int publicLines;
                if (!Int32.TryParse(publicLinesStr, out publicLines) || publicLines < 0)
                {
                    throw new SSHException(Strings.GetString("NotValidPrivateKeyFile") + " (invalid public lines)");
                }

                ReadBlob(sreader, publicLines, out publicBlob);

                //*** Read private lines
                string privateLinesStr;
                ReadItemLine(sreader, "Private-Lines", out privateLinesStr);
                int privateLines;
                if (!Int32.TryParse(privateLinesStr, out privateLines) || privateLines < 0)
                {
                    throw new SSHException(Strings.GetString("NotValidPrivateKeyFile") + " (invalid private lines)");
                }

                ReadBlob(sreader, privateLines, out privateBlob);

                //*** Read private MAC
                ReadPrivateMACLine(sreader, version, out privateMac, out privateHash);
            }

            if (encryption.HasValue)
            {
                byte[] key    = PuTTYPassphraseToKey(passphrase);
                byte[] iv     = new byte[16];
                Cipher cipher = CipherFactory.CreateCipher(SSHProtocol.SSH2, encryption.Value, key, iv);
                if (privateBlob.Length % cipher.BlockSize != 0)
                {
                    throw new SSHException(Strings.GetString("NotValidPrivateKeyFile") + " (invalid key data size)");
                }
                cipher.Decrypt(privateBlob, 0, privateBlob.Length, privateBlob, 0);
            }

            bool verified = Verify(version, privateMac, privateHash,
                                   passphrase, keyTypeName, encryptionName, comment, publicBlob, privateBlob);

            if (!verified)
            {
                if (encryption.HasValue)
                {
                    throw new SSHException(Strings.GetString("WrongPassphrase"));
                }
                else
                {
                    throw new SSHException(Strings.GetString("NotValidPrivateKeyFile") + " (HMAC verification failed)");
                }
            }

            if (keyType == KeyType.RSA)
            {
                SSH2DataReader reader = new SSH2DataReader(publicBlob);
                string         magic  = reader.ReadString();
                if (magic != "ssh-rsa")
                {
                    throw new SSHException(Strings.GetString("NotValidPrivateKeyFile") + " (missing magic)");
                }

                BigInteger e = reader.ReadMPInt();
                BigInteger n = reader.ReadMPInt();

                reader = new SSH2DataReader(privateBlob);
                BigInteger d    = reader.ReadMPInt();
                BigInteger p    = reader.ReadMPInt();
                BigInteger q    = reader.ReadMPInt();
                BigInteger iqmp = reader.ReadMPInt();

                BigInteger u = p.ModInverse(q);

                keyPair = new RSAKeyPair(e, d, n, u, p, q);
            }
            else if (keyType == KeyType.DSA)
            {
                SSH2DataReader reader = new SSH2DataReader(publicBlob);
                string         magic  = reader.ReadString();
                if (magic != "ssh-dss")
                {
                    throw new SSHException(Strings.GetString("NotValidPrivateKeyFile") + " (missing magic)");
                }

                BigInteger p = reader.ReadMPInt();
                BigInteger q = reader.ReadMPInt();
                BigInteger g = reader.ReadMPInt();
                BigInteger y = reader.ReadMPInt();

                reader = new SSH2DataReader(privateBlob);
                BigInteger x = reader.ReadMPInt();

                keyPair = new DSAKeyPair(p, g, q, y, x);
            }
            else if (keyType == KeyType.ECDSA)
            {
                SSH2DataReader reader        = new SSH2DataReader(publicBlob);
                string         algorithmName = reader.ReadString();
                string         curveName     = reader.ReadString();
                byte[]         publicKeyPt   = reader.ReadByteString();

                reader = new SSH2DataReader(privateBlob);
                BigInteger privateKey = reader.ReadMPInt();

                EllipticCurve curve = EllipticCurve.FindByName(curveName);
                if (curve == null)
                {
                    throw new SSHException(Strings.GetString("UnsupportedEllipticCurve") + " : " + curveName);
                }
                ECPoint publicKey;
                if (!ECPoint.Parse(publicKeyPt, curve, out publicKey))
                {
                    throw new SSHException(Strings.GetString("NotValidPrivateKeyFile") + " (parsing public key failed)");
                }

                keyPair = new ECDSAKeyPair(curve, new ECDSAPublicKey(curve, publicKey), privateKey);

                if (!((ECDSAKeyPair)keyPair).CheckKeyConsistency())
                {
                    throw new SSHException(Strings.GetString("NotValidPrivateKeyFile") + " (invalid key pair)");
                }
            }
            else if (keyType == KeyType.ED25519)
            {
                SSH2DataReader reader        = new SSH2DataReader(publicBlob);
                string         algorithmName = reader.ReadString();
                byte[]         publicKey     = reader.ReadByteString();

                reader = new SSH2DataReader(privateBlob);
                byte[] privateKey = reader.ReadByteString();

                EdwardsCurve curve = EdwardsCurve.FindByAlgorithm(PublicKeyAlgorithm.ED25519);
                if (curve == null)
                {
                    throw new SSHException(Strings.GetString("UnsupportedEllipticCurve"));
                }

                keyPair = new EDDSAKeyPair(curve, new EDDSAPublicKey(curve, publicKey), privateKey);

                if (!((EDDSAKeyPair)keyPair).CheckKeyConsistency())
                {
                    throw new SSHException(Strings.GetString("NotValidPrivateKeyFile") + " (invalid key pair)");
                }
            }
            else
            {
                throw new SSHException("Unknown file type. This should not happen.");
            }
        }