
net.sf.sshapi.impl.maverick.MaverickIdentityManager Maven / Gradle / Ivy
Go to download
Maverick is the definitive solution for total SSH compatibility on the Java™ platform. The library is designed to support SSH1 and SSH2 using any version of the Java Development Kit from 1.1 and above, and the API is also now J2ME-ready1 in anticipation of the new breed of interconnected mobile devices
Downloads and more information about Maverick may be found at http://www.sshtools.co.uk/en/j2ssh-maverick/.
This library is the provider bridge for SSHAPI.
The newest version!
/*
* Copyright (c) 2010 The JavaSSH Project
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package net.sf.sshapi.impl.maverick;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
import com.sshtools.publickey.InvalidPassphraseException;
import com.sshtools.publickey.OpenSSHPublicKeyFile;
import com.sshtools.publickey.SECSHPublicKeyFile;
import com.sshtools.publickey.SshKeyPairGenerator;
import com.sshtools.publickey.SshPrivateKeyFileFactory;
import com.sshtools.publickey.SshPublicKeyFileFactory;
import com.sshtools.ssh.components.SshKeyPair;
import net.sf.sshapi.Logger.Level;
import net.sf.sshapi.SshConfiguration;
import net.sf.sshapi.SshException;
import net.sf.sshapi.SshPrivateKey;
import net.sf.sshapi.SshPublicKey;
import net.sf.sshapi.identity.SshIdentityManager;
import net.sf.sshapi.identity.SshPrivateKeyFile;
import net.sf.sshapi.identity.SshPublicKeyFile;
/**
* Maverick implementation of an {@link SshIdentityManager}, used for managing
* private keys used for authentication.
*/
public class MaverickIdentityManager implements SshIdentityManager {
public SshPrivateKeyFile createPrivateKeyFromStream(InputStream in) throws SshException {
try {
return new MaverickPrivateKeyFile(SshPrivateKeyFileFactory.parse(in));
} catch (IOException e) {
throw new SshException(SshException.IO_ERROR, e);
}
}
public SshPublicKeyFile createPublicKeyFromStream(InputStream in) throws SshException {
try {
return new MaverickPublicKeyFile(SshPublicKeyFileFactory.parse(in));
} catch (IOException e) {
throw new SshException(SshException.IO_ERROR, e);
}
}
public SshPrivateKeyFile create(net.sf.sshapi.identity.SshKeyPair pair, int format, char[] passphrase,
String comment) throws SshException {
int typeNo = SshPrivateKeyFileFactory.OPENSSH_FORMAT;
if (format == SshPrivateKeyFile.VENDOR_OPENSSH) {
typeNo = SshPrivateKeyFileFactory.OPENSSH_FORMAT;
} else if (format == SshPrivateKeyFile.VENDOR_SSHTOOLS) {
typeNo = SshPrivateKeyFileFactory.SSHTOOLS_FORMAT;
} else {
throw new SshException(SshException.UNSUPPORTED_FEATURE,
"Private key file format " + format + " not supported.");
}
try {
MaverickPrivateKeyFile pk = new MaverickPrivateKeyFile(SshPrivateKeyFileFactory.create(convertPair(pair),
passphrase == null ? null : new String(passphrase), comment, typeNo));
return pk;
} catch (IOException e) {
throw new SshException(e);
}
}
private SshKeyPair convertPair(net.sf.sshapi.identity.SshKeyPair pair) {
final MaverickPublicKey publicKey = (MaverickPublicKey) pair.getPublicKey();
final MaverickPrivateKey privateKey = (MaverickPrivateKey) pair.getPrivateKey();
return SshKeyPair.getKeyPair(privateKey.privateKey, publicKey.publicKey);
}
public net.sf.sshapi.identity.SshKeyPair generateKeyPair(String keyType, int keyBits) throws SshException {
try {
SshKeyPair pair = SshKeyPairGenerator.generateKeyPair(translateKeyType(keyType), keyBits);
return new net.sf.sshapi.identity.SshKeyPair(new MaverickPublicKey(pair.getPublicKey()),
new MaverickPrivateKey(pair.getPrivateKey()));
} catch (IOException e) {
throw new SshException(SshException.IO_ERROR, e);
} catch (com.sshtools.ssh.SshException e) {
throw new SshException(SshException.GENERAL, e);
}
}
private static String translateKeyType(String type) {
if (type.equals(SshConfiguration.PUBLIC_KEY_SSHRSA)) {
return SshKeyPairGenerator.SSH2_RSA;
} else if (type.equals(SshConfiguration.PUBLIC_KEY_SSHRSA1)) {
return SshKeyPairGenerator.SSH1_RSA;
} else {
return SshKeyPairGenerator.SSH2_DSA;
}
}
public List getSupportedKeyLengths() {
return Arrays
.asList(new Integer[] { new Integer(2048), new Integer(1024), new Integer(768), new Integer(512) });
}
public List getSupportedPublicKeyFileFormats() {
return Arrays.asList(new Integer[] { new Integer(SshPublicKeyFile.OPENSSH_FORMAT),
new Integer(SshPublicKeyFile.SECSH_FORMAT), new Integer(SshPublicKeyFile.SSH1_FORMAT) });
}
public List getSupportedPrivateKeyFileFormats() {
return Arrays.asList(new Integer[] { new Integer(SshPrivateKeyFile.VENDOR_OPENSSH),
new Integer(SshPrivateKeyFile.VENDOR_SSH1), new Integer(SshPrivateKeyFile.VENDOR_SSHTOOLS) });
}
public List getSupportedKeyTypes() {
return Arrays.asList(new String[] { "ssh-dss", "ssh-rsa", "rsa1" });
}
public SshPublicKeyFile create(SshPublicKey key, String options, String comment, int format) throws SshException {
MaverickPublicKey pk = (MaverickPublicKey) key;
int type;
switch (format) {
case SshPublicKeyFile.OPENSSH_FORMAT:
type = SshPublicKeyFileFactory.OPENSSH_FORMAT;
break;
case SshPublicKeyFile.SECSH_FORMAT:
type = SshPublicKeyFileFactory.SECSH_FORMAT;
break;
case SshPublicKeyFile.SSH1_FORMAT:
type = SshPublicKeyFileFactory.SSH1_FORMAT;
break;
default:
throw new SshException(SshException.UNSUPPORTED_FEATURE, "Unsupport public key file format.");
}
com.sshtools.publickey.SshPublicKeyFile publicKeyFile;
try {
publicKeyFile = SshPublicKeyFileFactory.create(pk.publicKey, comment, type);
} catch (IOException e) {
throw new SshException(e);
}
return new MaverickPublicKeyFile(publicKeyFile);
}
class MaverickPrivateKeyFile implements SshPrivateKeyFile {
private com.sshtools.publickey.SshPrivateKeyFile privateKeyFile;
private SshKeyPair pair;
public MaverickPrivateKeyFile(com.sshtools.publickey.SshPrivateKeyFile privateKeyFile) {
this.privateKeyFile = privateKeyFile;
try {
if (!isEncrypted()) {
pair = privateKeyFile.toKeyPair(null);
}
} catch (IOException e) {
SshConfiguration.getLogger().log(Level.ERROR, "Failed to load key.");
} catch (InvalidPassphraseException e) {
SshConfiguration.getLogger().log(Level.WARN, "Failed to decode supposedly unencrypted key.");
} catch (SshException e) {
SshConfiguration.getLogger().log(Level.WARN, "Failed to test if key is encrypted.");
}
}
public void changePassphrase(char[] newPassphrase) throws SshException {
if (isEncrypted()) {
throw new SshException(SshException.PASSPHRASE_REQUIRED,
"Key is encrypted, you must decrypt it before changing the passphrase.");
}
try {
privateKeyFile.changePassphrase("", newPassphrase == null ? null : new String(newPassphrase));
} catch (IOException e) {
throw new SshException(SshException.IO_ERROR, e);
} catch (InvalidPassphraseException e) {
throw new SshException(SshException.INCORRECT_PASSPHRASE,
"Could not decrypte key, invalid passphrase.");
}
}
public byte[] getFormattedKey() throws SshException {
try {
return privateKeyFile.getFormattedKey();
} catch (IOException e) {
throw new SshException(SshException.IO_ERROR, e);
}
}
public void decrypt(char[] passphrase) throws SshException {
if (!isEncrypted()) {
throw new SshException(SshException.NOT_ENCRYPTED, "Key not encrypted.");
}
try {
pair = privateKeyFile.toKeyPair(new String(passphrase));
privateKeyFile = SshPrivateKeyFileFactory.create(pair, null, "Create by SSHAPI Identity Management",
convertType(privateKeyFile.getType()));
} catch (IOException e) {
throw new SshException(SshException.IO_ERROR, e);
} catch (InvalidPassphraseException e) {
throw new SshException(SshException.INCORRECT_PASSPHRASE,
"Could not decrypte key, invalid passphrase.");
}
}
public boolean isEncrypted() throws SshException {
return privateKeyFile.isPassphraseProtected();
}
private int convertType(String typeName) throws SshException {
if (typeName.equals("OpenSSH")) {
return SshPrivateKeyFileFactory.OPENSSH_FORMAT;
} else if (typeName.equals("SSHTools")) {
return SshPrivateKeyFileFactory.SSHTOOLS_FORMAT;
}
throw new SshException(SshException.PRIVATE_KEY_FORMAT_NOT_SUPPORTED,
"Cannot write keys in " + typeName + " format");
}
public boolean supportsPassphraseChange() {
return privateKeyFile.supportsPassphraseChange();
}
public int getFormat() {
String type = privateKeyFile.getType();
if (type.equals("OpenSSH")) {
return VENDOR_OPENSSH;
} else if (type.equals("SSHTools")) {
return VENDOR_SSHTOOLS;
} else if (type.equals("SSH1")) {
return VENDOR_SSH1;
} else if (type.equals("Putty")) {
return VENDOR_PUTTY;
} else if (type.equals("SSH Communications Security")) {
return VENDOR_SSHCOM;
}
return VENDOR_UNKNOWN;
}
public net.sf.sshapi.identity.SshKeyPair toKeyPair() throws SshException {
if (isEncrypted()) {
throw new SshException(SshException.PASSPHRASE_REQUIRED,
"Key is encrypted, you must decrypt it before extracing the keys.");
}
try {
return new net.sf.sshapi.identity.SshKeyPair(new MaverickPublicKey(pair.getPublicKey()),
new MaverickPrivateKey(pair.getPrivateKey()));
} catch (com.sshtools.ssh.SshException e) {
throw new SshException(SshException.GENERAL, e);
}
}
}
class MaverickPrivateKey implements SshPrivateKey {
private com.sshtools.ssh.components.SshPrivateKey privateKey;
public MaverickPrivateKey(com.sshtools.ssh.components.SshPrivateKey privateKey) {
this.privateKey = privateKey;
}
public byte[] sign(byte[] data) throws SshException {
try {
return privateKey.sign(data);
} catch (IOException e) {
throw new SshException(SshException.IO_ERROR, e);
}
}
public String getAlgorithm() {
return privateKey.getAlgorithm();
}
}
class MaverickPublicKey implements SshPublicKey {
private byte[] key;
private String fingerPrint;
private String algorithm;
private int bitLength;
private com.sshtools.ssh.components.SshPublicKey publicKey;
public MaverickPublicKey(com.sshtools.publickey.SshPublicKeyFile publicKeyFile)
throws com.sshtools.ssh.SshException, IOException {
init(publicKeyFile.toPublicKey());
}
private void init(com.sshtools.ssh.components.SshPublicKey publicKey) throws com.sshtools.ssh.SshException {
this.publicKey = publicKey;
key = publicKey.getEncoded();
algorithm = publicKey.getAlgorithm();
fingerPrint = publicKey.getFingerprint();
bitLength = publicKey.getBitLength();
}
public MaverickPublicKey(com.sshtools.ssh.components.SshPublicKey publicKey)
throws com.sshtools.ssh.SshException {
init(publicKey);
}
public MaverickPublicKey(SshPublicKey publicKey) throws SshException {
key = publicKey.getEncodedKey();
fingerPrint = publicKey.getFingerprint();
algorithm = publicKey.getAlgorithm();
bitLength = publicKey.getBitLength();
}
public String getAlgorithm() {
return algorithm;
}
public String getFingerprint() {
return fingerPrint;
}
public byte[] getEncodedKey() {
return key;
}
public int getBitLength() {
return bitLength;
}
}
class MaverickPublicKeyFile implements SshPublicKeyFile {
private byte[] formattedKey;
private String options;
private String comment;
private MaverickPublicKey publicKey;
private final int format;
public MaverickPublicKeyFile(com.sshtools.publickey.SshPublicKeyFile keyFile) throws SshException {
comment = keyFile.getComment();
// Not supported :(
// options = keyFile.getOptions();
try {
formattedKey = keyFile.getFormattedKey();
publicKey = new MaverickPublicKey(keyFile.toPublicKey());
} catch (Exception e) {
throw new SshException(SshException.GENERAL, e);
}
if (keyFile instanceof OpenSSHPublicKeyFile) {
format = SshPublicKeyFile.OPENSSH_FORMAT;
} else if (keyFile instanceof SECSHPublicKeyFile) {
format = SshPublicKeyFile.SECSH_FORMAT;
} else if (keyFile.getClass().getName().endsWith(".Ssh1RsaPublicKeyFile")) {
// ^^ Wasn't public
format = SshPublicKeyFile.SSH1_FORMAT;
} else {
throw new SshException(SshException.UNSUPPORTED_FEATURE,
"Unsupported public key file of type " + keyFile.getClass());
}
}
public SshPublicKey getPublicKey() throws SshException {
return publicKey;
}
public String getComment() {
return comment;
}
public byte[] getFormattedKey() {
return formattedKey;
}
public String getOptions() {
return options;
}
public int getFormat() {
return format;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy