package org.limewire.security.id;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.limewire.io.BadGGEPBlockException;
import org.limewire.io.BadGGEPPropertyException;
import org.limewire.io.GGEP;
import org.limewire.io.GUID;
import org.limewire.io.InvalidDataException;
/**
* RemoteIdKeys contains keys that the local node uses to securely communicate
* with a remote node identified with the id field.
*/
class RemoteIdKeys {
private final PublicKey signaturePublicKey;
private final SecretKey outgoingMacHmacKey;
private final SecretKey incomingVerificationHmacKey;
private final SecretKey outgoingEncryptionKey;
private final SecretKey incomingDecryptionKey;
private final GUID id;
public RemoteIdKeys(byte[] data) throws InvalidDataException {
try {
GGEP ggep = new GGEP(data);
id = new GUID(ggep.getBytes("ID"));
KeyFactory factory = KeyFactory.getInstance(SecureIdManager.SIG_KEY_ALGO);
signaturePublicKey = factory.generatePublic(new X509EncodedKeySpec(ggep.getBytes("SPK")));
outgoingMacHmacKey = new SecretKeySpec(ggep.getBytes("OUTHMAC"), SecureIdManager.MAC_ALGO);
incomingVerificationHmacKey = new SecretKeySpec(ggep.getBytes("INHMAC"), SecureIdManager.MAC_ALGO);
outgoingEncryptionKey = new SecretKeySpec(ggep.getBytes("OUTENC"), SecureIdManager.ENCRYPTION_KEY_ALGO);
incomingDecryptionKey = new SecretKeySpec(ggep.getBytes("INDEC"), SecureIdManager.ENCRYPTION_KEY_ALGO);
} catch (BadGGEPBlockException e) {
throw new InvalidDataException(e);
} catch (BadGGEPPropertyException e) {
throw new InvalidDataException(e);
} catch (NoSuchAlgorithmException e) {
throw new InvalidDataException(e);
} catch (InvalidKeySpecException e) {
throw new InvalidDataException(e);
}
}
public RemoteIdKeys(GUID id, PublicKey pk, SecretKey macHmacKey, SecretKey verificationHmacKey, SecretKey outgoingEncryptionKey, SecretKey incomingDecryptionKey) {
this.id = id;
signaturePublicKey = pk;
this.outgoingMacHmacKey = macHmacKey;
this.incomingVerificationHmacKey = verificationHmacKey;
this.outgoingEncryptionKey = outgoingEncryptionKey;
this.incomingDecryptionKey = incomingDecryptionKey;
}
public GUID getId() {
return id;
}
public PublicKey getSignaturePublicKey() {
return signaturePublicKey;
}
public SecretKey getOutgoingMacHmacKey() {
return outgoingMacHmacKey;
}
public SecretKey getIncomingVerificationHmacKey() {
return incomingVerificationHmacKey;
}
public SecretKey getOutgoingEncryptionKey() {
return outgoingEncryptionKey;
}
public SecretKey getIncomingDecryptionKey() {
return incomingDecryptionKey;
}
public byte[] toByteArray() {
GGEP ggep = new GGEP();
ggep.put("ID", id.bytes());
ggep.put("SPK", signaturePublicKey.getEncoded());
ggep.put("OUTHMAC", outgoingMacHmacKey.getEncoded());
ggep.put("INHMAC", incomingVerificationHmacKey.getEncoded());
ggep.put("OUTENC", outgoingEncryptionKey.getEncoded());
ggep.put("INDEC", incomingDecryptionKey.getEncoded());
return ggep.toByteArray();
}
}