mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-04-19 07:15:54 -04:00
Update bouncycastle, cleanup, renamings
This commit is contained in:
parent
07a9c7fd52
commit
3711519e3a
@ -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() +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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() +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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()) +
|
||||
'}';
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<>();
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -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");
|
||||
|
||||
|
@ -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 + '\'' +*/
|
||||
|
@ -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);
|
||||
|
@ -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.");
|
||||
}
|
||||
|
@ -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("");
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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.");
|
||||
|
@ -4,5 +4,5 @@ import io.bitsquare.p2p.Address;
|
||||
|
||||
public interface DecryptedMailListener {
|
||||
|
||||
void onMailMessage(DecryptedMessageWithPubKey decryptedMessageWithPubKey, Address peerAddress);
|
||||
void onMailMessage(DecryptedMsgWithPubKey decryptedMsgWithPubKey, Address peerAddress);
|
||||
}
|
||||
|
@ -4,5 +4,5 @@ import io.bitsquare.p2p.Address;
|
||||
|
||||
public interface DecryptedMailboxListener {
|
||||
|
||||
void onMailboxMessageAdded(DecryptedMessageWithPubKey decryptedMessageWithPubKey, Address senderAddress);
|
||||
void onMailboxMessageAdded(DecryptedMsgWithPubKey decryptedMsgWithPubKey, Address senderAddress);
|
||||
}
|
||||
|
@ -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);
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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());
|
||||
|
Loading…
x
Reference in New Issue
Block a user