Exemple #1
0
 internal static RSAPublicKey ReadFrom(SSH2DataReader reader)
 {
     BigInteger exp = reader.ReadMPInt();
     BigInteger mod = reader.ReadMPInt();
     return new RSAPublicKey(exp, mod);
 }
        /// <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);
                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 {
                throw new SSHException("Unknown file type. This should not happen.");
            }
        }
        private void VerifyHostKeyByRSA(SSH2DataReader pubkey, byte[] sigbody, byte[] hash) {
            BigInteger exp = pubkey.ReadMPInt();
            BigInteger mod = pubkey.ReadMPInt();
            Debug.Assert(pubkey.Rest==0);

            RSAPublicKey pk = new RSAPublicKey(exp, mod);
            pk.VerifyWithSHA1(sigbody, new SHA1CryptoServiceProvider().ComputeHash(hash));
            _cInfo._hostkey = pk;
        }
        private void VerifyHostKeyByDSS(SSH2DataReader pubkey, byte[] sigbody, byte[] hash) {
            BigInteger p = pubkey.ReadMPInt();
            BigInteger q = pubkey.ReadMPInt();
            BigInteger g = pubkey.ReadMPInt();
            BigInteger y = pubkey.ReadMPInt();
            Debug.Assert(pubkey.Rest==0);

            DSAPublicKey pk = new DSAPublicKey(p,g,q,y);
            pk.Verify(sigbody, new SHA1CryptoServiceProvider().ComputeHash(hash));
            _cInfo._hostkey = pk;
        }
        private bool ProcessKEXDHREPLY(DataFragment packet) {
            //Round2 receives response
            SSH2DataReader re = null;
            PacketType h;
            do {
                re = new SSH2DataReader(packet);
                h = re.ReadPacketType();
                if(h==PacketType.SSH_MSG_KEXDH_REPLY)
                    break; //successfully exit
                else if(h==PacketType.SSH_MSG_IGNORE || h==PacketType.SSH_MSG_DEBUG) { //continue
                    packet = _connection.ReceivePacket();
                }
                else
                    throw new SSHException(String.Format("KeyExchange response is not KEXDH_REPLY but {0}", h));
            } while(true);

            byte[] key_and_cert = re.ReadString();
            BigInteger f = re.ReadMPInt();
            byte[] signature = re.ReadString();
            Debug.Assert(re.Rest==0);

            //Round3 calc hash H
            SSH2DataWriter wr = new SSH2DataWriter();
            _k = f.modPow(_x, DH_PRIME);
            wr = new SSH2DataWriter();
            wr.Write(_cInfo._clientVersionString);
            wr.Write(_cInfo._serverVersionString);
            wr.WriteAsString(_clientKEXINITPayload);
            wr.WriteAsString(_serverKEXINITPayload);
            wr.WriteAsString(key_and_cert);
            wr.Write(_e);
            wr.Write(f);
            wr.Write(_k);
            _hash = new SHA1CryptoServiceProvider().ComputeHash(wr.ToByteArray());

            _connection.TraceReceptionEvent(h, "verifying host key");
            if(!VerifyHostKey(key_and_cert, signature, _hash)) return false;

            //Debug.WriteLine("hash="+DebugUtil.DumpByteArray(hash));
            if(_sessionID==null) _sessionID = _hash;
            return true;
        }
Exemple #6
0
 internal static DSAPublicKey ReadFrom(SSH2DataReader reader)
 {
     BigInteger p = reader.ReadMPInt();
     BigInteger q = reader.ReadMPInt();
     BigInteger g = reader.ReadMPInt();
     BigInteger y = reader.ReadMPInt();
     return new DSAPublicKey(p, g, q, y);
 }
Exemple #7
0
        public void Verify(byte[] data, byte[] expected) {
            SSH2DataReader reader = new SSH2DataReader(data);
            BigInteger r = reader.ReadMPInt();
            BigInteger s = reader.ReadMPInt();
            if (r == 0 || r >= _curve.Order || s == 0 || s >= _curve.Order) {
                goto Fail;
            }

            if (!IsValid()) {
                goto Fail;
            }

            BigInteger order = _curve.Order;

            byte[] hash = HashForSigning(expected, _curve);
            BigInteger e = new BigInteger(hash);

            BigInteger.ModulusRing nring = new BigInteger.ModulusRing(order);

            try {
                BigInteger sInv = s.ModInverse(order);
                BigInteger u1 = nring.Multiply(e, sInv);
                BigInteger u2 = nring.Multiply(r, sInv);

                ECPoint p1 = _curve.PointMul(u1, _curve.BasePoint, true);
                ECPoint p2 = _curve.PointMul(u2, Point, true);
                if (p1 == null || p2 == null) {
                    goto Fail;
                }
                ECPoint R = _curve.PointAdd(p1, p2, true);
                if (R == null) {
                    goto Fail;
                }

                BigInteger v = R.X % order;

                if (v != r) {
                    goto Fail;
                }
            }
            catch (Exception) {
                goto Fail;
            }

            return;

        Fail:
            throw new VerifyException("Failed to verify");
        }
Exemple #8
0
        private RSAPublicKey ReadRSAPublicKey(SSH2DataReader pubkey, byte[] sigbody, byte[] hash)
        {
            BigInteger exp = pubkey.ReadMPInt();
            BigInteger mod = pubkey.ReadMPInt();
            Debug.Assert(pubkey.RemainingDataLength == 0);

            RSAPublicKey pk = new RSAPublicKey(exp, mod);
            return pk;
        }
Exemple #9
0
        private DSAPublicKey ReadDSAPublicKey(SSH2DataReader pubkey, byte[] sigbody, byte[] hash)
        {
            BigInteger p = pubkey.ReadMPInt();
            BigInteger q = pubkey.ReadMPInt();
            BigInteger g = pubkey.ReadMPInt();
            BigInteger y = pubkey.ReadMPInt();
            Debug.Assert(pubkey.RemainingDataLength == 0);

            DSAPublicKey pk = new DSAPublicKey(p, g, q, y);
            return pk;
        }