All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sshtools.agent.InMemoryKeyStore Maven / Gradle / Ivy

There is a newer version: 3.1.2
Show newest version
/**
 * (c) 2002-2021 JADAPTIVE Limited. All Rights Reserved.
 *
 * This file is part of the Maverick Synergy Java SSH API.
 *
 * Maverick Synergy is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Maverick Synergy is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Maverick Synergy.  If not, see .
 */
package com.sshtools.agent;

import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import com.sshtools.agent.exceptions.KeyTimeoutException;
import com.sshtools.agent.openssh.OpenSSHAgentMessages;
import com.sshtools.common.publickey.SshKeyUtils;
import com.sshtools.common.ssh.SshException;
import com.sshtools.common.ssh.components.SshKeyPair;
import com.sshtools.common.ssh.components.SshPrivateKey;
import com.sshtools.common.ssh.components.SshPublicKey;
import com.sshtools.common.ssh.components.SshRsaPublicKey;


/**
 * A store for maintaining public keys in agent 
 */
public class InMemoryKeyStore implements KeyStore {
 
    HashMap descriptions = new HashMap();
    HashMap publickeys = new HashMap(); 
    HashMap privatekeys = new HashMap(); 
    HashMap constraints = new HashMap();
    Vector index = new Vector();
    Vector listeners = new Vector();
    String lockedPassword = null;

    /**
     * Creates a new KeyStore object.
     */
    public InMemoryKeyStore() {
    }

    /* (non-Javadoc)
	 * @see com.maverick.agent.IKeyStore#getPublicKeys()
	 */
    @Override
	public Map getPublicKeys() {
    	Map res = new HashMap();
    	for(Map.Entry key : publickeys.entrySet()) {
    		res.put(key.getValue(), descriptions.get(key.getKey()));
    	}
        return Collections.unmodifiableMap(res);
    }

    /**
     * Find the index of a key.
     *
     * @param key The key to look for.
     *
     * @return
     */
    public int indexOf(SshPublicKey  key) {
        return index.indexOf(key);
    }

    /**
     * Get the public key at the specified index
     *
     * @param i The index of the key.
     *
     * @return
     */
    public SshPublicKey elementAt(int i) {
        return index.elementAt(i);
    }

    /* (non-Javadoc)
	 * @see com.maverick.agent.IKeyStore#getKeyConstraints(com.maverick.ssh.components.SshPublicKey)
	 */
    @Override
	public KeyConstraints getKeyConstraints(SshPublicKey key) {
        return (KeyConstraints) constraints.get(SshKeyUtils.getFingerprint(key));
    }

    /* (non-Javadoc)
	 * @see com.maverick.agent.IKeyStore#size()
	 */
    @Override
	public int size() {
        return index.size();
    }

    /**
     * Add a listener.
     *
     * @param listener
     */
    public void addKeyStoreListener(KeyStoreListener listener) {
        listeners.add(listener);
    }

    /**
     * Remove a listener.
     *
     * @param listener
     */
    public void removeKeyStoreListener(KeyStoreListener listener) {
        listeners.remove(listener);
    }

    /* (non-Javadoc)
	 * @see com.maverick.agent.IKeyStore#addKey(com.maverick.ssh.components.SshPrivateKey, com.maverick.ssh.components.SshPublicKey, java.lang.String, com.maverick.agent.KeyConstraints)
	 */
    @Override
	public boolean addKey(SshPrivateKey prvkey, SshPublicKey pubkey,
        String description, KeyConstraints cs) throws IOException {
    	String fingerprint = getFingerprint(pubkey);
        synchronized (publickeys) {
            if (!publickeys.containsKey(fingerprint)) {
                publickeys.put(fingerprint, pubkey);
                privatekeys.put(fingerprint, prvkey); 
                constraints.put(fingerprint, cs);
                descriptions.put(fingerprint, description);
                index.add(pubkey);

                Iterator it = listeners.iterator();
                KeyStoreListener listener;

                while (it.hasNext()) {
                    listener = it.next();
                    listener.onAddKey(this);
                }

                return true;
            } else {
                return false;
            }
        }
    }

    private String getFingerprint(SshPublicKey key) {
    	try {
			return key.getFingerprint();
		} catch (SshException e) {
			throw new IllegalStateException(e.getMessage(), e);
		}
    }
    /* (non-Javadoc)
	 * @see com.maverick.agent.IKeyStore#addKey(com.maverick.ssh.components.SshKeyPair, java.lang.String, com.maverick.agent.KeyConstraints)
	 */
    @Override
	public boolean addKey(SshKeyPair pair, String description, KeyConstraints cs) throws IOException {
    	return addKey(pair.getPrivateKey(), pair.getPublicKey(), description, cs);
    }
    
    /* (non-Javadoc)
	 * @see com.maverick.agent.IKeyStore#deleteAllKeys()
	 */
    @Override
	public boolean deleteAllKeys() {
        synchronized (publickeys) {
            publickeys.clear();
            privatekeys.clear();
            constraints.clear();
            index.clear();

            Iterator it = listeners.iterator();
            KeyStoreListener listener;

            while (it.hasNext()) {
                listener = it.next();
                listener.onDeleteAllKeys(this);
            }
        }
        
        return true;
    }

    /* (non-Javadoc)
	 * @see com.maverick.agent.IKeyStore#performHashAndSign(com.maverick.ssh.components.SshPublicKey, java.util.List, byte[])
	 */
    @Override
	public byte[] performHashAndSign(SshPublicKey pubkey, List forwardingNodes,
        byte[] data, int flags)
        throws KeyTimeoutException, SshException   {
    	String fingerprint = getFingerprint(pubkey);
        synchronized (publickeys) {
            if (privatekeys.containsKey(fingerprint)) {
                SshPrivateKey key = (SshPrivateKey) privatekeys.get(fingerprint);
                KeyConstraints cs = (KeyConstraints) constraints.get(fingerprint); 

                if (cs.canUse()) {
                    if (!cs.hasTimedOut()) {
                        cs.use();
                        try{
                        	String signingAlgorithm = pubkey.getSigningAlgorithm();
                        	switch(flags) {
                        	case OpenSSHAgentMessages.SSH_AGENT_RSA_SHA2_256:
                        		if(pubkey instanceof SshRsaPublicKey) {
                        			signingAlgorithm = "rsa-sha2-256";
                        		}
                        		break;
                        	case OpenSSHAgentMessages.SSH_AGENT_RSA_SHA2_512:
                        		if(pubkey instanceof SshRsaPublicKey) {
                        			signingAlgorithm = "rsa-sha2-512";
                        		}
                        		break;
                        	default:
                        	}
                        	byte[] sig = key.sign(data, signingAlgorithm);
                        	Iterator it = listeners.iterator();
                        	KeyStoreListener listener;

                        	while (it.hasNext()) {
                        		listener = it.next();
                        		listener.onKeyOperation(this, "hash-and-sign");
                        	}
                            return sig;
                        }catch(IOException ioe){
                        	throw new SshException(ioe.getMessage(),SshException.AGENT_ERROR);
                        }
                    } else {
                        throw new KeyTimeoutException();
                    }
                } else {
                    throw new KeyTimeoutException();
                }
            } else {
                throw new SshException("The key does not exist",SshException.AGENT_ERROR);
            }
        }
    }

    /* (non-Javadoc)
	 * @see com.maverick.agent.IKeyStore#deleteKey(com.maverick.ssh.components.SshPublicKey)
	 */
    @Override
	public boolean deleteKey(SshPublicKey pubkey)
        throws IOException {
        synchronized (publickeys) {
        		String fingerprint = SshKeyUtils.getFingerprint(pubkey);
            if (publickeys.containsKey(fingerprint)) {
                
                publickeys.remove(fingerprint);
                privatekeys.remove(fingerprint);
                constraints.remove(fingerprint);
                index.remove(pubkey);

                Iterator it = listeners.iterator();
                KeyStoreListener listener;

                while (it.hasNext()) {
                    listener = it.next();
                    listener.onDeleteKey(this);
                }

                return true;
            
            }

            return false;
        }
    }

    /* (non-Javadoc)
	 * @see com.maverick.agent.IKeyStore#lock(java.lang.String)
	 */
    @Override
	public boolean lock(String password) throws IOException {
        synchronized (publickeys) {
            if (lockedPassword == null) {
                lockedPassword = password;

                Iterator it = listeners.iterator();
                KeyStoreListener listener;

                while (it.hasNext()) {
                    listener = it.next();
                    listener.onLock(this);
                }

                return true;
            } else {
                return false;
            }
        }
    }

    /* (non-Javadoc)
	 * @see com.maverick.agent.IKeyStore#unlock(java.lang.String)
	 */
    @Override
	public boolean unlock(String password) throws IOException {
        synchronized (publickeys) {
            if (lockedPassword != null) {
                if (password.equals(lockedPassword)) {
                    lockedPassword = null;

                    Iterator it = listeners.iterator();
                    KeyStoreListener listener;

                    while (it.hasNext()) {
                        listener = it.next();
                        listener.onUnlock(this);
                    }

                    return true;
                }
            }

            return false;
        }
    }
    
    /* (non-Javadoc)
	 * @see com.maverick.agent.IKeyStore#isLocked()
	 */
    @Override
	public boolean isLocked(){
    	return (lockedPassword !=null);
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy