package org.bbssh.ssh.packets;
import java.io.IOException;
import net.rim.device.api.crypto.CryptoException;
import net.rim.device.api.crypto.DSAPrivateKey;
import net.rim.device.api.crypto.DSASignatureSigner;
import net.rim.device.api.crypto.PKCS1SignatureSigner;
import net.rim.device.api.crypto.RSAPrivateKey;
import net.rim.device.api.crypto.SHA1Digest;
import org.bbssh.crypto.SignatureTools;
import org.bbssh.crypto.TypesReader;
import org.bbssh.crypto.TypesWriter;
import org.bbssh.ssh.SSHMessages;
public class PacketUserauthRequestPublicKey {
byte[] payload;
String userName;
String serviceName;
String password;
String pkAlgoName;
byte[] pkEnc;
// byte[] sig = new byte[20];
private byte[] sig;
;
public PacketUserauthRequestPublicKey(String serviceName, String user, String pkAlgorithmName, byte[] pk) {
this.serviceName = serviceName;
this.userName = user;
this.pkAlgoName = pkAlgorithmName;
this.pkEnc = pk;
}
public PacketUserauthRequestPublicKey(byte payload[], int off, int len) throws IOException {
this.payload = new byte[len];
System.arraycopy(payload, off, this.payload, 0, len);
TypesReader tr = new TypesReader(payload, off, len);
int packet_type = tr.readByte();
if (packet_type != SSHMessages.SSH_MSG_USERAUTH_REQUEST) {
throw new IOException("This is not a SSH_MSG_USERAUTH_REQUEST! (" + packet_type + ")");
}
}
// @todo can this also use the PrivateKey interface?
public PacketUserauthRequestPublicKey(RSAPrivateKey key, byte[] sessionId, String serviceName, String user,
String pkAlgorithmName) throws IOException, CryptoException {
this(serviceName, user, pkAlgorithmName, SignatureTools.encodePublicKey(key));
// Now properly intiialize our signature.
TypesWriter tw = new TypesWriter();
tw.writeString(sessionId, 0, sessionId.length);
addSharedFields(tw);
PKCS1SignatureSigner signer = new PKCS1SignatureSigner(key, new SHA1Digest());
signer.update(tw.getBytes());
byte[] s = new byte[signer.getLength()];
try {
signer.sign(s, 0);
} catch (IllegalArgumentException e) {
}
this.sig = SignatureTools.encodeSSHRSASignature(s);
}
public PacketUserauthRequestPublicKey(DSAPrivateKey key, byte[] sessionId, String serviceName, String user,
String pkAlgorithmName) throws IOException, CryptoException {
this(serviceName, user, pkAlgorithmName, SignatureTools.encodePublicKey(key));
// Now properly intiialize our signature.
TypesWriter tw = new TypesWriter();
// In addition to the auth fields, signature also requires
// the session ID.
tw.writeString(sessionId, 0, sessionId.length);
addSharedFields(tw);
DSASignatureSigner signer = new DSASignatureSigner(key, new SHA1Digest());
signer.update(tw.getBytes());
byte[] r = new byte[signer.getRLength()];
byte[] s = new byte[signer.getSLength()];
signer.sign(r, 0, s, 0);
this.sig = SignatureTools.encodeSSHDSASignature(r, s);
// Generate signature.
}
public byte[] getPayload() {
if (payload == null) {
TypesWriter tw = new TypesWriter();
addSharedFields(tw);
tw.writeString(sig, 0, sig.length);
payload = tw.getBytes();
}
return payload;
}
private void addSharedFields(TypesWriter tw) {
tw.writeByte(SSHMessages.SSH_MSG_USERAUTH_REQUEST);
tw.writeString(userName);
tw.writeString(serviceName);
tw.writeString("publickey");
tw.writeBoolean(true); // yes, we have a key.
tw.writeString(pkAlgoName);
tw.writeString(pkEnc, 0, pkEnc.length);
}
}