Update bouncycastle, cleanup, renamings

This commit is contained in:
Manfred Karrer 2015-11-02 01:57:00 +01:00
parent 07a9c7fd52
commit 3711519e3a
26 changed files with 267 additions and 210 deletions

View File

@ -22,11 +22,6 @@ import io.bitsquare.app.Version;
import java.io.Serializable;
import java.security.PublicKey;
/**
* Packs the encrypted symmetric secretKey and the encrypted and signed message into one object.
* SecretKey is encrypted with asymmetric pubKey of peer. Signed message is encrypted with secretKey.
* Using that hybrid encryption model we are not restricted by data size and performance as symmetric encryption is very fast.
*/
public final class DecryptedPayloadWithPubKey implements Serializable {
// That object is sent over the wire, so we need to take care of version compatibility.
private static final long serialVersionUID = Version.NETWORK_PROTOCOL_VERSION;
@ -39,4 +34,30 @@ public final class DecryptedPayloadWithPubKey implements Serializable {
this.sigPublicKey = sigPublicKey;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof DecryptedPayloadWithPubKey)) return false;
DecryptedPayloadWithPubKey that = (DecryptedPayloadWithPubKey) o;
if (payload != null ? !payload.equals(that.payload) : that.payload != null) return false;
return !(sigPublicKey != null ? !sigPublicKey.equals(that.sigPublicKey) : that.sigPublicKey != null);
}
@Override
public int hashCode() {
int result = payload != null ? payload.hashCode() : 0;
result = 31 * result + (sigPublicKey != null ? sigPublicKey.hashCode() : 0);
return result;
}
@Override
public String toString() {
return "DecryptedPayloadWithPubKey{" +
"payload=" + payload +
", sigPublicKey.hashCode()=" + sigPublicKey.hashCode() +
'}';
}
}

View File

@ -30,24 +30,28 @@ import java.io.Serializable;
import java.security.*;
import java.util.Arrays;
// TODO: which counter modes and paddings should we use?
// https://security.stackexchange.com/questions/52665/which-is-the-best-cipher-mode-and-padding-mode-for-aes-encryption
public class Encryption {
private static final Logger log = LoggerFactory.getLogger(Encryption.class);
public static final String ENCR_KEY_ALGO = "RSA";
public static final String SYM_KEY_ALGO = "AES";
public static final String SYM_CIPHER = "AES"; // java.security.NoSuchAlgorithmException: AES/ECB/PKCS5Padding KeyGenerator not available
public static final String ASYM_CIPHER = "RSA"; // TODO test with RSA/ECB/PKCS1Padding
public static final String ASYM_KEY_ALGO = "RSA"; // RSA/NONE/OAEPWithSHA256AndMGF1Padding
public static final String ASYM_CIPHER = "RSA";
public static final String SYM_KEY_ALGO = "AES"; // AES/CTR/NoPadding
public static final String SYM_CIPHER = "AES";
public static final String HMAC = "HmacSHA256";
public static KeyPair generateKeyPair() {
long ts = System.currentTimeMillis();
try {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ENCR_KEY_ALGO);
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ASYM_KEY_ALGO, "BC");
keyPairGenerator.initialize(2048);
KeyPair keyPair = keyPairGenerator.genKeyPair();
log.trace("Generate msgEncryptionKeyPair needed {} ms", System.currentTimeMillis() - ts);
return keyPair;
} catch (NoSuchAlgorithmException e) {
} catch (NoSuchAlgorithmException | NoSuchProviderException e) {
e.printStackTrace();
throw new RuntimeException("Could not create key.");
}
@ -60,11 +64,11 @@ public class Encryption {
public static byte[] encrypt(byte[] payload, SecretKey secretKey) throws CryptoException {
try {
Cipher cipher = Cipher.getInstance(SYM_CIPHER);
Cipher cipher = Cipher.getInstance(SYM_CIPHER, "BC");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
return cipher.doFinal(payload);
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException
| BadPaddingException | IllegalBlockSizeException e) {
| BadPaddingException | IllegalBlockSizeException | NoSuchProviderException e) {
e.printStackTrace();
throw new CryptoException(e);
}
@ -72,11 +76,11 @@ public class Encryption {
public static byte[] decrypt(byte[] encryptedPayload, SecretKey secretKey) throws CryptoException {
try {
Cipher cipher = Cipher.getInstance(SYM_CIPHER);
Cipher cipher = Cipher.getInstance(SYM_CIPHER, "BC");
cipher.init(Cipher.DECRYPT_MODE, secretKey);
return cipher.doFinal(encryptedPayload);
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException
| BadPaddingException | IllegalBlockSizeException e) {
| BadPaddingException | IllegalBlockSizeException | NoSuchProviderException e) {
e.printStackTrace();
throw new CryptoException(e);
}
@ -99,7 +103,7 @@ public class Encryption {
outputStream.write(hmac);
outputStream.flush();
payloadWithHmac = outputStream.toByteArray().clone();
} catch (IOException e) {
} catch (IOException | NoSuchProviderException e) {
e.printStackTrace();
throw new RuntimeException("Could not create hmac");
} finally {
@ -122,14 +126,14 @@ public class Encryption {
try {
byte[] hmacTest = getHmac(message, secretKey);
return Arrays.equals(hmacTest, hmac);
} catch (NoSuchAlgorithmException | InvalidKeyException e) {
} catch (NoSuchAlgorithmException | InvalidKeyException | NoSuchProviderException e) {
e.printStackTrace();
throw new RuntimeException("Could not create cipher");
}
}
private static byte[] getHmac(byte[] payload, SecretKey secretKey) throws NoSuchAlgorithmException, InvalidKeyException {
Mac mac = Mac.getInstance(HMAC);
private static byte[] getHmac(byte[] payload, SecretKey secretKey) throws NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException {
Mac mac = Mac.getInstance(HMAC, "BC");
mac.init(secretKey);
return mac.doFinal(payload);
}
@ -170,11 +174,11 @@ public class Encryption {
public static byte[] encrypt(byte[] payload, PublicKey publicKey) throws CryptoException {
try {
Cipher cipher = Cipher.getInstance(ASYM_CIPHER);
Cipher cipher = Cipher.getInstance(ASYM_CIPHER, "BC");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return cipher.doFinal(payload);
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException
| BadPaddingException | IllegalBlockSizeException e) {
| BadPaddingException | IllegalBlockSizeException | NoSuchProviderException e) {
e.printStackTrace();
throw new CryptoException("Couldn't encrypt payload");
}
@ -182,11 +186,11 @@ public class Encryption {
public static byte[] decrypt(byte[] encryptedPayload, PrivateKey privateKey) throws CryptoException {
try {
Cipher cipher = Cipher.getInstance(ASYM_CIPHER);
Cipher cipher = Cipher.getInstance(ASYM_CIPHER, "BC");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(encryptedPayload);
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException
| BadPaddingException | IllegalBlockSizeException e) {
| BadPaddingException | IllegalBlockSizeException | NoSuchProviderException e) {
// errors when trying to decrypt foreign messages are normal
throw new CryptoException(e);
}
@ -199,14 +203,13 @@ public class Encryption {
/**
* @param payload The data to encrypt.
* @param sigPrivateKey The private key for signing.
* @param sigPublicKey The public key used for signing.
* @param signatureKeyPair The key pair for signing.
* @param encryptionPublicKey The public key used for encryption.
* @return A SealedAndSigned object.
* @throws CryptoException
*/
public static SealedAndSigned encryptHybridWithSignature(Serializable payload, PrivateKey sigPrivateKey,
PublicKey sigPublicKey, PublicKey encryptionPublicKey)
public static SealedAndSigned encryptHybridWithSignature(Serializable payload, KeyPair signatureKeyPair,
PublicKey encryptionPublicKey)
throws CryptoException {
// Create a symmetric key
SecretKey secretKey = generateSecretKey();
@ -214,22 +217,15 @@ public class Encryption {
// Encrypt secretKey with receivers publicKey
byte[] encryptedSecretKey = encrypt(secretKey.getEncoded(), encryptionPublicKey);
// Encrypt with sym key and add hmac
// Encrypt with sym key payload with appended hmac
byte[] encryptedPayloadWithHmac = encryptPayloadWithHmac(payload, secretKey);
// sign hash of encryptedPayloadWithHmac
byte[] hash = Hash.getHash(encryptedPayloadWithHmac);
try {
byte[] signature = Sig.sign(sigPrivateKey, hash);
// Pack all together
return new SealedAndSigned(encryptedSecretKey, encryptedPayloadWithHmac, signature, sigPublicKey);
} catch (SignatureException | NoSuchAlgorithmException | InvalidKeyException e) {
e.printStackTrace();
throw new CryptoException(e);
}
byte[] signature = Sig.sign(signatureKeyPair.getPrivate(), hash);
// Pack all together
return new SealedAndSigned(encryptedSecretKey, encryptedPayloadWithHmac, signature, signatureKeyPair.getPublic());
}
/**
@ -240,18 +236,14 @@ public class Encryption {
*/
public static DecryptedPayloadWithPubKey decryptHybridWithSignature(SealedAndSigned sealedAndSigned, PrivateKey privateKey) throws CryptoException {
SecretKey secretKey = getSecretKeyFromBytes(decrypt(sealedAndSigned.encryptedSecretKey, privateKey));
try {
boolean isValid = Sig.verify(sealedAndSigned.sigPublicKey,
Hash.getHash(sealedAndSigned.encryptedPayloadWithHmac),
sealedAndSigned.signature);
if (!isValid)
throw new CryptoException("Signature verification failed.");
Serializable decryptedPayload = Utilities.deserialize(decryptPayloadWithHmac(sealedAndSigned.encryptedPayloadWithHmac, secretKey));
return new DecryptedPayloadWithPubKey(decryptedPayload, sealedAndSigned.sigPublicKey);
} catch (NoSuchAlgorithmException | SignatureException | InvalidKeyException e) {
boolean isValid = Sig.verify(sealedAndSigned.sigPublicKey,
Hash.getHash(sealedAndSigned.encryptedPayloadWithHmac),
sealedAndSigned.signature);
if (!isValid)
throw new CryptoException("Signature verification failed.");
}
Serializable decryptedPayload = Utilities.deserialize(decryptPayloadWithHmac(sealedAndSigned.encryptedPayloadWithHmac, secretKey));
return new DecryptedPayloadWithPubKey(decryptedPayload, sealedAndSigned.sigPublicKey);
}
@ -265,10 +257,11 @@ public class Encryption {
private static SecretKey generateSecretKey() {
try {
KeyGenerator keyPairGenerator = KeyGenerator.getInstance(SYM_CIPHER);
KeyGenerator keyPairGenerator = KeyGenerator.getInstance(SYM_CIPHER, "BC");
keyPairGenerator.init(256);
return keyPairGenerator.generateKey();
} catch (NoSuchAlgorithmException e) {
} catch (NoSuchAlgorithmException | NoSuchProviderException e) {
e.printStackTrace();
throw new RuntimeException("Couldn't generate key");
}
}

View File

@ -27,6 +27,7 @@ import java.io.Serializable;
import java.nio.ByteBuffer;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
public class Hash {
private static final Logger log = LoggerFactory.getLogger(Hash.class);
@ -38,8 +39,8 @@ public class Hash {
public static byte[] getHash(byte[] data) {
MessageDigest digest;
try {
digest = MessageDigest.getInstance("SHA-256");
} catch (NoSuchAlgorithmException e) {
digest = MessageDigest.getInstance("SHA-256", "BC");
} catch (NoSuchAlgorithmException | NoSuchProviderException e) {
log.error("Could not create MessageDigest for hash. " + e.getMessage());
throw new RuntimeException(e);
}

View File

@ -21,7 +21,6 @@ import javax.inject.Inject;
import java.security.KeyPair;
public class KeyRing {
private final KeyPair signatureKeyPair;
private final KeyPair encryptionKeyPair;
private final PubKeyRing pubKeyRing;
@ -52,4 +51,36 @@ public class KeyRing {
public PubKeyRing getPubKeyRing() {
return pubKeyRing;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof KeyRing)) return false;
KeyRing keyRing = (KeyRing) o;
if (signatureKeyPair != null ? !signatureKeyPair.equals(keyRing.signatureKeyPair) : keyRing.signatureKeyPair != null)
return false;
if (encryptionKeyPair != null ? !encryptionKeyPair.equals(keyRing.encryptionKeyPair) : keyRing.encryptionKeyPair != null)
return false;
return !(pubKeyRing != null ? !pubKeyRing.equals(keyRing.pubKeyRing) : keyRing.pubKeyRing != null);
}
@Override
public int hashCode() {
int result = signatureKeyPair != null ? signatureKeyPair.hashCode() : 0;
result = 31 * result + (encryptionKeyPair != null ? encryptionKeyPair.hashCode() : 0);
result = 31 * result + (pubKeyRing != null ? pubKeyRing.hashCode() : 0);
return result;
}
@Override
public String toString() {
return "KeyRing{" +
"signatureKeyPair.hashCode()=" + signatureKeyPair.hashCode() +
", encryptionKeyPair.hashCode()=" + encryptionKeyPair.hashCode() +
", pubKeyRing.hashCode()=" + pubKeyRing.hashCode() +
'}';
}
}

View File

@ -34,6 +34,7 @@ import java.security.interfaces.DSAPrivateKey;
import java.security.interfaces.RSAPrivateCrtKey;
import java.security.spec.*;
// TODO: use a password protection for storage?
public class KeyStorage {
private static final Logger log = LoggerFactory.getLogger(KeyStorage.class);
@ -41,7 +42,7 @@ public class KeyStorage {
public enum KeyEntry {
MSG_SIGNATURE("sig", Sig.KEY_ALGO),
MSG_ENCRYPTION("enc", Encryption.ENCR_KEY_ALGO);
MSG_ENCRYPTION("enc", Encryption.ASYM_KEY_ALGO);
private final String fileName;
private final String algorithm;
@ -87,7 +88,7 @@ public class KeyStorage {
public KeyPair loadKeyPair(KeyEntry keyEntry) {
// long now = System.currentTimeMillis();
try {
KeyFactory keyFactory = KeyFactory.getInstance(keyEntry.getAlgorithm());
KeyFactory keyFactory = KeyFactory.getInstance(keyEntry.getAlgorithm(), "BC");
PublicKey publicKey;
PrivateKey privateKey;
@ -123,7 +124,7 @@ public class KeyStorage {
//log.info("load completed in {} msec", System.currentTimeMillis() - now);
return new KeyPair(publicKey, privateKey);
} catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
} catch (NoSuchAlgorithmException | InvalidKeySpecException | NoSuchProviderException e) {
e.printStackTrace();
log.error(e.getMessage());
throw new RuntimeException("Could not load key " + keyEntry.toString(), e);

View File

@ -26,13 +26,14 @@ import java.io.ObjectInputStream;
import java.io.Serializable;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
/**
* Same as KeyRing but with public keys only.
* Used to sent over the wire to other peer.
* Used to send public keys over the wire to other peer.
*/
public class PubKeyRing implements Serializable {
// That object is sent over the wire, so we need to take care of version compatibility.
@ -57,9 +58,9 @@ public class PubKeyRing implements Serializable {
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
try {
in.defaultReadObject();
signaturePubKey = KeyFactory.getInstance(Sig.KEY_ALGO).generatePublic(new X509EncodedKeySpec(signaturePubKeyBytes));
encryptionPubKey = KeyFactory.getInstance(Encryption.ENCR_KEY_ALGO).generatePublic(new X509EncodedKeySpec(encryptionPubKeyBytes));
} catch (InvalidKeySpecException | NoSuchAlgorithmException e) {
signaturePubKey = KeyFactory.getInstance(Sig.KEY_ALGO, "BC").generatePublic(new X509EncodedKeySpec(signaturePubKeyBytes));
encryptionPubKey = KeyFactory.getInstance(Encryption.ASYM_KEY_ALGO, "BC").generatePublic(new X509EncodedKeySpec(encryptionPubKeyBytes));
} catch (InvalidKeySpecException | NoSuchAlgorithmException | NoSuchProviderException e) {
e.printStackTrace();
log.error(e.getMessage());
} catch (Throwable t) {
@ -98,8 +99,8 @@ public class PubKeyRing implements Serializable {
@Override
public String toString() {
return "PubKeyRing{" +
"\n\nmsgSignaturePubKey=\n" + Util.pubKeyToString(getSignaturePubKey()) +
"\n\nmsgEncryptionPubKey=\n" + Util.pubKeyToString(getEncryptionPubKey()) +
"\n\nsignaturePubKey=\n" + Util.pubKeyToString(getSignaturePubKey()) +
"\n\nencryptionPubKey=\n" + Util.pubKeyToString(getEncryptionPubKey()) +
'}';
}

View File

@ -23,11 +23,6 @@ import java.io.Serializable;
import java.security.PublicKey;
import java.util.Arrays;
/**
* Packs the encrypted symmetric secretKey and the encrypted and signed message into one object.
* SecretKey is encrypted with asymmetric pubKey of peer. Signed message is encrypted with secretKey.
* Using that hybrid encryption model we are not restricted by data size and performance as symmetric encryption is very fast.
*/
public final class SealedAndSigned implements Serializable {
// That object is sent over the wire, so we need to take care of version compatibility.
private static final long serialVersionUID = Version.NETWORK_PROTOCOL_VERSION;

View File

@ -36,7 +36,7 @@ public class Sig {
private static final Logger log = LoggerFactory.getLogger(Sig.class);
public static final String KEY_ALGO = "DSA";
public static final String ALGO = "SHA1withDSA"; //TODO better SHA512withECDSA
public static final String ALGO = "SHA256withDSA";
/**
@ -45,12 +45,12 @@ public class Sig {
public static KeyPair generateKeyPair() {
long ts = System.currentTimeMillis();
try {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGO);
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGO, "BC");
keyPairGenerator.initialize(1024);
KeyPair keyPair = keyPairGenerator.genKeyPair();
log.trace("Generate msgSignatureKeyPair needed {} ms", System.currentTimeMillis() - ts);
return keyPair;
} catch (NoSuchAlgorithmException e) {
} catch (NoSuchAlgorithmException | NoSuchProviderException e) {
e.printStackTrace();
throw new RuntimeException("Could not create key.");
}
@ -65,12 +65,15 @@ public class Sig {
* @throws NoSuchAlgorithmException
* @throws InvalidKeyException
*/
public static byte[] sign(PrivateKey privateKey, byte[] data)
throws SignatureException, NoSuchAlgorithmException, InvalidKeyException {
Signature sig = Signature.getInstance(ALGO);
sig.initSign(privateKey);
sig.update(data);
return sig.sign();
public static byte[] sign(PrivateKey privateKey, byte[] data) throws CryptoException {
try {
Signature sig = Signature.getInstance(ALGO, "BC");
sig.initSign(privateKey);
sig.update(data);
return sig.sign();
} catch (SignatureException | NoSuchProviderException | InvalidKeyException | NoSuchAlgorithmException e) {
throw new CryptoException("Signing failed. " + e.getMessage());
}
}
/**
@ -81,8 +84,7 @@ public class Sig {
* @throws NoSuchAlgorithmException
* @throws InvalidKeyException
*/
public static String sign(PrivateKey privateKey, String message)
throws SignatureException, NoSuchAlgorithmException, InvalidKeyException {
public static String sign(PrivateKey privateKey, String message) throws CryptoException {
byte[] sigAsBytes = sign(privateKey, message.getBytes(Charsets.UTF_8));
return Base64.toBase64String(sigAsBytes);
}
@ -96,12 +98,16 @@ public class Sig {
* @throws InvalidKeyException
* @throws SignatureException
*/
public static boolean verify(PublicKey publicKey, byte[] data, byte[] signature)
throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
Signature sig = Signature.getInstance(ALGO);
sig.initVerify(publicKey);
sig.update(data);
return sig.verify(signature);
public static boolean verify(PublicKey publicKey, byte[] data, byte[] signature) throws CryptoException {
byte[] sigAsBytes = new byte[0];
try {
Signature sig = Signature.getInstance(ALGO, "BC");
sig.initVerify(publicKey);
sig.update(data);
return sig.verify(signature);
} catch (SignatureException | NoSuchProviderException | InvalidKeyException | NoSuchAlgorithmException e) {
throw new CryptoException("Signature verification failed. " + e.getMessage());
}
}
/**
@ -113,8 +119,7 @@ public class Sig {
* @throws InvalidKeyException
* @throws SignatureException
*/
public static boolean verify(PublicKey publicKey, String message, String signature)
throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
public static boolean verify(PublicKey publicKey, String message, String signature) throws CryptoException {
return verify(publicKey, message.getBytes(Charsets.UTF_8), Base64.decode(signature));
}
}

View File

@ -17,18 +17,14 @@
package io.bitsquare.common.crypto;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
public class Util {
private static final Logger log = LoggerFactory.getLogger(Util.class);
public static String pubKeyToString(PublicKey publicKey) {
final X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(publicKey.getEncoded());
return java.util.Base64.getEncoder().encodeToString(x509EncodedKeySpec.getEncoded());
return Base64.getEncoder().encodeToString(x509EncodedKeySpec.getEncoded());
}
}

View File

@ -30,7 +30,7 @@ import io.bitsquare.p2p.Address;
import io.bitsquare.p2p.Message;
import io.bitsquare.p2p.P2PService;
import io.bitsquare.p2p.P2PServiceListener;
import io.bitsquare.p2p.messaging.DecryptedMessageWithPubKey;
import io.bitsquare.p2p.messaging.DecryptedMsgWithPubKey;
import io.bitsquare.p2p.messaging.SendMailboxMessageListener;
import io.bitsquare.storage.Storage;
import io.bitsquare.trade.Contract;
@ -68,8 +68,8 @@ public class DisputeManager {
transient private final ObservableList<Dispute> disputesObservableList;
private final String disputeInfo;
private final P2PServiceListener p2PServiceListener;
private final List<DecryptedMessageWithPubKey> decryptedMailboxMessageWithPubKeys = new CopyOnWriteArrayList<>();
private final List<DecryptedMessageWithPubKey> decryptedMailMessageWithPubKeys = new CopyOnWriteArrayList<>();
private final List<DecryptedMsgWithPubKey> decryptedMailboxMessageWithPubKeys = new CopyOnWriteArrayList<>();
private final List<DecryptedMsgWithPubKey> decryptedMailMessageWithPubKeys = new CopyOnWriteArrayList<>();
///////////////////////////////////////////////////////////////////////////////////////////

View File

@ -8,25 +8,25 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.spongycastle.crypto.params.KeyParameter;
//TODO
//TODO: Borrowed form BitcoinJ/Lighthouse. Remove Protos dependency, check complete code logic.
public class ScryptUtil {
private static final Logger log = LoggerFactory.getLogger(ScryptUtil.class);
public ScryptUtil() {
}
public static final Protos.ScryptParameters SCRYPT_PARAMETERS = Protos.ScryptParameters.newBuilder()
.setP(6)
.setR(8)
.setN(32768)
.setSalt(ByteString.copyFrom(KeyCrypterScrypt.randomSalt()))
.build();
public interface ScryptKeyDerivationResultHandler {
public interface DeriveKeyResultHandler {
void handleResult(KeyParameter aesKey);
}
public static void deriveKeyWithScrypt(KeyCrypterScrypt keyCrypterScrypt, String password, ScryptKeyDerivationResultHandler resultHandler) {
public static KeyCrypterScrypt getKeyCrypterScrypt() {
Protos.ScryptParameters scryptParameters = Protos.ScryptParameters.newBuilder()
.setP(6)
.setR(8)
.setN(32768)
.setSalt(ByteString.copyFrom(KeyCrypterScrypt.randomSalt()))
.build();
return new KeyCrypterScrypt(scryptParameters);
}
public static void deriveKeyWithScrypt(KeyCrypterScrypt keyCrypterScrypt, String password, DeriveKeyResultHandler resultHandler) {
new Thread(() -> {
log.info("Doing key derivation");

View File

@ -30,7 +30,7 @@ import io.bitsquare.common.crypto.KeyRing;
import io.bitsquare.common.taskrunner.Model;
import io.bitsquare.p2p.Address;
import io.bitsquare.p2p.P2PService;
import io.bitsquare.p2p.messaging.DecryptedMessageWithPubKey;
import io.bitsquare.p2p.messaging.DecryptedMsgWithPubKey;
import io.bitsquare.storage.Storage;
import io.bitsquare.trade.offer.Offer;
import io.bitsquare.trade.offer.OpenOfferManager;
@ -149,7 +149,7 @@ abstract public class Trade implements Tradable, Model, Serializable {
private final ProcessModel processModel;
// Mutable
private DecryptedMessageWithPubKey decryptedMessageWithPubKey;
private DecryptedMsgWithPubKey decryptedMsgWithPubKey;
private Date takeOfferDate = new Date(0); // in some error cases the date is not set and cause null pointers, so we set a default
protected State state;
@ -236,8 +236,8 @@ abstract public class Trade implements Tradable, Model, Serializable {
tradeProtocol.checkPayoutTxTimeLock(this);
if (decryptedMessageWithPubKey != null) {
tradeProtocol.applyMailboxMessage(decryptedMessageWithPubKey, this);
if (decryptedMsgWithPubKey != null) {
tradeProtocol.applyMailboxMessage(decryptedMsgWithPubKey, this);
}
}
@ -280,13 +280,13 @@ abstract public class Trade implements Tradable, Model, Serializable {
return depositTx;
}
public void setMailboxMessage(DecryptedMessageWithPubKey decryptedMessageWithPubKey) {
log.trace("setMailboxMessage " + decryptedMessageWithPubKey);
this.decryptedMessageWithPubKey = decryptedMessageWithPubKey;
public void setMailboxMessage(DecryptedMsgWithPubKey decryptedMsgWithPubKey) {
log.trace("setMailboxMessage " + decryptedMsgWithPubKey);
this.decryptedMsgWithPubKey = decryptedMsgWithPubKey;
}
public DecryptedMessageWithPubKey getMailboxMessage() {
return decryptedMessageWithPubKey;
public DecryptedMsgWithPubKey getMailboxMessage() {
return decryptedMsgWithPubKey;
}
public void setStorage(Storage<? extends TradableList> storage) {
@ -618,7 +618,7 @@ abstract public class Trade implements Tradable, Model, Serializable {
", date=" + takeOfferDate +
", processModel=" + processModel +
", processState=" + state +
", messageWithPubKey=" + decryptedMessageWithPubKey +
", messageWithPubKey=" + decryptedMsgWithPubKey +
", depositTx=" + depositTx +
/* ", contract=" + contract +
", contractAsJson='" + contractAsJson + '\'' +*/

View File

@ -31,7 +31,7 @@ import io.bitsquare.p2p.P2PService;
import io.bitsquare.p2p.P2PServiceListener;
import io.bitsquare.p2p.messaging.DecryptedMailListener;
import io.bitsquare.p2p.messaging.DecryptedMailboxListener;
import io.bitsquare.p2p.messaging.DecryptedMessageWithPubKey;
import io.bitsquare.p2p.messaging.DecryptedMsgWithPubKey;
import io.bitsquare.storage.Storage;
import io.bitsquare.trade.closed.ClosedTradableManager;
import io.bitsquare.trade.failed.FailedTradesManager;
@ -114,8 +114,8 @@ public class TradeManager {
p2PService.addDecryptedMailListener(new DecryptedMailListener() {
@Override
public void onMailMessage(DecryptedMessageWithPubKey decryptedMessageWithPubKey, Address peerAddress) {
Message message = decryptedMessageWithPubKey.message;
public void onMailMessage(DecryptedMsgWithPubKey decryptedMsgWithPubKey, Address peerAddress) {
Message message = decryptedMsgWithPubKey.message;
// Handler for incoming initial messages from taker
if (message instanceof PayDepositRequest) {
@ -126,10 +126,10 @@ public class TradeManager {
});
p2PService.addDecryptedMailboxListener(new DecryptedMailboxListener() {
@Override
public void onMailboxMessageAdded(DecryptedMessageWithPubKey decryptedMessageWithPubKey, Address senderAddress) {
log.trace("onMailboxMessageAdded decryptedMessageWithPubKey: " + decryptedMessageWithPubKey);
public void onMailboxMessageAdded(DecryptedMsgWithPubKey decryptedMsgWithPubKey, Address senderAddress) {
log.trace("onMailboxMessageAdded decryptedMessageWithPubKey: " + decryptedMsgWithPubKey);
log.trace("onMailboxMessageAdded senderAddress: " + senderAddress);
Message message = decryptedMessageWithPubKey.message;
Message message = decryptedMsgWithPubKey.message;
if (message instanceof PayDepositRequest) {
//TODO is that used????
PayDepositRequest payDepositRequest = (PayDepositRequest) message;
@ -143,7 +143,7 @@ public class TradeManager {
String tradeId = ((TradeMessage) message).tradeId;
Optional<Trade> tradeOptional = trades.stream().filter(e -> e.getId().equals(tradeId)).findAny();
if (tradeOptional.isPresent())
tradeOptional.get().setMailboxMessage(decryptedMessageWithPubKey);
tradeOptional.get().setMailboxMessage(decryptedMsgWithPubKey);
}
}
});
@ -203,7 +203,7 @@ public class TradeManager {
initTrade(trade);
// after we are authenticated we remove mailbox messages.
DecryptedMessageWithPubKey mailboxMessage = trade.getMailboxMessage();
DecryptedMsgWithPubKey mailboxMessage = trade.getMailboxMessage();
if (mailboxMessage != null) {
p2PService.removeEntryFromMailbox(mailboxMessage);
trade.setMailboxMessage(null);

View File

@ -22,7 +22,7 @@ import io.bitsquare.common.crypto.PubKeyRing;
import io.bitsquare.p2p.Address;
import io.bitsquare.p2p.Message;
import io.bitsquare.p2p.messaging.DecryptedMailListener;
import io.bitsquare.p2p.messaging.DecryptedMessageWithPubKey;
import io.bitsquare.p2p.messaging.DecryptedMsgWithPubKey;
import io.bitsquare.trade.OffererTrade;
import io.bitsquare.trade.TakerTrade;
import io.bitsquare.trade.Trade;
@ -94,10 +94,10 @@ public abstract class TradeProtocol {
}
public void applyMailboxMessage(DecryptedMessageWithPubKey decryptedMessageWithPubKey, Trade trade) {
log.debug("applyMailboxMessage " + decryptedMessageWithPubKey.message);
if (decryptedMessageWithPubKey.signaturePubKey.equals(processModel.tradingPeer.getPubKeyRing().getSignaturePubKey()))
doApplyMailboxMessage(decryptedMessageWithPubKey.message, trade);
public void applyMailboxMessage(DecryptedMsgWithPubKey decryptedMsgWithPubKey, Trade trade) {
log.debug("applyMailboxMessage " + decryptedMsgWithPubKey.message);
if (decryptedMsgWithPubKey.signaturePubKey.equals(processModel.tradingPeer.getPubKeyRing().getSignaturePubKey()))
doApplyMailboxMessage(decryptedMsgWithPubKey.message, trade);
else
log.error("SignaturePubKey in message does not match the SignaturePubKey we have stored to that trading peer.");
}

View File

@ -103,7 +103,8 @@ public class PasswordView extends ActivatableView<GridPane, Void> {
if (wallet.isEncrypted())
keyCrypterScrypt = (KeyCrypterScrypt) wallet.getKeyCrypter();
else
keyCrypterScrypt = new KeyCrypterScrypt(ScryptUtil.SCRYPT_PARAMETERS);
keyCrypterScrypt = ScryptUtil.getKeyCrypterScrypt();
ScryptUtil.deriveKeyWithScrypt(keyCrypterScrypt, passwordField.getText(), aesKey -> {
deriveStatusLabel.setText("");

View File

@ -19,7 +19,7 @@ package io.bitsquare.crypto;
import io.bitsquare.common.crypto.*;
import io.bitsquare.p2p.Message;
import io.bitsquare.p2p.messaging.DecryptedMessageWithPubKey;
import io.bitsquare.p2p.messaging.DecryptedMsgWithPubKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -36,22 +36,19 @@ public class EncryptionService {
this.keyRing = keyRing;
}
public SealedAndSigned encryptAndSignMessage(PubKeyRing pubKeyRing, Message message) throws CryptoException {
log.trace("encryptAndSignMessage message = " + message);
public SealedAndSigned encryptAndSign(PubKeyRing pubKeyRing, Message message) throws CryptoException {
KeyPair signatureKeyPair = keyRing.getSignatureKeyPair();
return Encryption.encryptHybridWithSignature(message,
signatureKeyPair.getPrivate(),
signatureKeyPair.getPublic(),
pubKeyRing.getEncryptionPubKey());
return Encryption.encryptHybridWithSignature(message, signatureKeyPair, pubKeyRing.getEncryptionPubKey());
}
public DecryptedMessageWithPubKey decryptAndVerifyMessage(SealedAndSigned sealedAndSigned) throws CryptoException {
DecryptedPayloadWithPubKey decryptedPayloadWithPubKey = Encryption.decryptHybridWithSignature(sealedAndSigned, keyRing.getEncryptionKeyPair().getPrivate());
public DecryptedMsgWithPubKey decryptAndVerify(SealedAndSigned sealedAndSigned) throws CryptoException {
DecryptedPayloadWithPubKey decryptedPayloadWithPubKey = Encryption.decryptHybridWithSignature(sealedAndSigned,
keyRing.getEncryptionKeyPair().getPrivate());
if (decryptedPayloadWithPubKey.payload instanceof Message) {
//log.trace("Decryption needed {} ms", System.currentTimeMillis() - ts);
return new DecryptedMessageWithPubKey((Message) decryptedPayloadWithPubKey.payload, decryptedPayloadWithPubKey.sigPublicKey);
return new DecryptedMsgWithPubKey((Message) decryptedPayloadWithPubKey.payload,
decryptedPayloadWithPubKey.sigPublicKey);
} else {
throw new CryptoException("messageObject is not instance of Message");
throw new CryptoException("decryptedPayloadWithPubKey.payload is not instance of Message");
}
}
}

View File

@ -3,11 +3,8 @@ package io.bitsquare.crypto;
import io.bitsquare.common.crypto.SealedAndSigned;
import io.bitsquare.p2p.Address;
import io.bitsquare.p2p.messaging.MailboxMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SealedAndSignedMessage implements MailboxMessage {
private static final Logger log = LoggerFactory.getLogger(SealedAndSignedMessage.class);
public final SealedAndSigned sealedAndSigned;
public final Address peerAddress;

View File

@ -33,10 +33,7 @@ import org.slf4j.LoggerFactory;
import java.io.File;
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.SignatureException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
@ -62,7 +59,7 @@ public class P2PService {
private final List<DecryptedMailListener> decryptedMailListeners = new CopyOnWriteArrayList<>();
private final List<DecryptedMailboxListener> decryptedMailboxListeners = new CopyOnWriteArrayList<>();
private final List<P2PServiceListener> p2pServiceListeners = new CopyOnWriteArrayList<>();
private final Map<DecryptedMessageWithPubKey, ProtectedMailboxData> mailboxMap = new ConcurrentHashMap<>();
private final Map<DecryptedMsgWithPubKey, ProtectedMailboxData> mailboxMap = new ConcurrentHashMap<>();
private volatile boolean shutDownInProgress;
private List<Address> seedNodeAddresses;
private List<Address> connectedSeedNodes = new CopyOnWriteArrayList<>();
@ -205,18 +202,18 @@ public class P2PService {
HashSet<ProtectedData> set = ((DataSetMessage) message).set;
set.stream().forEach(e -> dataStorage.add(e, connection.getPeerAddress()));
// TODO done in addHashSetChangedListener
// set.stream().filter(e -> e instanceof ProtectedMailboxData).forEach(e -> tryDecryptMailboxData((ProtectedMailboxData) e));
dataReceived();
} else if (message instanceof SealedAndSignedMessage) {
if (encryptionService != null) {
try {
SealedAndSignedMessage sealedAndSignedMessage = (SealedAndSignedMessage) message;
DecryptedMessageWithPubKey decryptedMessageWithPubKey = encryptionService.decryptAndVerifyMessage(sealedAndSignedMessage.sealedAndSigned);
UserThread.execute(() -> decryptedMailListeners.stream().forEach(e -> e.onMailMessage(decryptedMessageWithPubKey, connection.getPeerAddress())));
DecryptedMsgWithPubKey decryptedMsgWithPubKey = encryptionService.decryptAndVerify(
sealedAndSignedMessage.sealedAndSigned);
UserThread.execute(() -> decryptedMailListeners.stream().forEach(
e -> e.onMailMessage(decryptedMsgWithPubKey, connection.getPeerAddress())));
} catch (CryptoException e) {
log.info("Decryption of SealedAndSignedMessage failed. That is expected if the message is not intended for us.");
log.info("Decryption of SealedAndSignedMessage failed. " +
"That is expected if the message is not intended for us.");
}
}
}
@ -313,14 +310,14 @@ public class P2PService {
return authenticated;
}
public void removeEntryFromMailbox(DecryptedMessageWithPubKey decryptedMessageWithPubKey) {
public void removeEntryFromMailbox(DecryptedMsgWithPubKey decryptedMsgWithPubKey) {
log.trace("removeEntryFromMailbox");
ProtectedMailboxData mailboxData = mailboxMap.get(decryptedMessageWithPubKey);
ProtectedMailboxData mailboxData = mailboxMap.get(decryptedMsgWithPubKey);
if (mailboxData != null && mailboxData.expirablePayload instanceof ExpirableMailboxPayload) {
checkArgument(mailboxData.receiversPubKey.equals(keyRing.getSignatureKeyPair().getPublic()),
"mailboxData.receiversPubKey is not matching with our key. That must not happen.");
removeMailboxData((ExpirableMailboxPayload) mailboxData.expirablePayload, mailboxData.receiversPubKey);
mailboxMap.remove(decryptedMessageWithPubKey);
mailboxMap.remove(decryptedMsgWithPubKey);
log.trace("Removed successfully protectedExpirableData.");
}
}
@ -329,7 +326,8 @@ public class P2PService {
// Messaging
///////////////////////////////////////////////////////////////////////////////////////////
public void sendEncryptedMailMessage(Address peerAddress, PubKeyRing pubKeyRing, MailMessage message, SendMailMessageListener sendMailMessageListener) {
public void sendEncryptedMailMessage(Address peerAddress, PubKeyRing pubKeyRing, MailMessage message,
SendMailMessageListener sendMailMessageListener) {
checkNotNull(peerAddress, "PeerAddress must not be null (sendEncryptedMailMessage)");
if (!authenticatedToFirstPeer)
@ -343,10 +341,12 @@ public class P2PService {
doSendEncryptedMailMessage(peerAddress, pubKeyRing, message, sendMailMessageListener);
}
private void doSendEncryptedMailMessage(Address peerAddress, PubKeyRing pubKeyRing, MailMessage message, SendMailMessageListener sendMailMessageListener) {
private void doSendEncryptedMailMessage(Address peerAddress, PubKeyRing pubKeyRing, MailMessage message,
SendMailMessageListener sendMailMessageListener) {
if (encryptionService != null) {
try {
SealedAndSignedMessage sealedAndSignedMessage = new SealedAndSignedMessage(encryptionService.encryptAndSignMessage(pubKeyRing, message), peerAddress);
SealedAndSignedMessage sealedAndSignedMessage = new SealedAndSignedMessage(
encryptionService.encryptAndSign(pubKeyRing, message), peerAddress);
SettableFuture<Connection> future = sendMessage(peerAddress, sealedAndSignedMessage);
Futures.addCallback(future, new FutureCallback<Connection>() {
@Override
@ -367,7 +367,8 @@ public class P2PService {
}
}
public void sendEncryptedMailboxMessage(Address peerAddress, PubKeyRing peersPubKeyRing, MailboxMessage message, SendMailboxMessageListener sendMailboxMessageListener) {
public void sendEncryptedMailboxMessage(Address peerAddress, PubKeyRing peersPubKeyRing,
MailboxMessage message, SendMailboxMessageListener sendMailboxMessageListener) {
checkNotNull(peerAddress, "PeerAddress must not be null (sendEncryptedMailboxMessage)");
checkArgument(!keyRing.getPubKeyRing().equals(peersPubKeyRing), "We got own keyring instead of that from peer");
@ -386,10 +387,12 @@ public class P2PService {
}
}
private void trySendEncryptedMailboxMessage(Address peerAddress, PubKeyRing peersPubKeyRing, MailboxMessage message, SendMailboxMessageListener sendMailboxMessageListener) {
private void trySendEncryptedMailboxMessage(Address peerAddress, PubKeyRing peersPubKeyRing,
MailboxMessage message, SendMailboxMessageListener sendMailboxMessageListener) {
if (encryptionService != null) {
try {
SealedAndSignedMessage sealedAndSignedMessage = new SealedAndSignedMessage(encryptionService.encryptAndSignMessage(peersPubKeyRing, message), peerAddress);
SealedAndSignedMessage sealedAndSignedMessage = new SealedAndSignedMessage(
encryptionService.encryptAndSign(peersPubKeyRing, message), peerAddress);
SettableFuture<Connection> future = sendMessage(peerAddress, sealedAndSignedMessage);
Futures.addCallback(future, new FutureCallback<Connection>() {
@Override
@ -430,8 +433,9 @@ public class P2PService {
throw new AuthenticationException("You must be authenticated before adding data to the P2P network.");
try {
return dataStorage.add(dataStorage.getDataWithSignedSeqNr(expirablePayload, keyRing.getSignatureKeyPair()), networkNode.getAddress());
} catch (NoSuchAlgorithmException | SignatureException | InvalidKeyException e) {
return dataStorage.add(dataStorage.getDataWithSignedSeqNr(expirablePayload,
keyRing.getSignatureKeyPair()), networkNode.getAddress());
} catch (CryptoException e) {
log.error("Signing at getDataWithSignedSeqNr failed. That should never happen.");
return false;
}
@ -442,8 +446,9 @@ public class P2PService {
throw new AuthenticationException("You must be authenticated before adding data to the P2P network.");
try {
return dataStorage.add(dataStorage.getMailboxDataWithSignedSeqNr(expirableMailboxPayload, keyRing.getSignatureKeyPair(), receiversPublicKey), networkNode.getAddress());
} catch (NoSuchAlgorithmException | SignatureException | InvalidKeyException e) {
return dataStorage.add(dataStorage.getMailboxDataWithSignedSeqNr(expirableMailboxPayload,
keyRing.getSignatureKeyPair(), receiversPublicKey), networkNode.getAddress());
} catch (CryptoException e) {
log.error("Signing at getDataWithSignedSeqNr failed. That should never happen.");
return false;
}
@ -453,8 +458,9 @@ public class P2PService {
if (!authenticatedToFirstPeer)
throw new AuthenticationException("You must be authenticated before removing data from the P2P network.");
try {
return dataStorage.remove(dataStorage.getDataWithSignedSeqNr(expirablePayload, keyRing.getSignatureKeyPair()), networkNode.getAddress());
} catch (NoSuchAlgorithmException | SignatureException | InvalidKeyException e) {
return dataStorage.remove(dataStorage.getDataWithSignedSeqNr(expirablePayload,
keyRing.getSignatureKeyPair()), networkNode.getAddress());
} catch (CryptoException e) {
log.error("Signing at getDataWithSignedSeqNr failed. That should never happen.");
return false;
}
@ -464,8 +470,9 @@ public class P2PService {
if (!authenticatedToFirstPeer)
throw new AuthenticationException("You must be authenticated before removing data from the P2P network.");
try {
return dataStorage.removeMailboxData(dataStorage.getMailboxDataWithSignedSeqNr(expirableMailboxPayload, keyRing.getSignatureKeyPair(), receiversPublicKey), networkNode.getAddress());
} catch (NoSuchAlgorithmException | SignatureException | InvalidKeyException e) {
return dataStorage.removeMailboxData(dataStorage.getMailboxDataWithSignedSeqNr(expirableMailboxPayload,
keyRing.getSignatureKeyPair(), receiversPublicKey), networkNode.getAddress());
} catch (CryptoException e) {
log.error("Signing at getDataWithSignedSeqNr failed. That should never happen.");
return false;
}
@ -635,21 +642,26 @@ public class P2PService {
ExpirableMailboxPayload mailboxEntry = (ExpirableMailboxPayload) data;
SealedAndSigned sealedAndSigned = mailboxEntry.sealedAndSignedMessage.sealedAndSigned;
try {
DecryptedMessageWithPubKey decryptedMessageWithPubKey = encryptionService.decryptAndVerifyMessage(sealedAndSigned);
if (decryptedMessageWithPubKey.message instanceof MailboxMessage) {
MailboxMessage mailboxMessage = (MailboxMessage) decryptedMessageWithPubKey.message;
DecryptedMsgWithPubKey decryptedMsgWithPubKey = encryptionService.decryptAndVerify(sealedAndSigned);
if (decryptedMsgWithPubKey.message instanceof MailboxMessage) {
MailboxMessage mailboxMessage = (MailboxMessage) decryptedMsgWithPubKey.message;
Address senderAddress = mailboxMessage.getSenderAddress();
checkNotNull(senderAddress, "senderAddress must not be null for mailbox messages");
log.trace("mailboxData.publicKey " + mailboxData.ownerStoragePubKey.hashCode());
log.trace("keyRing.getStorageSignatureKeyPair().getPublic() " + keyRing.getSignatureKeyPair().getPublic().hashCode());
log.trace("keyRing.getMsgSignatureKeyPair().getPublic() " + keyRing.getSignatureKeyPair().getPublic().hashCode());
log.trace("keyRing.getMsgEncryptionKeyPair().getPublic() " + keyRing.getEncryptionKeyPair().getPublic().hashCode());
log.trace("keyRing.getStorageSignatureKeyPair().getPublic() "
+ keyRing.getSignatureKeyPair().getPublic().hashCode());
log.trace("keyRing.getMsgSignatureKeyPair().getPublic() "
+ keyRing.getSignatureKeyPair().getPublic().hashCode());
log.trace("keyRing.getMsgEncryptionKeyPair().getPublic() "
+ keyRing.getEncryptionKeyPair().getPublic().hashCode());
mailboxMap.put(decryptedMessageWithPubKey, mailboxData);
log.trace("Decryption of SealedAndSignedMessage succeeded. senderAddress=" + senderAddress + " / my address=" + getAddress());
UserThread.execute(() -> decryptedMailboxListeners.stream().forEach(e -> e.onMailboxMessageAdded(decryptedMessageWithPubKey, senderAddress)));
mailboxMap.put(decryptedMsgWithPubKey, mailboxData);
log.trace("Decryption of SealedAndSignedMessage succeeded. senderAddress="
+ senderAddress + " / my address=" + getAddress());
UserThread.execute(() -> decryptedMailboxListeners.stream().forEach(
e -> e.onMailboxMessageAdded(decryptedMsgWithPubKey, senderAddress)));
}
} catch (CryptoException e) {
log.trace("Decryption of SealedAndSignedMessage failed. That is expected if the message is not intended for us.");

View File

@ -4,5 +4,5 @@ import io.bitsquare.p2p.Address;
public interface DecryptedMailListener {
void onMailMessage(DecryptedMessageWithPubKey decryptedMessageWithPubKey, Address peerAddress);
void onMailMessage(DecryptedMsgWithPubKey decryptedMsgWithPubKey, Address peerAddress);
}

View File

@ -4,5 +4,5 @@ import io.bitsquare.p2p.Address;
public interface DecryptedMailboxListener {
void onMailboxMessageAdded(DecryptedMessageWithPubKey decryptedMessageWithPubKey, Address senderAddress);
void onMailboxMessageAdded(DecryptedMsgWithPubKey decryptedMsgWithPubKey, Address senderAddress);
}

View File

@ -22,14 +22,14 @@ import io.bitsquare.p2p.Message;
import java.security.PublicKey;
public final class DecryptedMessageWithPubKey implements MailMessage {
public final class DecryptedMsgWithPubKey implements MailMessage {
// That object is sent over the wire, so we need to take care of version compatibility.
private static final long serialVersionUID = Version.NETWORK_PROTOCOL_VERSION;
public final Message message;
public final PublicKey signaturePubKey;
public DecryptedMessageWithPubKey(Message message, PublicKey signaturePubKey) {
public DecryptedMsgWithPubKey(Message message, PublicKey signaturePubKey) {
this.message = message;
this.signaturePubKey = signaturePubKey;
}
@ -37,9 +37,9 @@ public final class DecryptedMessageWithPubKey implements MailMessage {
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof DecryptedMessageWithPubKey)) return false;
if (!(o instanceof DecryptedMsgWithPubKey)) return false;
DecryptedMessageWithPubKey that = (DecryptedMessageWithPubKey) o;
DecryptedMsgWithPubKey that = (DecryptedMsgWithPubKey) o;
if (message != null ? !message.equals(that.message) : that.message != null) return false;
return !(signaturePubKey != null ? !signaturePubKey.equals(that.signaturePubKey) : that.signaturePubKey != null);

View File

@ -2,6 +2,7 @@ package io.bitsquare.p2p.storage;
import com.google.common.annotations.VisibleForTesting;
import io.bitsquare.common.UserThread;
import io.bitsquare.common.crypto.CryptoException;
import io.bitsquare.common.crypto.Hash;
import io.bitsquare.common.crypto.Sig;
import io.bitsquare.p2p.Address;
@ -16,7 +17,8 @@ import org.slf4j.LoggerFactory;
import java.io.File;
import java.math.BigInteger;
import java.security.*;
import java.security.KeyPair;
import java.security.PublicKey;
import java.util.List;
import java.util.Map;
import java.util.Timer;
@ -185,7 +187,8 @@ public class ProtectedExpirableDataStorage {
return map;
}
public ProtectedData getDataWithSignedSeqNr(ExpirablePayload payload, KeyPair ownerStoragePubKey) throws NoSuchAlgorithmException, SignatureException, InvalidKeyException {
public ProtectedData getDataWithSignedSeqNr(ExpirablePayload payload, KeyPair ownerStoragePubKey)
throws CryptoException {
BigInteger hashOfData = getHashAsBigInteger(payload);
int sequenceNumber;
if (sequenceNumberMap.containsKey(hashOfData))
@ -198,8 +201,9 @@ public class ProtectedExpirableDataStorage {
return new ProtectedData(payload, payload.getTTL(), ownerStoragePubKey.getPublic(), sequenceNumber, signature);
}
public ProtectedMailboxData getMailboxDataWithSignedSeqNr(ExpirableMailboxPayload expirableMailboxPayload, KeyPair storageSignaturePubKey, PublicKey receiversPublicKey)
throws NoSuchAlgorithmException, SignatureException, InvalidKeyException {
public ProtectedMailboxData getMailboxDataWithSignedSeqNr(ExpirableMailboxPayload expirableMailboxPayload,
KeyPair storageSignaturePubKey, PublicKey receiversPublicKey)
throws CryptoException {
BigInteger hashOfData = getHashAsBigInteger(expirableMailboxPayload);
int sequenceNumber;
if (sequenceNumberMap.containsKey(hashOfData))
@ -209,7 +213,8 @@ public class ProtectedExpirableDataStorage {
byte[] hashOfDataAndSeqNr = Hash.getHash(new DataAndSeqNr(expirableMailboxPayload, sequenceNumber));
byte[] signature = Sig.sign(storageSignaturePubKey.getPrivate(), hashOfDataAndSeqNr);
return new ProtectedMailboxData(expirableMailboxPayload, expirableMailboxPayload.getTTL(), storageSignaturePubKey.getPublic(), sequenceNumber, signature, receiversPublicKey);
return new ProtectedMailboxData(expirableMailboxPayload, expirableMailboxPayload.getTTL(),
storageSignaturePubKey.getPublic(), sequenceNumber, signature, receiversPublicKey);
}
public void addHashMapChangedListener(HashMapChangedListener hashMapChangedListener) {
@ -257,7 +262,7 @@ public class ProtectedExpirableDataStorage {
"That should not happen. Consider it might be an attempt of fraud.");
return result;
} catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException e) {
} catch (CryptoException e) {
log.error("Signature verification failed at checkSignature");
return false;
}

View File

@ -24,7 +24,7 @@ import io.bitsquare.common.crypto.KeyStorage;
import io.bitsquare.common.crypto.PubKeyRing;
import io.bitsquare.common.util.Utilities;
import io.bitsquare.p2p.Address;
import io.bitsquare.p2p.messaging.DecryptedMessageWithPubKey;
import io.bitsquare.p2p.messaging.DecryptedMsgWithPubKey;
import io.bitsquare.p2p.messaging.MailboxMessage;
import org.junit.After;
import org.junit.Before;
@ -69,8 +69,8 @@ public class EncryptionServiceTests {
public void testDecryptAndVerifyMessage() throws CryptoException {
EncryptionService encryptionService = new EncryptionService(keyRing);
TestMessage data = new TestMessage("test");
SealedAndSignedMessage encrypted = new SealedAndSignedMessage(encryptionService.encryptAndSignMessage(pubKeyRing, data), null);
DecryptedMessageWithPubKey decrypted = encryptionService.decryptAndVerifyMessage(encrypted.sealedAndSigned);
SealedAndSignedMessage encrypted = new SealedAndSignedMessage(encryptionService.encryptAndSign(pubKeyRing, data), null);
DecryptedMsgWithPubKey decrypted = encryptionService.decryptAndVerify(encrypted.sealedAndSigned);
assertEquals(data.data, ((TestMessage) decrypted.message).data);
}

View File

@ -3,7 +3,7 @@ package io.bitsquare.p2p;
import io.bitsquare.common.crypto.*;
import io.bitsquare.crypto.EncryptionService;
import io.bitsquare.crypto.SealedAndSignedMessage;
import io.bitsquare.p2p.messaging.DecryptedMessageWithPubKey;
import io.bitsquare.p2p.messaging.DecryptedMsgWithPubKey;
import io.bitsquare.p2p.messaging.MailboxMessage;
import io.bitsquare.p2p.messaging.SendMailboxMessageListener;
import io.bitsquare.p2p.mocks.MockMailboxMessage;
@ -110,7 +110,7 @@ public class P2PServiceTest {
}
@Test
public void testAdversaryAttacks() throws InterruptedException, NoSuchAlgorithmException, CertificateException, KeyStoreException, IOException, CryptoException, SignatureException, InvalidKeyException {
public void testAdversaryAttacks() throws InterruptedException, NoSuchAlgorithmException, CertificateException, KeyStoreException, IOException, CryptoException, SignatureException, InvalidKeyException, NoSuchProviderException {
p2PService3 = TestUtils.getAndAuthenticateP2PService(8003, encryptionService3, keyRing3, useLocalhost, seedNodes);
MockData origData = new MockData("mockData1", keyRing1.getSignatureKeyPair().getPublic());
@ -273,9 +273,9 @@ public class P2PServiceTest {
if (message instanceof SealedAndSignedMessage) {
try {
SealedAndSignedMessage sealedAndSignedMessage = (SealedAndSignedMessage) message;
DecryptedMessageWithPubKey decryptedMessageWithPubKey = encryptionService2.decryptAndVerifyMessage(sealedAndSignedMessage.sealedAndSigned);
Assert.assertEquals(mockMessage, decryptedMessageWithPubKey.message);
Assert.assertEquals(p2PService2.getAddress(), ((MailboxMessage) decryptedMessageWithPubKey.message).getSenderAddress());
DecryptedMsgWithPubKey decryptedMsgWithPubKey = encryptionService2.decryptAndVerify(sealedAndSignedMessage.sealedAndSigned);
Assert.assertEquals(mockMessage, decryptedMsgWithPubKey.message);
Assert.assertEquals(p2PService2.getAddress(), ((MailboxMessage) decryptedMsgWithPubKey.message).getSenderAddress());
latch2.countDown();
} catch (CryptoException e) {
e.printStackTrace();

View File

@ -80,7 +80,7 @@ public class ProtectedDataStorageTest {
}
@Test
public void testAddAndRemove() throws InterruptedException, NoSuchAlgorithmException, CertificateException, KeyStoreException, IOException, CryptoException, SignatureException, InvalidKeyException {
public void testAddAndRemove() throws InterruptedException, NoSuchAlgorithmException, CertificateException, KeyStoreException, IOException, CryptoException, SignatureException, InvalidKeyException, NoSuchProviderException {
ProtectedData data = dataStorage1.getDataWithSignedSeqNr(mockData, storageSignatureKeyPair1);
Assert.assertTrue(dataStorage1.add(data, null));
Assert.assertEquals(1, dataStorage1.getMap().size());
@ -94,7 +94,7 @@ public class ProtectedDataStorageTest {
}
@Test
public void testExpirableData() throws InterruptedException, NoSuchAlgorithmException, CertificateException, KeyStoreException, IOException, CryptoException, SignatureException, InvalidKeyException {
public void testExpirableData() throws InterruptedException, NoSuchAlgorithmException, CertificateException, KeyStoreException, IOException, CryptoException, SignatureException, InvalidKeyException, NoSuchProviderException {
ProtectedExpirableDataStorage.CHECK_TTL_INTERVAL = 10;
// CHECK_TTL_INTERVAL is used in constructor of ProtectedExpirableDataStorage so we recreate it here
dataStorage1 = new ProtectedExpirableDataStorage(routing1, new File("dummy"));
@ -129,7 +129,7 @@ public class ProtectedDataStorageTest {
}
@Test
public void testMultiAddRemoveProtectedData() throws InterruptedException, NoSuchAlgorithmException, CertificateException, KeyStoreException, IOException, CryptoException, SignatureException, InvalidKeyException {
public void testMultiAddRemoveProtectedData() throws InterruptedException, NoSuchAlgorithmException, CertificateException, KeyStoreException, IOException, CryptoException, SignatureException, InvalidKeyException, NoSuchProviderException {
MockData mockData = new MockData("msg1", keyRing1.getSignatureKeyPair().getPublic());
ProtectedData data = dataStorage1.getDataWithSignedSeqNr(mockData, storageSignatureKeyPair1);
Assert.assertTrue(dataStorage1.add(data, null));
@ -192,10 +192,11 @@ public class ProtectedDataStorageTest {
}
@Test
public void testAddAndRemoveMailboxData() throws InterruptedException, NoSuchAlgorithmException, CertificateException, KeyStoreException, IOException, CryptoException, SignatureException, InvalidKeyException {
public void testAddAndRemoveMailboxData() throws InterruptedException, NoSuchAlgorithmException, CertificateException,
KeyStoreException, IOException, CryptoException, SignatureException, InvalidKeyException, NoSuchProviderException {
// sender
MockMessage mockMessage = new MockMessage("MockMessage");
SealedAndSignedMessage sealedAndSignedMessage = new SealedAndSignedMessage(encryptionService1.encryptAndSignMessage(keyRing1.getPubKeyRing(), mockMessage), null);
SealedAndSignedMessage sealedAndSignedMessage = new SealedAndSignedMessage(encryptionService1.encryptAndSign(keyRing1.getPubKeyRing(), mockMessage), null);
ExpirableMailboxPayload expirableMailboxPayload = new ExpirableMailboxPayload(sealedAndSignedMessage,
keyRing1.getSignatureKeyPair().getPublic(),
keyRing2.getSignatureKeyPair().getPublic());

View File

@ -122,7 +122,7 @@
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.52</version>
<version>1.53</version>
</dependency>
<dependency>