Mercurial > 510Connectbot
diff src/ch/ethz/ssh2/ServerConnection.java @ 298:ab3a99f11a36 ganymed
add ecdsa key support everywhere
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Tue, 29 Jul 2014 18:01:08 -0700 |
parents | d2ee20d9dff1 |
children | 349847b2e318 |
line wrap: on
line diff
--- a/src/ch/ethz/ssh2/ServerConnection.java Tue Jul 29 16:43:12 2014 -0700 +++ b/src/ch/ethz/ssh2/ServerConnection.java Tue Jul 29 18:01:08 2014 -0700 @@ -71,14 +71,16 @@ * @param s The socket * @param dsa_key The DSA hostkey, may be <code>NULL</code> * @param rsa_key The RSA hostkey, may be <code>NULL</code> + * @param ec_key The EC hostkey, may be <code>NULL</code> */ - public ServerConnection(Socket s, KeyPair dsa_key, KeyPair rsa_key) + public ServerConnection(Socket s, KeyPair dsa_key, KeyPair rsa_key, KeyPair ec_key) { state.s = s; state.softwareversion = softwareversion; state.next_dsa_key = dsa_key; state.next_rsa_key = rsa_key; - fixCryptoWishList(state.next_cryptoWishList, state.next_dsa_key, state.next_rsa_key); + state.next_ec_key = ec_key; + fixCryptoWishList(state.next_cryptoWishList, state.next_dsa_key, state.next_rsa_key, state.next_ec_key); } /** @@ -100,7 +102,7 @@ /** * Establish the connection and block until the first handshake has completed. * <p> - * Note 1: either a DSA or a RSA (or both) hostkey must be set before calling this method. + * Note 1: at least one DSA, RSA or EC hostkey must be set before calling this method. * <p> * Note 2: You must set the callbacks for authentication ({@link #setAuthenticationCallback(ServerAuthenticationCallback)}) * and connection events ({@link #setServerConnectionCallback(ServerConnectionCallback)}). @@ -126,8 +128,8 @@ if (state.tm != null) throw new IllegalStateException("The initial handshake has already been started."); - if ((state.next_dsa_key == null) && (state.next_rsa_key == null)) - throw new IllegalStateException("Neither a RSA nor a DSA host key has been specified!"); + if ((state.next_dsa_key == null) && (state.next_rsa_key == null) && (state.next_ec_key == null)) + throw new IllegalStateException("Neither an RSA nor a DSA nor an EC host key has been specified!"); state.tm = new ServerTransportManager(state.s); } @@ -171,7 +173,7 @@ throw new IllegalStateException( "Cannot force another key exchange, you need to start the key exchange first."); - state.tm.forceKeyExchange(state.next_cryptoWishList, null, state.next_dsa_key, state.next_rsa_key); + state.tm.forceKeyExchange(state.next_cryptoWishList, null, state.next_dsa_key, state.next_rsa_key, state.next_ec_key); } } @@ -199,7 +201,7 @@ } /** - * Change the current DSA hostkey. Either a DSA or RSA private key must be set for a successful handshake with + * Change the current DSA hostkey. Either a DSA or RSA or EC private key must be set for a successful handshake with * the client. * <p> * Note: You can change an existing DSA hostkey after the initial kex exchange (the new value will @@ -216,12 +218,12 @@ throw new IllegalStateException("Cannot remove DSA hostkey after first key exchange."); state.next_dsa_key = dsa_hostkey; - fixCryptoWishList(state.next_cryptoWishList, state.next_dsa_key, state.next_rsa_key); + fixCryptoWishList(state.next_cryptoWishList, state.next_dsa_key, state.next_rsa_key, state.next_ec_key); } } /** - * Change the current RSA hostkey. Either a DSA or RSA private key must be set for a successful handshake with + * Change the current RSA hostkey. Either a DSA or RSA or EC private key must be set for a successful handshake with * the client. * <p> * Note: You can change an existing RSA hostkey after the initial kex exchange (the new value will @@ -238,7 +240,29 @@ throw new IllegalStateException("Cannot remove RSA hostkey after first key exchange."); state.next_rsa_key = rsa_hostkey; - fixCryptoWishList(state.next_cryptoWishList, state.next_dsa_key, state.next_rsa_key); + fixCryptoWishList(state.next_cryptoWishList, state.next_dsa_key, state.next_rsa_key, state.next_ec_key); + } + } + + /** + * Change the current EC hostkey. Either a DSA or RSA or EC private key must be set for a successful handshake with + * the client. + * <p> + * Note: You can change an existing EC hostkey after the initial kex exchange (the new value will + * be used during the next server initiated key exchange), but you cannot remove (i.e., set to <code>null</code>) the + * current EC key, otherwise the next key exchange may fail in case the client supports only EC hostkeys. + * + * @param rsa_hostkey + */ + public synchronized void setEcHostKey(KeyPair ec_hostkey) + { + synchronized (state) + { + if ((ec_hostkey == null) && (state.next_ec_key != null) && (state.tm != null)) + throw new IllegalStateException("Cannot remove EC hostkey after first key exchange."); + + state.next_ec_key = ec_hostkey; + fixCryptoWishList(state.next_cryptoWishList, state.next_dsa_key, state.next_rsa_key, state.next_ec_key); } } @@ -258,6 +282,8 @@ if (key instanceof DSAPrivateKey) setDsaHostKey(pair); if (key instanceof RSAPrivateKey) setRsaHostKey(pair); + + if (key instanceof ECPrivateKey) setEcHostKey(pair); } /** @@ -292,16 +318,14 @@ setPEMHostKey(cw.toCharArray(), password); } - private void fixCryptoWishList(CryptoWishList next_cryptoWishList, KeyPair next_dsa_key, KeyPair next_rsa_key) + private void fixCryptoWishList(CryptoWishList next_cryptoWishList, KeyPair next_dsa_key, KeyPair next_rsa_key, KeyPair next_ec_key) { - if ((next_dsa_key != null) && (next_rsa_key != null)) - next_cryptoWishList.serverHostKeyAlgorithms = new String[] { "ssh-rsa", "ssh-dss" }; - else if (next_dsa_key != null) - next_cryptoWishList.serverHostKeyAlgorithms = new String[] { "ssh-dss" }; - else if (next_rsa_key != null) - next_cryptoWishList.serverHostKeyAlgorithms = new String[] { "ssh-rsa" }; - else - next_cryptoWishList.serverHostKeyAlgorithms = new String[0]; + List<String> algos = new ArrayList<string>(); + if (next_dsa_key != null) algos.add("ssh-dss"); + if (next_rsa_key != null) algos.add("ssh-rsa"); + if (next_ec_key != null) algos.add("ssh-ec"); + next_cryptoWishList.serverHostKeyAlgorithms = new String[algos.size()]; + algos.toArray(next_cryptoWishList.serverHostKeyAlgorithms); } /**