Remove PGP keys from the KeyRing

The PGP support was envisioned in the KeyRing but never fully
implemented. This removes the (essentially) dead code.

The protobuf message compatibility is implemented with `reserved`.
This commit is contained in:
battleofwizards 2019-09-05 14:19:01 +02:00
parent d4079cb161
commit 82e9672e91
No known key found for this signature in database
GPG Key ID: 58B1485148D203E1
7 changed files with 11 additions and 200 deletions

View File

@ -20,18 +20,12 @@ package bisq.common.crypto;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.bouncycastle.openpgp.PGPKeyPair;
import org.bouncycastle.openpgp.PGPPublicKey;
import java.security.KeyPair;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import javax.annotation.Nullable;
@Getter
@EqualsAndHashCode
@Slf4j
@ -41,33 +35,18 @@ public final class KeyRing {
private final KeyPair encryptionKeyPair;
private final PubKeyRing pubKeyRing;
// We generate by default a PGP keypair but the user can set his own if he prefers.
// Not impl. yet but prepared in data structure
@Nullable
@Setter
// TODO remove Nullable once impl.
private PGPKeyPair pgpKeyPair;
@Inject
public KeyRing(KeyStorage keyStorage) {
if (keyStorage.allKeyFilesExist()) {
signatureKeyPair = keyStorage.loadKeyPair(KeyStorage.KeyEntry.MSG_SIGNATURE);
encryptionKeyPair = keyStorage.loadKeyPair(KeyStorage.KeyEntry.MSG_ENCRYPTION);
// TODO not impl
pgpKeyPair = keyStorage.loadPgpKeyPair(KeyStorage.KeyEntry.PGP);
} else {
// First time we create key pairs
signatureKeyPair = Sig.generateKeyPair();
encryptionKeyPair = Encryption.generateKeyPair();
// TODO not impl
pgpKeyPair = PGP.generateKeyPair();
keyStorage.saveKeyRing(this);
}
// TODO remove Nullable once impl.
final PGPPublicKey pgpPublicKey = pgpKeyPair != null ? pgpKeyPair.getPublicKey() : null;
pubKeyRing = new PubKeyRing(signatureKeyPair.getPublic(), encryptionKeyPair.getPublic(), pgpPublicKey);
pubKeyRing = new PubKeyRing(signatureKeyPair.getPublic(), encryptionKeyPair.getPublic());
}
// Don't print keys for security reasons

View File

@ -24,8 +24,6 @@ import com.google.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import org.bouncycastle.openpgp.PGPKeyPair;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.NoSuchAlgorithmException;
@ -54,8 +52,6 @@ import org.slf4j.LoggerFactory;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable;
// TODO: use a password protection for key storage
@Singleton
public class KeyStorage {
@ -65,9 +61,7 @@ public class KeyStorage {
public enum KeyEntry {
MSG_SIGNATURE("sig", Sig.KEY_ALGO),
MSG_ENCRYPTION("enc", Encryption.ASYM_KEY_ALGO),
// TODO not impl
PGP("pgp", null);
MSG_ENCRYPTION("enc", Encryption.ASYM_KEY_ALGO);
private final String fileName;
private final String algorithm;
@ -111,14 +105,6 @@ public class KeyStorage {
return new File(storageDir + "/" + keyEntry.getFileName() + ".key").exists();
}
// TODO not impl
@SuppressWarnings({"SameParameterValue", "SameReturnValue", "UnusedParameters"})
@Nullable
public PGPKeyPair loadPgpKeyPair(KeyEntry keyEntry) {
return null;
}
public KeyPair loadKeyPair(KeyEntry keyEntry) {
FileUtil.rollingBackup(storageDir, keyEntry.getFileName() + ".key", 20);
// long now = System.currentTimeMillis();

View File

@ -1,134 +0,0 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.common.crypto;
import bisq.common.util.Hex;
import com.google.common.base.Charsets;
import org.bouncycastle.bcpg.BCPGKey;
import org.bouncycastle.bcpg.RSAPublicBCPGKey;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPKeyPair;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPUtil;
import org.bouncycastle.openpgp.jcajce.JcaPGPPublicKeyRingCollection;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAPublicKeySpec;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable;
@SuppressWarnings("UnusedAssignment")
@Slf4j
public class PGP {
// TODO not tested yet, remove Nullable once impl.
// PEM encoding
@Nullable
public static PGPPublicKey getPubKeyFromPem(@Nullable String pem) {
if (pem != null) {
InputStream inputStream = new ByteArrayInputStream(pem.getBytes(Charsets.UTF_8));
try {
inputStream = PGPUtil.getDecoderStream(inputStream);
try {
JcaPGPPublicKeyRingCollection ringCollection = new JcaPGPPublicKeyRingCollection(inputStream);
Iterator<PGPPublicKeyRing> keyRingsIterator = ringCollection.getKeyRings();
while (keyRingsIterator.hasNext()) {
PGPPublicKeyRing pgpPublicKeyRing = keyRingsIterator.next();
Iterator<PGPPublicKey> pubKeysIterator = pgpPublicKeyRing.getPublicKeys();
while (pubKeysIterator.hasNext()) {
final PGPPublicKey pgpPublicKey = pubKeysIterator.next();
if ((pgpPublicKey).isEncryptionKey()) {
log.debug(pgpPublicKey.getClass().getName()
+ " KeyID: " + Long.toHexString(pgpPublicKey.getKeyID())
+ " type: " + pgpPublicKey.getAlgorithm()
+ " fingerprint: " + Hex.encode(pgpPublicKey.getFingerprint()));
BCPGKey bcKey = pgpPublicKey.getPublicKeyPacket().getKey();
log.debug(bcKey.getClass().getName());
if (bcKey instanceof RSAPublicBCPGKey) {
RSAPublicBCPGKey bcRSA = (RSAPublicBCPGKey) bcKey;
RSAPublicKeySpec specRSA = new RSAPublicKeySpec(bcRSA.getModulus(), bcRSA.getPublicExponent());
PublicKey jceKey = KeyFactory.getInstance("RSA").generatePublic(specRSA);
// if you want to use the key in JCE, use jceKey
// if you want to write "X.509" (SPKI) DER format to a file:
//Files.write(new File(pubKeyAsString).toPath(), jceKey.getEncoded());
// if you want to write in PEM, bouncycastle can do that
// or you can just do base64 and add BEGIN/END lines
// return pubKeyAsString; // assume only one key; if need to handle multiple keys
// or select other than the first, specify more clearly
}
return pgpPublicKey;
}
}
}
return null;
} catch (PGPException | InvalidKeySpecException | NoSuchAlgorithmException e) {
log.error("Error creating publicKey from pem. pem={}, error={}", pem, e);
e.printStackTrace();
throw new KeyConversionException(e);
}
} catch (IOException e) {
log.error("Error creating publicKey from pem. pem={}, error={}", pem, e);
e.printStackTrace();
throw new KeyConversionException(e);
} finally {
try {
inputStream.close();
} catch (IOException ignore) {
}
}
} else {
log.warn("Error creating publicKey from pem. pem=null");
return null;
}
}
// TODO not impl, remove Nullable once impl.
// PEM encoding
@SuppressWarnings({"SameReturnValue", "UnusedParameters"})
@NotNull
public static String getPEMFromPubKey(@Nullable PGPPublicKey pgpPubKey) {
// We use empty string as we must not have null in proto file
return "";
}
// TODO not impl, remove Nullable once impl.
@SuppressWarnings("SameReturnValue")
@Nullable
public static PGPKeyPair generateKeyPair() {
return null;
}
}

View File

@ -25,16 +25,12 @@ import com.google.protobuf.ByteString;
import com.google.common.annotations.VisibleForTesting;
import org.bouncycastle.openpgp.PGPPublicKey;
import java.security.PublicKey;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import javax.annotation.Nullable;
/**
* Same as KeyRing but with public keys only.
* Used to send public keys over the wire to other peer.
@ -45,22 +41,15 @@ import javax.annotation.Nullable;
public final class PubKeyRing implements NetworkPayload, UsedForTradeContractJson {
private final byte[] signaturePubKeyBytes;
private final byte[] encryptionPubKeyBytes;
@Nullable
private final String pgpPubKeyAsPem;
private transient PublicKey signaturePubKey;
private transient PublicKey encryptionPubKey;
@Nullable
private transient PGPPublicKey pgpPubKey;
public PubKeyRing(PublicKey signaturePubKey, PublicKey encryptionPubKey, @Nullable PGPPublicKey pgpPubKey) {
public PubKeyRing(PublicKey signaturePubKey, PublicKey encryptionPubKey) {
this.signaturePubKeyBytes = Sig.getPublicKeyBytes(signaturePubKey);
this.encryptionPubKeyBytes = Encryption.getPublicKeyBytes(encryptionPubKey);
this.pgpPubKeyAsPem = PGP.getPEMFromPubKey(pgpPubKey);
this.signaturePubKey = signaturePubKey;
this.encryptionPubKey = encryptionPubKey;
this.pgpPubKey = pgpPubKey;
}
@ -69,15 +58,11 @@ public final class PubKeyRing implements NetworkPayload, UsedForTradeContractJso
///////////////////////////////////////////////////////////////////////////////////////////
@VisibleForTesting
public PubKeyRing(byte[] signaturePubKeyBytes, byte[] encryptionPubKeyBytes, @Nullable String pgpPubKeyAsPem) {
public PubKeyRing(byte[] signaturePubKeyBytes, byte[] encryptionPubKeyBytes) {
this.signaturePubKeyBytes = signaturePubKeyBytes;
this.encryptionPubKeyBytes = encryptionPubKeyBytes;
this.pgpPubKeyAsPem = pgpPubKeyAsPem;
signaturePubKey = Sig.getPublicKeyFromBytes(signaturePubKeyBytes);
encryptionPubKey = Encryption.getPublicKeyFromBytes(encryptionPubKeyBytes);
if (pgpPubKeyAsPem != null)
pgpPubKey = PGP.getPubKeyFromPem(pgpPubKeyAsPem);
}
@Override
@ -85,14 +70,13 @@ public final class PubKeyRing implements NetworkPayload, UsedForTradeContractJso
return protobuf.PubKeyRing.newBuilder()
.setSignaturePubKeyBytes(ByteString.copyFrom(signaturePubKeyBytes))
.setEncryptionPubKeyBytes(ByteString.copyFrom(encryptionPubKeyBytes))
.setPgpPubKeyAsPem(pgpPubKeyAsPem)
.build();
}
public static PubKeyRing fromProto(protobuf.PubKeyRing proto) {
return new PubKeyRing(proto.getSignaturePubKeyBytes().toByteArray(),
proto.getEncryptionPubKeyBytes().toByteArray(),
proto.getPgpPubKeyAsPem());
return new PubKeyRing(
proto.getSignaturePubKeyBytes().toByteArray(),
proto.getEncryptionPubKeyBytes().toByteArray());
}
@Override
@ -100,7 +84,6 @@ public final class PubKeyRing implements NetworkPayload, UsedForTradeContractJso
return "PubKeyRing{" +
"signaturePubKeyHex=" + Utilities.bytesAsHexString(signaturePubKeyBytes) +
", encryptionPubKeyHex=" + Utilities.bytesAsHexString(encryptionPubKeyBytes) +
", pgpPubKeyAsString=" + pgpPubKeyAsPem +
'}';
"}";
}
}

View File

@ -410,7 +410,7 @@ message Peer {
message PubKeyRing {
bytes signature_pub_key_bytes = 1;
bytes encryption_pub_key_bytes = 2;
string pgp_pub_key_as_pem = 3;
reserved 3; // WAS: string pgp_pub_key_as_pem = 3;
}
message SealedAndSigned {

View File

@ -44,7 +44,7 @@ public class ArbitratorTest {
return new Arbitrator(new NodeAddress("host", 1000),
getBytes(100),
"btcaddress",
new PubKeyRing(getBytes(100), getBytes(100), "key"),
new PubKeyRing(getBytes(100), getBytes(100)),
Lists.newArrayList(),
new Date().getTime(),
getBytes(100),
@ -56,4 +56,3 @@ public class ArbitratorTest {
return RandomUtils.nextBytes(count);
}
}

View File

@ -42,7 +42,7 @@ public class MediatorTest {
public static Mediator getMediatorMock() {
return new Mediator(new NodeAddress("host", 1000),
new PubKeyRing(getBytes(100), getBytes(100), "key"),
new PubKeyRing(getBytes(100), getBytes(100)),
Lists.newArrayList(),
new Date().getTime(),
getBytes(100),
@ -51,6 +51,4 @@ public class MediatorTest {
"info",
null);
}
}