aboutsummaryrefslogtreecommitdiffstats
path: root/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp
diff options
context:
space:
mode:
Diffstat (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp')
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CachedPublicKeyRing.java7
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CachedSecretKey.java58
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CachedSecretKeyRing.java6
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java69
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java53
5 files changed, 97 insertions, 96 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CachedPublicKeyRing.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CachedPublicKeyRing.java
index fb142adce..3a45b4ff9 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CachedPublicKeyRing.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CachedPublicKeyRing.java
@@ -36,7 +36,7 @@ public class CachedPublicKeyRing extends CachedKeyRing {
mPubKey = pubkey;
}
- private PGPPublicKeyRing getRing() {
+ PGPPublicKeyRing getRing() {
if(mRing == null) {
mRing = (PGPPublicKeyRing) PgpConversionHelper.BytesToPGPKeyRing(mPubKey);
}
@@ -47,6 +47,10 @@ public class CachedPublicKeyRing extends CachedKeyRing {
getRing().encode(stream);
}
+ public CachedPublicKey getSubkey() {
+ return new CachedPublicKey(this, getRing().getPublicKey());
+ }
+
public CachedPublicKey getSubkey(long id) {
return new CachedPublicKey(this, getRing().getPublicKey(id));
}
@@ -128,7 +132,6 @@ public class CachedPublicKeyRing extends CachedKeyRing {
}
-
static boolean isEncryptionKey(PGPPublicKey key) {
if (!key.isEncryptionKey()) {
return false;
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CachedSecretKey.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CachedSecretKey.java
index 514fca6fb..ea302ea0b 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CachedSecretKey.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CachedSecretKey.java
@@ -2,10 +2,14 @@ package org.sufficientlysecure.keychain.pgp;
import org.spongycastle.openpgp.PGPException;
import org.spongycastle.openpgp.PGPPrivateKey;
+import org.spongycastle.openpgp.PGPPublicKey;
+import org.spongycastle.openpgp.PGPPublicKeyRing;
import org.spongycastle.openpgp.PGPSecretKey;
import org.spongycastle.openpgp.PGPSignature;
import org.spongycastle.openpgp.PGPSignatureGenerator;
import org.spongycastle.openpgp.PGPSignatureSubpacketGenerator;
+import org.spongycastle.openpgp.PGPSignatureSubpacketVector;
+import org.spongycastle.openpgp.PGPUtil;
import org.spongycastle.openpgp.PGPV3SignatureGenerator;
import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor;
import org.spongycastle.openpgp.operator.PublicKeyDataDecryptorFactory;
@@ -14,6 +18,13 @@ import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
import org.spongycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
+import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralMsgIdException;
+import org.sufficientlysecure.keychain.util.IterableIterator;
+
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.SignatureException;
+import java.util.List;
public class CachedSecretKey {
@@ -113,6 +124,53 @@ public class CachedSecretKey {
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(mPrivateKey);
}
+ /**
+ * Certify the given pubkeyid with the given masterkeyid.
+ *
+ * @param publicKeyRing Keyring to add certification to.
+ * @param userIds User IDs to certify, must not be null or empty
+ * @return A keyring with added certifications
+ */
+ public UncachedKeyRing certifyUserIds(CachedPublicKeyRing publicKeyRing, List<String> userIds)
+ throws PgpGeneralMsgIdException, NoSuchAlgorithmException, NoSuchProviderException,
+ PGPException, SignatureException {
+
+ if(mPrivateKey == null) {
+ throw new PrivateKeyNotUnlockedException();
+ }
+
+ // create a signatureGenerator from the supplied masterKeyId and passphrase
+ PGPSignatureGenerator signatureGenerator;
+ {
+ // TODO: SHA256 fixed?
+ JcaPGPContentSignerBuilder contentSignerBuilder = new JcaPGPContentSignerBuilder(
+ mKey.getPublicKey().getAlgorithm(), PGPUtil.SHA256)
+ .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
+
+ signatureGenerator = new PGPSignatureGenerator(contentSignerBuilder);
+ signatureGenerator.init(PGPSignature.DEFAULT_CERTIFICATION, mPrivateKey);
+ }
+
+ { // supply signatureGenerator with a SubpacketVector
+ PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator();
+ PGPSignatureSubpacketVector packetVector = spGen.generate();
+ signatureGenerator.setHashedSubpackets(packetVector);
+ }
+
+ // get the master subkey (which we certify for)
+ PGPPublicKey publicKey = publicKeyRing.getSubkey().getKey();
+
+ // fetch public key ring, add the certification and return it
+ for (String userId : new IterableIterator<String>(userIds.iterator())) {
+ PGPSignature sig = signatureGenerator.generateCertification(userId, publicKey);
+ publicKey = PGPPublicKey.addCertification(publicKey, userId, sig);
+ }
+
+ PGPPublicKeyRing ring = PGPPublicKeyRing.insertPublicKey(publicKeyRing.getRing(), publicKey);
+
+ return new UncachedKeyRing(ring);
+ }
+
static class PrivateKeyNotUnlockedException extends RuntimeException {
// this exception is a programming error which happens when an operation which requires
// the private key is called without a previous call to unlock()
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CachedSecretKeyRing.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CachedSecretKeyRing.java
index a2b2b2832..5403e1510 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CachedSecretKeyRing.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CachedSecretKeyRing.java
@@ -23,7 +23,11 @@ public class CachedSecretKeyRing extends CachedKeyRing {
mRing = (PGPSecretKeyRing) PgpConversionHelper.BytesToPGPKeyRing(blob);
}
- CachedSecretKey getSubKey(long id) {
+ public CachedSecretKey getSubKey() {
+ return new CachedSecretKey(this, mRing.getSecretKey());
+ }
+
+ public CachedSecretKey getSubKey(long id) {
return new CachedSecretKey(this, mRing.getSecretKey(id));
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java
index 6aeb19e65..6de958d8d 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java
@@ -97,12 +97,12 @@ public class PgpImportExport {
}
}
- public boolean uploadKeyRingToServer(HkpKeyServer server, PGPPublicKeyRing keyring) {
+ public boolean uploadKeyRingToServer(HkpKeyServer server, CachedPublicKeyRing keyring) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ArmoredOutputStream aos = null;
try {
aos = new ArmoredOutputStream(bos);
- aos.write(keyring.getEncoded());
+ keyring.encode(aos);
aos.close();
String armoredKey = bos.toString("UTF-8");
@@ -147,8 +147,25 @@ public class PgpImportExport {
if (obj instanceof PGPKeyRing) {
PGPKeyRing keyring = (PGPKeyRing) obj;
-
- int status = storeKeyRingInCache(keyring);
+ int status;
+ // TODO Better try to get this one from the db first!
+ if(keyring instanceof PGPSecretKeyRing) {
+ PGPSecretKeyRing secretKeyRing = (PGPSecretKeyRing) keyring;
+ // TODO: preserve certifications
+ // (http://osdir.com/ml/encryption.bouncy-castle.devel/2007-01/msg00054.html ?)
+ PGPPublicKeyRing newPubRing = null;
+ for (PGPPublicKey key : new IterableIterator<PGPPublicKey>(
+ secretKeyRing.getPublicKeys())) {
+ if (newPubRing == null) {
+ newPubRing = new PGPPublicKeyRing(key.getEncoded(),
+ new JcaKeyFingerprintCalculator());
+ }
+ newPubRing = PGPPublicKeyRing.insertPublicKey(newPubRing, key);
+ }
+ status = storeKeyRingInCache(new UncachedKeyRing(newPubRing ,secretKeyRing));
+ } else {
+ status = storeKeyRingInCache(new UncachedKeyRing((PGPPublicKeyRing) keyring));
+ }
if (status == RETURN_ERROR) {
throw new PgpGeneralException(
@@ -259,44 +276,16 @@ public class PgpImportExport {
}
@SuppressWarnings("unchecked")
- public int storeKeyRingInCache(PGPKeyRing keyring) {
+ public int storeKeyRingInCache(UncachedKeyRing keyring) {
int status = RETURN_ERROR;
try {
- if (keyring instanceof PGPSecretKeyRing) {
- PGPSecretKeyRing secretKeyRing = (PGPSecretKeyRing) keyring;
- boolean save = true;
-
- for (PGPSecretKey testSecretKey : new IterableIterator<PGPSecretKey>(
- secretKeyRing.getSecretKeys())) {
- if (!testSecretKey.isMasterKey()) {
- if (testSecretKey.isPrivateKeyEmpty()) {
- // this is bad, something is very wrong...
- save = false;
- status = RETURN_BAD;
- }
- }
- }
-
- if (save) {
- // TODO: preserve certifications
- // (http://osdir.com/ml/encryption.bouncy-castle.devel/2007-01/msg00054.html ?)
- PGPPublicKeyRing newPubRing = null;
- for (PGPPublicKey key : new IterableIterator<PGPPublicKey>(
- secretKeyRing.getPublicKeys())) {
- if (newPubRing == null) {
- newPubRing = new PGPPublicKeyRing(key.getEncoded(),
- new JcaKeyFingerprintCalculator());
- }
- newPubRing = PGPPublicKeyRing.insertPublicKey(newPubRing, key);
- }
- if (newPubRing != null) {
- mProviderHelper.saveKeyRing(newPubRing);
- }
- mProviderHelper.saveKeyRing(secretKeyRing);
- status = RETURN_OK;
- }
- } else if (keyring instanceof PGPPublicKeyRing) {
- PGPPublicKeyRing publicKeyRing = (PGPPublicKeyRing) keyring;
+ PGPSecretKeyRing secretKeyRing = keyring.getSecretRing();
+ PGPPublicKeyRing publicKeyRing = keyring.getPublicRing();
+ // see what type we have. we can either have a secret + public keyring, or just public
+ if (secretKeyRing != null) {
+ mProviderHelper.saveKeyRing(publicKeyRing, secretKeyRing);
+ status = RETURN_OK;
+ } else {
mProviderHelper.saveKeyRing(publicKeyRing);
status = RETURN_OK;
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java
index 9dd9f660b..2033a91e7 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java
@@ -691,59 +691,6 @@ public class PgpKeyOperation {
}
/**
- * Certify the given pubkeyid with the given masterkeyid.
- *
- * @param certificationKey Certifying key
- * @param publicKey public key to certify
- * @param userIds User IDs to certify, must not be null or empty
- * @param passphrase Passphrase of the secret key
- * @return A keyring with added certifications
- */
- public PGPPublicKey certifyKey(PGPSecretKey certificationKey, PGPPublicKey publicKey,
- List<String> userIds, String passphrase)
- throws PgpGeneralMsgIdException, NoSuchAlgorithmException, NoSuchProviderException,
- PGPException, SignatureException {
-
- // create a signatureGenerator from the supplied masterKeyId and passphrase
- PGPSignatureGenerator signatureGenerator;
- {
-
- if (certificationKey == null) {
- throw new PgpGeneralMsgIdException(R.string.error_no_signature_key);
- }
-
- PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(
- Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(passphrase.toCharArray());
- PGPPrivateKey signaturePrivateKey = certificationKey.extractPrivateKey(keyDecryptor);
- if (signaturePrivateKey == null) {
- throw new PgpGeneralMsgIdException(R.string.error_could_not_extract_private_key);
- }
-
- // TODO: SHA256 fixed?
- JcaPGPContentSignerBuilder contentSignerBuilder = new JcaPGPContentSignerBuilder(
- certificationKey.getPublicKey().getAlgorithm(), PGPUtil.SHA256)
- .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
-
- signatureGenerator = new PGPSignatureGenerator(contentSignerBuilder);
- signatureGenerator.init(PGPSignature.DEFAULT_CERTIFICATION, signaturePrivateKey);
- }
-
- { // supply signatureGenerator with a SubpacketVector
- PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator();
- PGPSignatureSubpacketVector packetVector = spGen.generate();
- signatureGenerator.setHashedSubpackets(packetVector);
- }
-
- // fetch public key ring, add the certification and return it
- for (String userId : new IterableIterator<String>(userIds.iterator())) {
- PGPSignature sig = signatureGenerator.generateCertification(userId, publicKey);
- publicKey = PGPPublicKey.addCertification(publicKey, userId, sig);
- }
-
- return publicKey;
- }
-
- /**
* Simple static subclass that stores two values.
* <p/>
* This is only used to return a pair of values in one function above. We specifically don't use