mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-06-07 14:42:51 -04:00
Remove pubkey storage, remove duplicate sig keys
This commit is contained in:
parent
4883c90030
commit
07a9c7fd52
13 changed files with 101 additions and 139 deletions
|
@ -39,7 +39,7 @@ public class Encryption {
|
||||||
public static final String ASYM_CIPHER = "RSA"; // TODO test with RSA/ECB/PKCS1Padding
|
public static final String ASYM_CIPHER = "RSA"; // TODO test with RSA/ECB/PKCS1Padding
|
||||||
public static final String HMAC = "HmacSHA256";
|
public static final String HMAC = "HmacSHA256";
|
||||||
|
|
||||||
public static KeyPair generateEncryptionKeyPair() {
|
public static KeyPair generateKeyPair() {
|
||||||
long ts = System.currentTimeMillis();
|
long ts = System.currentTimeMillis();
|
||||||
try {
|
try {
|
||||||
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ENCR_KEY_ALGO);
|
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ENCR_KEY_ALGO);
|
||||||
|
@ -187,7 +187,7 @@ public class Encryption {
|
||||||
return cipher.doFinal(encryptedPayload);
|
return cipher.doFinal(encryptedPayload);
|
||||||
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException
|
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException
|
||||||
| BadPaddingException | IllegalBlockSizeException e) {
|
| BadPaddingException | IllegalBlockSizeException e) {
|
||||||
e.printStackTrace();
|
// errors when trying to decrypt foreign messages are normal
|
||||||
throw new CryptoException(e);
|
throw new CryptoException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,39 +17,28 @@
|
||||||
|
|
||||||
package io.bitsquare.common.crypto;
|
package io.bitsquare.common.crypto;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import java.security.KeyPair;
|
import java.security.KeyPair;
|
||||||
|
|
||||||
public class KeyRing {
|
public class KeyRing {
|
||||||
private static final Logger log = LoggerFactory.getLogger(KeyRing.class);
|
|
||||||
|
|
||||||
// Used for signing messages sent over the wire
|
|
||||||
private final KeyPair signatureKeyPair;
|
private final KeyPair signatureKeyPair;
|
||||||
// Used for encrypting messages sent over the wire (hybrid encryption scheme is used, so it is used only to encrypt a symmetric session key)
|
|
||||||
private final KeyPair encryptionKeyPair;
|
private final KeyPair encryptionKeyPair;
|
||||||
|
|
||||||
private final PubKeyRing pubKeyRing;
|
private final PubKeyRing pubKeyRing;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public KeyRing(KeyStorage keyStorage) {
|
public KeyRing(KeyStorage keyStorage) {
|
||||||
if (keyStorage.allKeyFilesExist()) {
|
if (keyStorage.allKeyFilesExist()) {
|
||||||
signatureKeyPair = keyStorage.loadKeyPair(KeyStorage.Key.MSG_SIGNATURE);
|
signatureKeyPair = keyStorage.loadKeyPair(KeyStorage.KeyEntry.MSG_SIGNATURE);
|
||||||
encryptionKeyPair = keyStorage.loadKeyPair(KeyStorage.Key.MSG_ENCRYPTION);
|
encryptionKeyPair = keyStorage.loadKeyPair(KeyStorage.KeyEntry.MSG_ENCRYPTION);
|
||||||
} else {
|
} else {
|
||||||
// First time we create key pairs
|
// First time we create key pairs
|
||||||
signatureKeyPair = Sig.generateKeyPair();
|
signatureKeyPair = Sig.generateKeyPair();
|
||||||
encryptionKeyPair = Encryption.generateEncryptionKeyPair();
|
encryptionKeyPair = Encryption.generateKeyPair();
|
||||||
keyStorage.saveKeyRing(this);
|
keyStorage.saveKeyRing(this);
|
||||||
}
|
}
|
||||||
pubKeyRing = new PubKeyRing(signatureKeyPair.getPublic(), signatureKeyPair.getPublic(), encryptionKeyPair.getPublic());
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO
|
pubKeyRing = new PubKeyRing(signatureKeyPair.getPublic(), encryptionKeyPair.getPublic());
|
||||||
public KeyPair getStorageSignatureKeyPair() {
|
|
||||||
return signatureKeyPair;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public KeyPair getSignatureKeyPair() {
|
public KeyPair getSignatureKeyPair() {
|
||||||
|
|
|
@ -27,26 +27,26 @@ import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.math.BigInteger;
|
||||||
import java.security.*;
|
import java.security.*;
|
||||||
import java.security.cert.CertificateException;
|
import java.security.interfaces.DSAParams;
|
||||||
import java.security.spec.InvalidKeySpecException;
|
import java.security.interfaces.DSAPrivateKey;
|
||||||
import java.security.spec.PKCS8EncodedKeySpec;
|
import java.security.interfaces.RSAPrivateCrtKey;
|
||||||
import java.security.spec.X509EncodedKeySpec;
|
import java.security.spec.*;
|
||||||
|
|
||||||
public class KeyStorage {
|
public class KeyStorage {
|
||||||
private static final Logger log = LoggerFactory.getLogger(KeyStorage.class);
|
private static final Logger log = LoggerFactory.getLogger(KeyStorage.class);
|
||||||
|
|
||||||
public static final String DIR_KEY = "key.storage.dir";
|
public static final String DIR_KEY = "key.storage.dir";
|
||||||
|
|
||||||
public enum Key {
|
public enum KeyEntry {
|
||||||
STORAGE_SIGNATURE("storageSignature", Sig.KEY_ALGO),
|
MSG_SIGNATURE("sig", Sig.KEY_ALGO),
|
||||||
MSG_SIGNATURE("msgSignature", Sig.KEY_ALGO),
|
MSG_ENCRYPTION("enc", Encryption.ENCR_KEY_ALGO);
|
||||||
MSG_ENCRYPTION("msgEncryption", Encryption.ENCR_KEY_ALGO);
|
|
||||||
|
|
||||||
private final String fileName;
|
private final String fileName;
|
||||||
private final String algorithm;
|
private final String algorithm;
|
||||||
|
|
||||||
Key(String fileName, String algorithm) {
|
KeyEntry(String fileName, String algorithm) {
|
||||||
this.fileName = fileName;
|
this.fileName = fileName;
|
||||||
this.algorithm = algorithm;
|
this.algorithm = algorithm;
|
||||||
}
|
}
|
||||||
|
@ -72,39 +72,26 @@ public class KeyStorage {
|
||||||
private final File storageDir;
|
private final File storageDir;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public KeyStorage(@Named(DIR_KEY) File storageDir) throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException {
|
public KeyStorage(@Named(DIR_KEY) File storageDir) {
|
||||||
this.storageDir = storageDir;
|
this.storageDir = storageDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean allKeyFilesExist() {
|
public boolean allKeyFilesExist() {
|
||||||
return fileExists(KeyStorage.Key.STORAGE_SIGNATURE) && fileExists(KeyStorage.Key.MSG_SIGNATURE) && fileExists(KeyStorage.Key.MSG_ENCRYPTION);
|
return fileExists(KeyEntry.MSG_SIGNATURE) && fileExists(KeyEntry.MSG_ENCRYPTION);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean fileExists(Key key) {
|
private boolean fileExists(KeyEntry keyEntry) {
|
||||||
return new File(storageDir + "/" + key.getFileName() + "Pub.key").exists();
|
return new File(storageDir + "/" + keyEntry.getFileName() + ".key").exists();
|
||||||
}
|
}
|
||||||
|
|
||||||
public KeyPair loadKeyPair(Key key) {
|
public KeyPair loadKeyPair(KeyEntry keyEntry) {
|
||||||
// long now = System.currentTimeMillis();
|
// long now = System.currentTimeMillis();
|
||||||
try {
|
try {
|
||||||
KeyFactory keyFactory = KeyFactory.getInstance(key.getAlgorithm());
|
KeyFactory keyFactory = KeyFactory.getInstance(keyEntry.getAlgorithm());
|
||||||
PublicKey publicKey;
|
PublicKey publicKey;
|
||||||
PrivateKey privateKey;
|
PrivateKey privateKey;
|
||||||
|
|
||||||
File filePublicKey = new File(storageDir + "/" + key.getFileName() + "Pub.key");
|
File filePrivateKey = new File(storageDir + "/" + keyEntry.getFileName() + ".key");
|
||||||
try (FileInputStream fis = new FileInputStream(filePublicKey.getPath())) {
|
|
||||||
byte[] encodedPublicKey = new byte[(int) filePublicKey.length()];
|
|
||||||
fis.read(encodedPublicKey);
|
|
||||||
|
|
||||||
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(encodedPublicKey);
|
|
||||||
publicKey = keyFactory.generatePublic(publicKeySpec);
|
|
||||||
} catch (InvalidKeySpecException | IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
log.error(e.getMessage());
|
|
||||||
throw new RuntimeException("Could not load key " + key.toString(), e);
|
|
||||||
}
|
|
||||||
|
|
||||||
File filePrivateKey = new File(storageDir + "/" + key.getFileName() + "Priv.key");
|
|
||||||
try (FileInputStream fis = new FileInputStream(filePrivateKey.getPath())) {
|
try (FileInputStream fis = new FileInputStream(filePrivateKey.getPath())) {
|
||||||
byte[] encodedPrivateKey = new byte[(int) filePrivateKey.length()];
|
byte[] encodedPrivateKey = new byte[(int) filePrivateKey.length()];
|
||||||
fis.read(encodedPrivateKey);
|
fis.read(encodedPrivateKey);
|
||||||
|
@ -114,39 +101,46 @@ public class KeyStorage {
|
||||||
} catch (InvalidKeySpecException | IOException e) {
|
} catch (InvalidKeySpecException | IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
log.error(e.getMessage());
|
log.error(e.getMessage());
|
||||||
throw new RuntimeException("Could not load key " + key.toString(), e);
|
throw new RuntimeException("Could not load key " + keyEntry.toString(), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (privateKey instanceof RSAPrivateCrtKey) {
|
||||||
|
RSAPrivateCrtKey rsaPrivateKey = (RSAPrivateCrtKey) privateKey;
|
||||||
|
RSAPublicKeySpec publicKeySpec = new RSAPublicKeySpec(rsaPrivateKey.getModulus(), rsaPrivateKey.getPublicExponent());
|
||||||
|
publicKey = keyFactory.generatePublic(publicKeySpec);
|
||||||
|
} else if (privateKey instanceof DSAPrivateKey) {
|
||||||
|
DSAPrivateKey dsaPrivateKey = (DSAPrivateKey) privateKey;
|
||||||
|
DSAParams dsaParams = dsaPrivateKey.getParams();
|
||||||
|
BigInteger p = dsaParams.getP();
|
||||||
|
BigInteger q = dsaParams.getQ();
|
||||||
|
BigInteger g = dsaParams.getG();
|
||||||
|
BigInteger y = g.modPow(dsaPrivateKey.getX(), p);
|
||||||
|
KeySpec publicKeySpec = new DSAPublicKeySpec(y, p, q, g);
|
||||||
|
publicKey = keyFactory.generatePublic(publicKeySpec);
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("Unsupported key algo" + keyEntry.getAlgorithm());
|
||||||
|
}
|
||||||
|
|
||||||
//log.info("load completed in {} msec", System.currentTimeMillis() - now);
|
//log.info("load completed in {} msec", System.currentTimeMillis() - now);
|
||||||
return new KeyPair(publicKey, privateKey);
|
return new KeyPair(publicKey, privateKey);
|
||||||
|
} catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
|
||||||
} catch (NoSuchAlgorithmException e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
log.error(e.getMessage());
|
log.error(e.getMessage());
|
||||||
throw new RuntimeException("Could not load key " + key.toString(), e);
|
throw new RuntimeException("Could not load key " + keyEntry.toString(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void saveKeyRing(KeyRing keyRing) {
|
public void saveKeyRing(KeyRing keyRing) {
|
||||||
saveKeyPair(keyRing.getStorageSignatureKeyPair(), Key.STORAGE_SIGNATURE.getFileName());
|
savePrivateKey(keyRing.getSignatureKeyPair().getPrivate(), KeyEntry.MSG_SIGNATURE.getFileName());
|
||||||
saveKeyPair(keyRing.getSignatureKeyPair(), Key.MSG_SIGNATURE.getFileName());
|
savePrivateKey(keyRing.getEncryptionKeyPair().getPrivate(), KeyEntry.MSG_ENCRYPTION.getFileName());
|
||||||
saveKeyPair(keyRing.getEncryptionKeyPair(), Key.MSG_ENCRYPTION.getFileName());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void saveKeyPair(KeyPair keyPair, String name) {
|
public void savePrivateKey(PrivateKey privateKey, String name) {
|
||||||
if (!storageDir.exists())
|
if (!storageDir.exists())
|
||||||
storageDir.mkdir();
|
storageDir.mkdir();
|
||||||
|
|
||||||
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyPair.getPublic().getEncoded());
|
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privateKey.getEncoded());
|
||||||
try (FileOutputStream fos = new FileOutputStream(storageDir + "/" + name + "Pub.key")) {
|
try (FileOutputStream fos = new FileOutputStream(storageDir + "/" + name + ".key")) {
|
||||||
fos.write(x509EncodedKeySpec.getEncoded());
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
log.error(e.getMessage());
|
|
||||||
throw new RuntimeException("Could not save key " + name, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyPair.getPrivate().getEncoded());
|
|
||||||
try (FileOutputStream fos = new FileOutputStream(storageDir + "/" + name + "Priv.key")) {
|
|
||||||
fos.write(pkcs8EncodedKeySpec.getEncoded());
|
fos.write(pkcs8EncodedKeySpec.getEncoded());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|
|
@ -21,13 +21,14 @@ import io.bitsquare.app.Version;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.ObjectInputStream;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.security.KeyFactory;
|
import java.security.KeyFactory;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.PublicKey;
|
import java.security.PublicKey;
|
||||||
import java.security.spec.InvalidKeySpecException;
|
import java.security.spec.InvalidKeySpecException;
|
||||||
import java.security.spec.X509EncodedKeySpec;
|
import java.security.spec.X509EncodedKeySpec;
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Same as KeyRing but with public keys only.
|
* Same as KeyRing but with public keys only.
|
||||||
|
@ -39,87 +40,65 @@ public class PubKeyRing implements Serializable {
|
||||||
|
|
||||||
transient private static final Logger log = LoggerFactory.getLogger(PubKeyRing.class);
|
transient private static final Logger log = LoggerFactory.getLogger(PubKeyRing.class);
|
||||||
|
|
||||||
private final byte[] storageSignaturePubKeyBytes;
|
private final byte[] signaturePubKeyBytes;
|
||||||
private final byte[] msgSignaturePubKeyBytes;
|
private final byte[] encryptionPubKeyBytes;
|
||||||
private final byte[] msgEncryptionPubKeyBytes;
|
|
||||||
|
|
||||||
transient private PublicKey storageSignaturePubKey;
|
transient private PublicKey signaturePubKey;
|
||||||
transient private PublicKey msgSignaturePubKey;
|
|
||||||
transient private PublicKey encryptionPubKey;
|
transient private PublicKey encryptionPubKey;
|
||||||
|
|
||||||
public PubKeyRing(PublicKey storageSignaturePubKey, PublicKey msgSignaturePubKey, PublicKey encryptionPubKey) {
|
public PubKeyRing(PublicKey signaturePubKey, PublicKey encryptionPubKey) {
|
||||||
this.storageSignaturePubKey = storageSignaturePubKey;
|
this.signaturePubKey = signaturePubKey;
|
||||||
this.msgSignaturePubKey = msgSignaturePubKey;
|
|
||||||
this.encryptionPubKey = encryptionPubKey;
|
this.encryptionPubKey = encryptionPubKey;
|
||||||
|
|
||||||
this.storageSignaturePubKeyBytes = new X509EncodedKeySpec(storageSignaturePubKey.getEncoded()).getEncoded();
|
this.signaturePubKeyBytes = new X509EncodedKeySpec(signaturePubKey.getEncoded()).getEncoded();
|
||||||
this.msgSignaturePubKeyBytes = new X509EncodedKeySpec(msgSignaturePubKey.getEncoded()).getEncoded();
|
this.encryptionPubKeyBytes = new X509EncodedKeySpec(encryptionPubKey.getEncoded()).getEncoded();
|
||||||
this.msgEncryptionPubKeyBytes = new X509EncodedKeySpec(encryptionPubKey.getEncoded()).getEncoded();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public PublicKey getStorageSignaturePubKey() {
|
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
|
||||||
if (storageSignaturePubKey == null) {
|
|
||||||
try {
|
try {
|
||||||
storageSignaturePubKey = KeyFactory.getInstance(Sig.KEY_ALGO).generatePublic(new X509EncodedKeySpec(storageSignaturePubKeyBytes));
|
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) {
|
} catch (InvalidKeySpecException | NoSuchAlgorithmException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
log.error(e.getMessage());
|
log.error(e.getMessage());
|
||||||
|
} catch (Throwable t) {
|
||||||
|
log.trace("Cannot be deserialized." + t.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return storageSignaturePubKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public PublicKey getSignaturePubKey() {
|
||||||
public PublicKey getMsgSignaturePubKey() {
|
return signaturePubKey;
|
||||||
if (msgSignaturePubKey == null) {
|
|
||||||
try {
|
|
||||||
msgSignaturePubKey = KeyFactory.getInstance(Sig.KEY_ALGO).generatePublic(new X509EncodedKeySpec(msgSignaturePubKeyBytes));
|
|
||||||
} catch (InvalidKeySpecException | NoSuchAlgorithmException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
log.error(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return msgSignaturePubKey;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public PublicKey getEncryptionPubKey() {
|
public PublicKey getEncryptionPubKey() {
|
||||||
if (encryptionPubKey == null) {
|
|
||||||
try {
|
|
||||||
encryptionPubKey = KeyFactory.getInstance(Encryption.ENCR_KEY_ALGO).generatePublic(new X509EncodedKeySpec(msgEncryptionPubKeyBytes));
|
|
||||||
} catch (InvalidKeySpecException | NoSuchAlgorithmException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
log.error(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return encryptionPubKey;
|
return encryptionPubKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (!(o instanceof PubKeyRing)) return false;
|
||||||
|
|
||||||
PubKeyRing that = (PubKeyRing) o;
|
PubKeyRing that = (PubKeyRing) o;
|
||||||
|
|
||||||
if (!Arrays.equals(storageSignaturePubKeyBytes, that.storageSignaturePubKeyBytes)) return false;
|
if (signaturePubKey != null ? !signaturePubKey.equals(that.signaturePubKey) : that.signaturePubKey != null)
|
||||||
if (!Arrays.equals(msgSignaturePubKeyBytes, that.msgSignaturePubKeyBytes)) return false;
|
return false;
|
||||||
return Arrays.equals(msgEncryptionPubKeyBytes, that.msgEncryptionPubKeyBytes);
|
return !(encryptionPubKey != null ? !encryptionPubKey.equals(that.encryptionPubKey) : that.encryptionPubKey != null);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
int result = storageSignaturePubKeyBytes != null ? Arrays.hashCode(storageSignaturePubKeyBytes) : 0;
|
int result = signaturePubKey != null ? signaturePubKey.hashCode() : 0;
|
||||||
result = 31 * result + (msgSignaturePubKeyBytes != null ? Arrays.hashCode(msgSignaturePubKeyBytes) : 0);
|
result = 31 * result + (encryptionPubKey != null ? encryptionPubKey.hashCode() : 0);
|
||||||
result = 31 * result + (msgEncryptionPubKeyBytes != null ? Arrays.hashCode(msgEncryptionPubKeyBytes) : 0);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "PubKeyRing{" +
|
return "PubKeyRing{" +
|
||||||
"\nstorageSignaturePubKey=\n" + Util.pubKeyToString(getStorageSignaturePubKey()) +
|
"\n\nmsgSignaturePubKey=\n" + Util.pubKeyToString(getSignaturePubKey()) +
|
||||||
"\n\nmsgSignaturePubKey=\n" + Util.pubKeyToString(getMsgSignaturePubKey()) +
|
|
||||||
"\n\nmsgEncryptionPubKey=\n" + Util.pubKeyToString(getEncryptionPubKey()) +
|
"\n\nmsgEncryptionPubKey=\n" + Util.pubKeyToString(getEncryptionPubKey()) +
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,7 +128,7 @@ public class AlertManager {
|
||||||
private void signAndAddSignatureToAlertMessage(Alert alert) {
|
private void signAndAddSignatureToAlertMessage(Alert alert) {
|
||||||
String alertMessageAsHex = Utils.HEX.encode(alert.message.getBytes());
|
String alertMessageAsHex = Utils.HEX.encode(alert.message.getBytes());
|
||||||
String signatureAsBase64 = alertSigningKey.signMessage(alertMessageAsHex);
|
String signatureAsBase64 = alertSigningKey.signMessage(alertMessageAsHex);
|
||||||
alert.setSigAndStoragePubKey(signatureAsBase64, keyRing.getStorageSignatureKeyPair().getPublic());
|
alert.setSigAndStoragePubKey(signatureAsBase64, keyRing.getSignatureKeyPair().getPublic());
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean verifySignature(Alert alert) {
|
private boolean verifySignature(Alert alert) {
|
||||||
|
|
|
@ -73,7 +73,7 @@ public final class Arbitrator implements PubKeyProtectedExpirablePayload {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PublicKey getPubKey() {
|
public PublicKey getPubKey() {
|
||||||
return pubKeyRing.getStorageSignaturePubKey();
|
return pubKeyRing.getSignaturePubKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] getBtcPubKey() {
|
public byte[] getBtcPubKey() {
|
||||||
|
|
|
@ -169,7 +169,7 @@ public class ArbitratorManager {
|
||||||
arbitratorsObservableMap.clear();
|
arbitratorsObservableMap.clear();
|
||||||
Map<Address, Arbitrator> filtered = map.values().stream()
|
Map<Address, Arbitrator> filtered = map.values().stream()
|
||||||
.filter(e -> isPublicKeyInList(Utils.HEX.encode(e.getRegistrationPubKey()))
|
.filter(e -> isPublicKeyInList(Utils.HEX.encode(e.getRegistrationPubKey()))
|
||||||
&& verifySignature(e.getPubKeyRing().getStorageSignaturePubKey(), e.getRegistrationPubKey(), e.getRegistrationSignature()))
|
&& verifySignature(e.getPubKeyRing().getSignaturePubKey(), e.getRegistrationPubKey(), e.getRegistrationSignature()))
|
||||||
.collect(Collectors.toMap(Arbitrator::getArbitratorAddress, Function.identity()));
|
.collect(Collectors.toMap(Arbitrator::getArbitratorAddress, Function.identity()));
|
||||||
|
|
||||||
arbitratorsObservableMap.putAll(filtered);
|
arbitratorsObservableMap.putAll(filtered);
|
||||||
|
@ -233,7 +233,7 @@ public class ArbitratorManager {
|
||||||
// An invited arbitrator will sign at registration his storageSignaturePubKey with that private key and attach the signature and pubKey to his data.
|
// An invited arbitrator will sign at registration his storageSignaturePubKey with that private key and attach the signature and pubKey to his data.
|
||||||
// Other users will check the signature with the list of public keys hardcoded in the app.
|
// Other users will check the signature with the list of public keys hardcoded in the app.
|
||||||
public String signStorageSignaturePubKey(ECKey key) {
|
public String signStorageSignaturePubKey(ECKey key) {
|
||||||
String keyToSignAsHex = Utils.HEX.encode(keyRing.getPubKeyRing().getStorageSignaturePubKey().getEncoded());
|
String keyToSignAsHex = Utils.HEX.encode(keyRing.getPubKeyRing().getSignaturePubKey().getEncoded());
|
||||||
return key.signMessage(keyToSignAsHex);
|
return key.signMessage(keyToSignAsHex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -250,7 +250,7 @@ public final class Offer implements PubKeyProtectedExpirablePayload {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PublicKey getPubKey() {
|
public PublicKey getPubKey() {
|
||||||
return pubKeyRing.getStorageSignaturePubKey();
|
return pubKeyRing.getSignaturePubKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,7 @@ public abstract class TradeProtocol {
|
||||||
// We check the sig only as soon we have stored the peers pubKeyRing.
|
// We check the sig only as soon we have stored the peers pubKeyRing.
|
||||||
PubKeyRing tradingPeerPubKeyRing = processModel.tradingPeer.getPubKeyRing();
|
PubKeyRing tradingPeerPubKeyRing = processModel.tradingPeer.getPubKeyRing();
|
||||||
PublicKey signaturePubKey = decryptedMessageWithPubKey.signaturePubKey;
|
PublicKey signaturePubKey = decryptedMessageWithPubKey.signaturePubKey;
|
||||||
if (tradingPeerPubKeyRing != null && signaturePubKey.equals(tradingPeerPubKeyRing.getMsgSignaturePubKey())) {
|
if (tradingPeerPubKeyRing != null && signaturePubKey.equals(tradingPeerPubKeyRing.getSignaturePubKey())) {
|
||||||
Message message = decryptedMessageWithPubKey.message;
|
Message message = decryptedMessageWithPubKey.message;
|
||||||
log.trace("handleNewMessage: message = " + message.getClass().getSimpleName() + " from " + peerAddress);
|
log.trace("handleNewMessage: message = " + message.getClass().getSimpleName() + " from " + peerAddress);
|
||||||
if (message instanceof TradeMessage) {
|
if (message instanceof TradeMessage) {
|
||||||
|
@ -75,7 +75,7 @@ public abstract class TradeProtocol {
|
||||||
if (arbitratorOptional.isPresent())
|
if (arbitratorOptional.isPresent())
|
||||||
arbitratorPubKeyRing = arbitratorOptional.get().getPubKeyRing();
|
arbitratorPubKeyRing = arbitratorOptional.get().getPubKeyRing();
|
||||||
|
|
||||||
if ((arbitratorPubKeyRing != null && !signaturePubKey.equals(arbitratorPubKeyRing.getMsgSignaturePubKey())))
|
if ((arbitratorPubKeyRing != null && !signaturePubKey.equals(arbitratorPubKeyRing.getSignaturePubKey())))
|
||||||
log.error("Signature used in seal message does not match the one stored with that trade for the trading peer or arbitrator.");
|
log.error("Signature used in seal message does not match the one stored with that trade for the trading peer or arbitrator.");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -96,7 +96,7 @@ public abstract class TradeProtocol {
|
||||||
|
|
||||||
public void applyMailboxMessage(DecryptedMessageWithPubKey decryptedMessageWithPubKey, Trade trade) {
|
public void applyMailboxMessage(DecryptedMessageWithPubKey decryptedMessageWithPubKey, Trade trade) {
|
||||||
log.debug("applyMailboxMessage " + decryptedMessageWithPubKey.message);
|
log.debug("applyMailboxMessage " + decryptedMessageWithPubKey.message);
|
||||||
if (decryptedMessageWithPubKey.signaturePubKey.equals(processModel.tradingPeer.getPubKeyRing().getMsgSignaturePubKey()))
|
if (decryptedMessageWithPubKey.signaturePubKey.equals(processModel.tradingPeer.getPubKeyRing().getSignaturePubKey()))
|
||||||
doApplyMailboxMessage(decryptedMessageWithPubKey.message, trade);
|
doApplyMailboxMessage(decryptedMessageWithPubKey.message, trade);
|
||||||
else
|
else
|
||||||
log.error("SignaturePubKey in message does not match the SignaturePubKey we have stored to that trading peer.");
|
log.error("SignaturePubKey in message does not match the SignaturePubKey we have stored to that trading peer.");
|
||||||
|
|
|
@ -80,7 +80,7 @@ public class VerifyAndSignContract extends TradeTask {
|
||||||
trade.setTakerContractSignature(signature);
|
trade.setTakerContractSignature(signature);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Sig.verify(offerer.getPubKeyRing().getMsgSignaturePubKey(),
|
Sig.verify(offerer.getPubKeyRing().getSignaturePubKey(),
|
||||||
contractAsJson,
|
contractAsJson,
|
||||||
offerer.getContractSignature());
|
offerer.getContractSignature());
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
|
|
|
@ -317,7 +317,7 @@ public class P2PService {
|
||||||
log.trace("removeEntryFromMailbox");
|
log.trace("removeEntryFromMailbox");
|
||||||
ProtectedMailboxData mailboxData = mailboxMap.get(decryptedMessageWithPubKey);
|
ProtectedMailboxData mailboxData = mailboxMap.get(decryptedMessageWithPubKey);
|
||||||
if (mailboxData != null && mailboxData.expirablePayload instanceof ExpirableMailboxPayload) {
|
if (mailboxData != null && mailboxData.expirablePayload instanceof ExpirableMailboxPayload) {
|
||||||
checkArgument(mailboxData.receiversPubKey.equals(keyRing.getStorageSignatureKeyPair().getPublic()),
|
checkArgument(mailboxData.receiversPubKey.equals(keyRing.getSignatureKeyPair().getPublic()),
|
||||||
"mailboxData.receiversPubKey is not matching with our key. That must not happen.");
|
"mailboxData.receiversPubKey is not matching with our key. That must not happen.");
|
||||||
removeMailboxData((ExpirableMailboxPayload) mailboxData.expirablePayload, mailboxData.receiversPubKey);
|
removeMailboxData((ExpirableMailboxPayload) mailboxData.expirablePayload, mailboxData.receiversPubKey);
|
||||||
mailboxMap.remove(decryptedMessageWithPubKey);
|
mailboxMap.remove(decryptedMessageWithPubKey);
|
||||||
|
@ -404,9 +404,9 @@ public class P2PService {
|
||||||
log.debug(throwable.toString());
|
log.debug(throwable.toString());
|
||||||
log.info("We cannot send message to peer. Peer might be offline. We will store message in mailbox.");
|
log.info("We cannot send message to peer. Peer might be offline. We will store message in mailbox.");
|
||||||
log.trace("create MailboxEntry with peerAddress " + peerAddress);
|
log.trace("create MailboxEntry with peerAddress " + peerAddress);
|
||||||
PublicKey receiverStoragePublicKey = peersPubKeyRing.getStorageSignaturePubKey();
|
PublicKey receiverStoragePublicKey = peersPubKeyRing.getSignaturePubKey();
|
||||||
addMailboxData(new ExpirableMailboxPayload(sealedAndSignedMessage,
|
addMailboxData(new ExpirableMailboxPayload(sealedAndSignedMessage,
|
||||||
keyRing.getStorageSignatureKeyPair().getPublic(),
|
keyRing.getSignatureKeyPair().getPublic(),
|
||||||
receiverStoragePublicKey),
|
receiverStoragePublicKey),
|
||||||
receiverStoragePublicKey);
|
receiverStoragePublicKey);
|
||||||
UserThread.execute(() -> sendMailboxMessageListener.onStoredInMailbox());
|
UserThread.execute(() -> sendMailboxMessageListener.onStoredInMailbox());
|
||||||
|
@ -430,7 +430,7 @@ public class P2PService {
|
||||||
throw new AuthenticationException("You must be authenticated before adding data to the P2P network.");
|
throw new AuthenticationException("You must be authenticated before adding data to the P2P network.");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return dataStorage.add(dataStorage.getDataWithSignedSeqNr(expirablePayload, keyRing.getStorageSignatureKeyPair()), networkNode.getAddress());
|
return dataStorage.add(dataStorage.getDataWithSignedSeqNr(expirablePayload, keyRing.getSignatureKeyPair()), networkNode.getAddress());
|
||||||
} catch (NoSuchAlgorithmException | SignatureException | InvalidKeyException e) {
|
} catch (NoSuchAlgorithmException | SignatureException | InvalidKeyException e) {
|
||||||
log.error("Signing at getDataWithSignedSeqNr failed. That should never happen.");
|
log.error("Signing at getDataWithSignedSeqNr failed. That should never happen.");
|
||||||
return false;
|
return false;
|
||||||
|
@ -442,7 +442,7 @@ public class P2PService {
|
||||||
throw new AuthenticationException("You must be authenticated before adding data to the P2P network.");
|
throw new AuthenticationException("You must be authenticated before adding data to the P2P network.");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return dataStorage.add(dataStorage.getMailboxDataWithSignedSeqNr(expirableMailboxPayload, keyRing.getStorageSignatureKeyPair(), receiversPublicKey), networkNode.getAddress());
|
return dataStorage.add(dataStorage.getMailboxDataWithSignedSeqNr(expirableMailboxPayload, keyRing.getSignatureKeyPair(), receiversPublicKey), networkNode.getAddress());
|
||||||
} catch (NoSuchAlgorithmException | SignatureException | InvalidKeyException e) {
|
} catch (NoSuchAlgorithmException | SignatureException | InvalidKeyException e) {
|
||||||
log.error("Signing at getDataWithSignedSeqNr failed. That should never happen.");
|
log.error("Signing at getDataWithSignedSeqNr failed. That should never happen.");
|
||||||
return false;
|
return false;
|
||||||
|
@ -453,7 +453,7 @@ public class P2PService {
|
||||||
if (!authenticatedToFirstPeer)
|
if (!authenticatedToFirstPeer)
|
||||||
throw new AuthenticationException("You must be authenticated before removing data from the P2P network.");
|
throw new AuthenticationException("You must be authenticated before removing data from the P2P network.");
|
||||||
try {
|
try {
|
||||||
return dataStorage.remove(dataStorage.getDataWithSignedSeqNr(expirablePayload, keyRing.getStorageSignatureKeyPair()), networkNode.getAddress());
|
return dataStorage.remove(dataStorage.getDataWithSignedSeqNr(expirablePayload, keyRing.getSignatureKeyPair()), networkNode.getAddress());
|
||||||
} catch (NoSuchAlgorithmException | SignatureException | InvalidKeyException e) {
|
} catch (NoSuchAlgorithmException | SignatureException | InvalidKeyException e) {
|
||||||
log.error("Signing at getDataWithSignedSeqNr failed. That should never happen.");
|
log.error("Signing at getDataWithSignedSeqNr failed. That should never happen.");
|
||||||
return false;
|
return false;
|
||||||
|
@ -464,7 +464,7 @@ public class P2PService {
|
||||||
if (!authenticatedToFirstPeer)
|
if (!authenticatedToFirstPeer)
|
||||||
throw new AuthenticationException("You must be authenticated before removing data from the P2P network.");
|
throw new AuthenticationException("You must be authenticated before removing data from the P2P network.");
|
||||||
try {
|
try {
|
||||||
return dataStorage.removeMailboxData(dataStorage.getMailboxDataWithSignedSeqNr(expirableMailboxPayload, keyRing.getStorageSignatureKeyPair(), receiversPublicKey), networkNode.getAddress());
|
return dataStorage.removeMailboxData(dataStorage.getMailboxDataWithSignedSeqNr(expirableMailboxPayload, keyRing.getSignatureKeyPair(), receiversPublicKey), networkNode.getAddress());
|
||||||
} catch (NoSuchAlgorithmException | SignatureException | InvalidKeyException e) {
|
} catch (NoSuchAlgorithmException | SignatureException | InvalidKeyException e) {
|
||||||
log.error("Signing at getDataWithSignedSeqNr failed. That should never happen.");
|
log.error("Signing at getDataWithSignedSeqNr failed. That should never happen.");
|
||||||
return false;
|
return false;
|
||||||
|
@ -642,7 +642,7 @@ public class P2PService {
|
||||||
checkNotNull(senderAddress, "senderAddress must not be null for mailbox messages");
|
checkNotNull(senderAddress, "senderAddress must not be null for mailbox messages");
|
||||||
|
|
||||||
log.trace("mailboxData.publicKey " + mailboxData.ownerStoragePubKey.hashCode());
|
log.trace("mailboxData.publicKey " + mailboxData.ownerStoragePubKey.hashCode());
|
||||||
log.trace("keyRing.getStorageSignatureKeyPair().getPublic() " + keyRing.getStorageSignatureKeyPair().getPublic().hashCode());
|
log.trace("keyRing.getStorageSignatureKeyPair().getPublic() " + keyRing.getSignatureKeyPair().getPublic().hashCode());
|
||||||
log.trace("keyRing.getMsgSignatureKeyPair().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.getMsgEncryptionKeyPair().getPublic() " + keyRing.getEncryptionKeyPair().getPublic().hashCode());
|
||||||
|
|
||||||
|
|
|
@ -113,7 +113,7 @@ public class P2PServiceTest {
|
||||||
public void testAdversaryAttacks() throws InterruptedException, NoSuchAlgorithmException, CertificateException, KeyStoreException, IOException, CryptoException, SignatureException, InvalidKeyException {
|
public void testAdversaryAttacks() throws InterruptedException, NoSuchAlgorithmException, CertificateException, KeyStoreException, IOException, CryptoException, SignatureException, InvalidKeyException {
|
||||||
p2PService3 = TestUtils.getAndAuthenticateP2PService(8003, encryptionService3, keyRing3, useLocalhost, seedNodes);
|
p2PService3 = TestUtils.getAndAuthenticateP2PService(8003, encryptionService3, keyRing3, useLocalhost, seedNodes);
|
||||||
|
|
||||||
MockData origData = new MockData("mockData1", keyRing1.getStorageSignatureKeyPair().getPublic());
|
MockData origData = new MockData("mockData1", keyRing1.getSignatureKeyPair().getPublic());
|
||||||
|
|
||||||
p2PService1.addData(origData);
|
p2PService1.addData(origData);
|
||||||
Assert.assertEquals(1, p2PService1.getDataMap().size());
|
Assert.assertEquals(1, p2PService1.getDataMap().size());
|
||||||
|
@ -122,7 +122,7 @@ public class P2PServiceTest {
|
||||||
|
|
||||||
|
|
||||||
// p2PService3 is adversary
|
// p2PService3 is adversary
|
||||||
KeyPair msgSignatureKeyPairAdversary = keyRing3.getStorageSignatureKeyPair();
|
KeyPair msgSignatureKeyPairAdversary = keyRing3.getSignatureKeyPair();
|
||||||
|
|
||||||
// try to remove data -> fails
|
// try to remove data -> fails
|
||||||
Assert.assertFalse(p2PService3.removeData(origData));
|
Assert.assertFalse(p2PService3.removeData(origData));
|
||||||
|
|
|
@ -51,7 +51,7 @@ public class ProtectedDataStorageTest {
|
||||||
ProtectedExpirableDataStorage.CHECK_TTL_INTERVAL = 10 * 60 * 1000;
|
ProtectedExpirableDataStorage.CHECK_TTL_INTERVAL = 10 * 60 * 1000;
|
||||||
|
|
||||||
keyRing1 = new KeyRing(new KeyStorage(new File("temp_keyStorage1")));
|
keyRing1 = new KeyRing(new KeyStorage(new File("temp_keyStorage1")));
|
||||||
storageSignatureKeyPair1 = keyRing1.getStorageSignatureKeyPair();
|
storageSignatureKeyPair1 = keyRing1.getSignatureKeyPair();
|
||||||
encryptionService1 = new EncryptionService(keyRing1);
|
encryptionService1 = new EncryptionService(keyRing1);
|
||||||
networkNode1 = TestUtils.getAndStartSeedNode(8001, encryptionService1, keyRing1, useClearNet, seedNodes).getP2PService().getNetworkNode();
|
networkNode1 = TestUtils.getAndStartSeedNode(8001, encryptionService1, keyRing1, useClearNet, seedNodes).getP2PService().getNetworkNode();
|
||||||
routing1 = new Routing(networkNode1, seedNodes);
|
routing1 = new Routing(networkNode1, seedNodes);
|
||||||
|
@ -59,10 +59,10 @@ public class ProtectedDataStorageTest {
|
||||||
|
|
||||||
// for mailbox
|
// for mailbox
|
||||||
keyRing2 = new KeyRing(new KeyStorage(new File("temp_keyStorage2")));
|
keyRing2 = new KeyRing(new KeyStorage(new File("temp_keyStorage2")));
|
||||||
storageSignatureKeyPair2 = keyRing2.getStorageSignatureKeyPair();
|
storageSignatureKeyPair2 = keyRing2.getSignatureKeyPair();
|
||||||
encryptionService2 = new EncryptionService(keyRing2);
|
encryptionService2 = new EncryptionService(keyRing2);
|
||||||
|
|
||||||
mockData = new MockData("mockData", keyRing1.getStorageSignatureKeyPair().getPublic());
|
mockData = new MockData("mockData", keyRing1.getSignatureKeyPair().getPublic());
|
||||||
Thread.sleep(sleepTime);
|
Thread.sleep(sleepTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,7 +130,7 @@ public class ProtectedDataStorageTest {
|
||||||
|
|
||||||
@Test
|
@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 {
|
||||||
MockData mockData = new MockData("msg1", keyRing1.getStorageSignatureKeyPair().getPublic());
|
MockData mockData = new MockData("msg1", keyRing1.getSignatureKeyPair().getPublic());
|
||||||
ProtectedData data = dataStorage1.getDataWithSignedSeqNr(mockData, storageSignatureKeyPair1);
|
ProtectedData data = dataStorage1.getDataWithSignedSeqNr(mockData, storageSignatureKeyPair1);
|
||||||
Assert.assertTrue(dataStorage1.add(data, null));
|
Assert.assertTrue(dataStorage1.add(data, null));
|
||||||
|
|
||||||
|
@ -197,8 +197,8 @@ public class ProtectedDataStorageTest {
|
||||||
MockMessage mockMessage = new MockMessage("MockMessage");
|
MockMessage mockMessage = new MockMessage("MockMessage");
|
||||||
SealedAndSignedMessage sealedAndSignedMessage = new SealedAndSignedMessage(encryptionService1.encryptAndSignMessage(keyRing1.getPubKeyRing(), mockMessage), null);
|
SealedAndSignedMessage sealedAndSignedMessage = new SealedAndSignedMessage(encryptionService1.encryptAndSignMessage(keyRing1.getPubKeyRing(), mockMessage), null);
|
||||||
ExpirableMailboxPayload expirableMailboxPayload = new ExpirableMailboxPayload(sealedAndSignedMessage,
|
ExpirableMailboxPayload expirableMailboxPayload = new ExpirableMailboxPayload(sealedAndSignedMessage,
|
||||||
keyRing1.getStorageSignatureKeyPair().getPublic(),
|
keyRing1.getSignatureKeyPair().getPublic(),
|
||||||
keyRing2.getStorageSignatureKeyPair().getPublic());
|
keyRing2.getSignatureKeyPair().getPublic());
|
||||||
|
|
||||||
ProtectedMailboxData data = dataStorage1.getMailboxDataWithSignedSeqNr(expirableMailboxPayload, storageSignatureKeyPair1, storageSignatureKeyPair2.getPublic());
|
ProtectedMailboxData data = dataStorage1.getMailboxDataWithSignedSeqNr(expirableMailboxPayload, storageSignatureKeyPair1, storageSignatureKeyPair2.getPublic());
|
||||||
Assert.assertTrue(dataStorage1.add(data, null));
|
Assert.assertTrue(dataStorage1.add(data, null));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue