wrapped-key-ring: more refactoring - no more pgp imports in KeychainIntentService!
This commit is contained in:
@@ -1,44 +1,26 @@
|
||||
package org.sufficientlysecure.keychain.pgp;
|
||||
|
||||
import org.spongycastle.openpgp.PGPSignature;
|
||||
|
||||
public abstract class CachedKeyRing {
|
||||
|
||||
private final long mMasterKeyId;
|
||||
private final int mKeySize;
|
||||
private final boolean mIsRevoked;
|
||||
private final boolean mCanCertify;
|
||||
private final long mCreation;
|
||||
private final long mExpiry;
|
||||
private final int mAlgorithm;
|
||||
private final byte[] mFingerprint;
|
||||
private final String mUserId;
|
||||
private final int mVerified;
|
||||
private final boolean mHasSecret;
|
||||
|
||||
protected CachedKeyRing(long masterKeyId, int keySize, boolean isRevoked,
|
||||
boolean canCertify, long creation, long expiry, int algorithm,
|
||||
protected CachedKeyRing(long masterKeyId, boolean canCertify,
|
||||
byte[] fingerprint, String userId, int verified, boolean hasSecret)
|
||||
{
|
||||
mMasterKeyId = masterKeyId;
|
||||
mKeySize = keySize;
|
||||
mIsRevoked = isRevoked;
|
||||
mCanCertify = canCertify;
|
||||
mCreation = creation;
|
||||
mExpiry = expiry;
|
||||
mAlgorithm = algorithm;
|
||||
mFingerprint = fingerprint;
|
||||
mUserId = userId;
|
||||
mVerified = verified;
|
||||
mHasSecret = hasSecret;
|
||||
}
|
||||
|
||||
public boolean isRevoked() {
|
||||
return mIsRevoked;
|
||||
}
|
||||
|
||||
public byte[] getFingerprint() {
|
||||
|
||||
return mFingerprint;
|
||||
}
|
||||
|
||||
@@ -54,4 +36,12 @@ public abstract class CachedKeyRing {
|
||||
return mVerified;
|
||||
}
|
||||
|
||||
public boolean canCertify() {
|
||||
return mCanCertify;
|
||||
}
|
||||
|
||||
public boolean hasSecret() {
|
||||
return mHasSecret;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,6 +31,10 @@ public class CachedPublicKey {
|
||||
return mKey.getKeyID();
|
||||
}
|
||||
|
||||
public boolean isRevoked() {
|
||||
return mKey.isRevoked();
|
||||
}
|
||||
|
||||
public Date getCreationTime() {
|
||||
return mKey.getCreationTime();
|
||||
}
|
||||
@@ -48,6 +52,15 @@ public class CachedPublicKey {
|
||||
return calendar.getTime();
|
||||
}
|
||||
|
||||
public boolean isExpired() {
|
||||
Date creationDate = mKey.getCreationTime();
|
||||
Date expiryDate = mKey.getValidSeconds() > 0
|
||||
? new Date(creationDate.getTime() + mKey.getValidSeconds() * 1000) : null;
|
||||
|
||||
Date now = new Date();
|
||||
return creationDate.after(now) || (expiryDate != null && expiryDate.before(now));
|
||||
}
|
||||
|
||||
public boolean isMasterKey() {
|
||||
return mKey.isMasterKey();
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package org.sufficientlysecure.keychain.pgp;
|
||||
|
||||
import org.spongycastle.bcpg.ArmoredOutputStream;
|
||||
import org.spongycastle.bcpg.SignatureSubpacketTags;
|
||||
import org.spongycastle.bcpg.sig.KeyFlags;
|
||||
import org.spongycastle.openpgp.PGPException;
|
||||
import org.spongycastle.openpgp.PGPPublicKey;
|
||||
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
||||
@@ -17,7 +16,6 @@ import org.sufficientlysecure.keychain.util.IterableIterator;
|
||||
import java.io.IOException;
|
||||
import java.security.SignatureException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
|
||||
public class CachedPublicKeyRing extends CachedKeyRing {
|
||||
@@ -30,8 +28,7 @@ public class CachedPublicKeyRing extends CachedKeyRing {
|
||||
byte[] fingerprint, String userId, int verified, boolean hasSecret,
|
||||
byte[] pubkey)
|
||||
{
|
||||
super(masterKeyId, keySize, isRevoked, canCertify, creation, expiry,
|
||||
algorithm, fingerprint, userId, verified, hasSecret);
|
||||
super(masterKeyId, canCertify, fingerprint, userId, verified, hasSecret);
|
||||
|
||||
mPubKey = pubkey;
|
||||
}
|
||||
@@ -55,24 +52,46 @@ public class CachedPublicKeyRing extends CachedKeyRing {
|
||||
return new CachedPublicKey(this, getRing().getPublicKey(id));
|
||||
}
|
||||
|
||||
public CachedPublicKey getFirstEncryptSubkey() throws PgpGeneralException {
|
||||
// only return master key if no other encryption key is available
|
||||
PGPPublicKey masterKey = null;
|
||||
for (PGPPublicKey key : new IterableIterator<PGPPublicKey>(getRing().getPublicKeys())) {
|
||||
if (key.isRevoked() || !isEncryptionKey(key) || isExpired(key)) {
|
||||
public CachedPublicKey getFirstSignSubkey() throws PgpGeneralException {
|
||||
// only return master key if no other signing key is available
|
||||
CachedPublicKey masterKey = null;
|
||||
for (PGPPublicKey k : new IterableIterator<PGPPublicKey>(getRing().getPublicKeys())) {
|
||||
CachedPublicKey key = new CachedPublicKey(this, k);
|
||||
if (key.isRevoked() || key.canSign() || key.isExpired()) {
|
||||
continue;
|
||||
}
|
||||
if (key.isMasterKey()) {
|
||||
masterKey = key;
|
||||
} else {
|
||||
return new CachedPublicKey(this, key);
|
||||
return key;
|
||||
}
|
||||
}
|
||||
if(masterKey == null) {
|
||||
// TODO proper exception
|
||||
throw new PgpGeneralException("key not found");
|
||||
}
|
||||
return new CachedPublicKey(this, masterKey);
|
||||
return masterKey;
|
||||
}
|
||||
|
||||
public CachedPublicKey getFirstEncryptSubkey() throws PgpGeneralException {
|
||||
// only return master key if no other encryption key is available
|
||||
CachedPublicKey masterKey = null;
|
||||
for (PGPPublicKey k : new IterableIterator<PGPPublicKey>(getRing().getPublicKeys())) {
|
||||
CachedPublicKey key = new CachedPublicKey(this, k);
|
||||
if (key.isRevoked() || key.canEncrypt() || key.isExpired()) {
|
||||
continue;
|
||||
}
|
||||
if (key.isMasterKey()) {
|
||||
masterKey = key;
|
||||
} else {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
if(masterKey == null) {
|
||||
// TODO proper exception
|
||||
throw new PgpGeneralException("key not found");
|
||||
}
|
||||
return masterKey;
|
||||
}
|
||||
|
||||
public boolean verifySubkeyBinding(CachedPublicKey cachedSubkey) {
|
||||
@@ -132,55 +151,6 @@ public class CachedPublicKeyRing extends CachedKeyRing {
|
||||
|
||||
}
|
||||
|
||||
static boolean isEncryptionKey(PGPPublicKey key) {
|
||||
if (!key.isEncryptionKey()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (key.getVersion() <= 3) {
|
||||
// this must be true now
|
||||
return key.isEncryptionKey();
|
||||
}
|
||||
|
||||
// special cases
|
||||
if (key.getAlgorithm() == PGPPublicKey.ELGAMAL_ENCRYPT) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (key.getAlgorithm() == PGPPublicKey.RSA_ENCRYPT) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (PGPSignature sig : new IterableIterator<PGPSignature>(key.getSignatures())) {
|
||||
if (key.isMasterKey() && sig.getKeyID() != key.getKeyID()) {
|
||||
continue;
|
||||
}
|
||||
PGPSignatureSubpacketVector hashed = sig.getHashedSubPackets();
|
||||
|
||||
if (hashed != null
|
||||
&& (hashed.getKeyFlags() & (KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE)) != 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
PGPSignatureSubpacketVector unhashed = sig.getUnhashedSubPackets();
|
||||
|
||||
if (unhashed != null
|
||||
&& (unhashed.getKeyFlags() & (KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE)) != 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static boolean isExpired(PGPPublicKey key) {
|
||||
Date creationDate = key.getCreationTime();
|
||||
Date expiryDate = key.getValidSeconds() > 0
|
||||
? new Date(creationDate.getTime() + key.getValidSeconds() * 1000) : null;
|
||||
|
||||
Date now = new Date();
|
||||
return creationDate.after(now) || (expiryDate != null && expiryDate.before(now));
|
||||
}
|
||||
|
||||
static boolean verifyPrimaryKeyBinding(PGPSignatureSubpacketVector pkts,
|
||||
PGPPublicKey masterPublicKey,
|
||||
PGPPublicKey signingPublicKey) {
|
||||
|
||||
@@ -9,9 +9,14 @@ import org.spongycastle.openpgp.PGPSecretKeyRing;
|
||||
import org.spongycastle.openpgp.PGPSignature;
|
||||
import org.spongycastle.openpgp.PGPSignatureSubpacketVector;
|
||||
import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyEncryptorBuilder;
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.util.IterableIterator;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.NoSuchProviderException;
|
||||
import java.util.Iterator;
|
||||
|
||||
public class CachedSecretKeyRing extends CachedKeyRing {
|
||||
@@ -23,12 +28,15 @@ public class CachedSecretKeyRing extends CachedKeyRing {
|
||||
byte[] fingerprint, String userId, int verified, boolean hasSecret,
|
||||
byte[] blob)
|
||||
{
|
||||
super(masterKeyId, keySize, isRevoked, canCertify, creation, expiry,
|
||||
algorithm, fingerprint, userId, verified, hasSecret);
|
||||
super(masterKeyId, canCertify, fingerprint, userId, verified, hasSecret);
|
||||
|
||||
mRing = (PGPSecretKeyRing) PgpConversionHelper.BytesToPGPKeyRing(blob);
|
||||
}
|
||||
|
||||
PGPSecretKeyRing getRing() {
|
||||
return mRing;
|
||||
}
|
||||
|
||||
public CachedSecretKey getSubKey() {
|
||||
return new CachedSecretKey(this, mRing.getSecretKey());
|
||||
}
|
||||
@@ -110,4 +118,27 @@ public class CachedSecretKeyRing extends CachedKeyRing {
|
||||
return false;
|
||||
}
|
||||
|
||||
public UncachedSecretKeyRing changeSecretKeyPassphrase(String oldPassphrase,
|
||||
String newPassphrase)
|
||||
throws IOException, PGPException, NoSuchProviderException {
|
||||
|
||||
if (oldPassphrase == null) {
|
||||
oldPassphrase = "";
|
||||
}
|
||||
if (newPassphrase == null) {
|
||||
newPassphrase = "";
|
||||
}
|
||||
|
||||
PGPSecretKeyRing newKeyRing = PGPSecretKeyRing.copyWithNewPassword(
|
||||
mRing,
|
||||
new JcePBESecretKeyDecryptorBuilder(new JcaPGPDigestCalculatorProviderBuilder()
|
||||
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build()).setProvider(
|
||||
Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(oldPassphrase.toCharArray()),
|
||||
new JcePBESecretKeyEncryptorBuilder(mRing.getSecretKey()
|
||||
.getKeyEncryptionAlgorithm()).build(newPassphrase.toCharArray()));
|
||||
|
||||
return new UncachedSecretKeyRing(newKeyRing);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -165,36 +165,4 @@ public class PgpConversionHelper {
|
||||
return os.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert from PGPSecretKey to byte[]
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public static byte[] PGPSecretKeyToBytes(PGPSecretKey key) {
|
||||
try {
|
||||
return key.getEncoded();
|
||||
} catch (IOException e) {
|
||||
Log.e(Constants.TAG, "Encoding failed", e);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert from PGPSecretKeyRing to byte[]
|
||||
*
|
||||
* @param keyRing
|
||||
* @return
|
||||
*/
|
||||
public static byte[] PGPSecretKeyRingToBytes(PGPSecretKeyRing keyRing) {
|
||||
try {
|
||||
return keyRing.getEncoded();
|
||||
} catch (IOException e) {
|
||||
Log.e(Constants.TAG, "Encoding failed", e);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -277,7 +277,7 @@ public class PgpImportExport {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public int storeKeyRingInCache(UncachedKeyRing keyring) {
|
||||
int status = RETURN_ERROR;
|
||||
int status;
|
||||
try {
|
||||
PGPSecretKeyRing secretKeyRing = keyring.getSecretRing();
|
||||
PGPPublicKeyRing publicKeyRing = keyring.getPublicRing();
|
||||
|
||||
@@ -81,18 +81,6 @@ public class PgpKeyHelper {
|
||||
return getExpiryDate(key.getPublicKey());
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static boolean isExpired(PGPPublicKey key) {
|
||||
Date creationDate = getCreationDate(key);
|
||||
Date expiryDate = getExpiryDate(key);
|
||||
Date now = new Date();
|
||||
if (now.compareTo(creationDate) >= 0
|
||||
&& (expiryDate == null || now.compareTo(expiryDate) <= 0)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Deprecated
|
||||
public static PGPSecretKey getKeyNum(PGPSecretKeyRing keyRing, long num) {
|
||||
@@ -110,48 +98,6 @@ public class PgpKeyHelper {
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Deprecated
|
||||
private static Vector<PGPSecretKey> getSigningKeys(PGPSecretKeyRing keyRing) {
|
||||
Vector<PGPSecretKey> signingKeys = new Vector<PGPSecretKey>();
|
||||
|
||||
for (PGPSecretKey key : new IterableIterator<PGPSecretKey>(keyRing.getSecretKeys())) {
|
||||
if (isSigningKey(key)) {
|
||||
signingKeys.add(key);
|
||||
}
|
||||
}
|
||||
|
||||
return signingKeys;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
private static Vector<PGPSecretKey> getUsableSigningKeys(PGPSecretKeyRing keyRing) {
|
||||
Vector<PGPSecretKey> usableKeys = new Vector<PGPSecretKey>();
|
||||
Vector<PGPSecretKey> signingKeys = getSigningKeys(keyRing);
|
||||
PGPSecretKey masterKey = null;
|
||||
for (int i = 0; i < signingKeys.size(); ++i) {
|
||||
PGPSecretKey key = signingKeys.get(i);
|
||||
if (key.isMasterKey()) {
|
||||
masterKey = key;
|
||||
} else {
|
||||
usableKeys.add(key);
|
||||
}
|
||||
}
|
||||
if (masterKey != null) {
|
||||
usableKeys.add(masterKey);
|
||||
}
|
||||
return usableKeys;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static PGPSecretKey getFirstSigningSubkey(PGPSecretKeyRing keyRing) {
|
||||
Vector<PGPSecretKey> signingKeys = getUsableSigningKeys(keyRing);
|
||||
if (signingKeys.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
return signingKeys.get(0);
|
||||
}
|
||||
|
||||
public static int getKeyUsage(PGPSecretKey key) {
|
||||
return getKeyUsage(key.getPublicKey());
|
||||
}
|
||||
|
||||
@@ -35,7 +35,6 @@ import org.spongycastle.openpgp.PGPSecretKeyRing;
|
||||
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.operator.PBESecretKeyDecryptor;
|
||||
import org.spongycastle.openpgp.operator.PBESecretKeyEncryptor;
|
||||
@@ -48,10 +47,8 @@ import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyEncryptorBuilder;
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.pgp.Progressable;
|
||||
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralMsgIdException;
|
||||
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
|
||||
import org.sufficientlysecure.keychain.util.IterableIterator;
|
||||
import org.sufficientlysecure.keychain.util.Primes;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -66,7 +63,6 @@ import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.TimeZone;
|
||||
|
||||
/**
|
||||
@@ -124,7 +120,7 @@ public class PgpKeyOperation {
|
||||
*/
|
||||
|
||||
// TODO: key flags?
|
||||
public PGPSecretKey createKey(int algorithmChoice, int keySize, String passphrase,
|
||||
public byte[] createKey(int algorithmChoice, int keySize, String passphrase,
|
||||
boolean isMasterKey)
|
||||
throws NoSuchAlgorithmException, PGPException, NoSuchProviderException,
|
||||
PgpGeneralMsgIdException, InvalidAlgorithmParameterException {
|
||||
@@ -188,35 +184,15 @@ public class PgpKeyOperation {
|
||||
PGPEncryptedData.CAST5, sha1Calc)
|
||||
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(passphrase.toCharArray());
|
||||
|
||||
return new PGPSecretKey(keyPair.getPrivateKey(), keyPair.getPublicKey(),
|
||||
sha1Calc, isMasterKey, keyEncryptor);
|
||||
try {
|
||||
return new PGPSecretKey(keyPair.getPrivateKey(), keyPair.getPublicKey(),
|
||||
sha1Calc, isMasterKey, keyEncryptor).getEncoded();
|
||||
} catch(IOException e) {
|
||||
throw new PgpGeneralMsgIdException(R.string.error_encoding);
|
||||
}
|
||||
}
|
||||
|
||||
public PGPSecretKeyRing changeSecretKeyPassphrase(PGPSecretKeyRing keyRing, String oldPassphrase,
|
||||
String newPassphrase)
|
||||
throws IOException, PGPException, NoSuchProviderException {
|
||||
|
||||
updateProgress(R.string.progress_building_key, 0, 100);
|
||||
if (oldPassphrase == null) {
|
||||
oldPassphrase = "";
|
||||
}
|
||||
if (newPassphrase == null) {
|
||||
newPassphrase = "";
|
||||
}
|
||||
|
||||
PGPSecretKeyRing newKeyRing = PGPSecretKeyRing.copyWithNewPassword(
|
||||
keyRing,
|
||||
new JcePBESecretKeyDecryptorBuilder(new JcaPGPDigestCalculatorProviderBuilder()
|
||||
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build()).setProvider(
|
||||
Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(oldPassphrase.toCharArray()),
|
||||
new JcePBESecretKeyEncryptorBuilder(keyRing.getSecretKey()
|
||||
.getKeyEncryptionAlgorithm()).build(newPassphrase.toCharArray()));
|
||||
|
||||
return newKeyRing;
|
||||
|
||||
}
|
||||
|
||||
public Pair<PGPSecretKeyRing, PGPPublicKeyRing> buildNewSecretKey(
|
||||
public UncachedKeyRing buildNewSecretKey(
|
||||
SaveKeyringParcel saveParcel)
|
||||
throws PgpGeneralMsgIdException, PGPException, SignatureException, IOException {
|
||||
|
||||
@@ -357,17 +333,19 @@ public class PgpKeyOperation {
|
||||
PGPSecretKeyRing secretKeyRing = keyGen.generateSecretKeyRing();
|
||||
PGPPublicKeyRing publicKeyRing = keyGen.generatePublicKeyRing();
|
||||
|
||||
return new Pair<PGPSecretKeyRing, PGPPublicKeyRing>(secretKeyRing, publicKeyRing);
|
||||
return new UncachedKeyRing(publicKeyRing, secretKeyRing);
|
||||
|
||||
}
|
||||
|
||||
public Pair<PGPSecretKeyRing, PGPPublicKeyRing> buildSecretKey(PGPSecretKeyRing mKR,
|
||||
PGPPublicKeyRing pKR,
|
||||
public UncachedKeyRing buildSecretKey(CachedSecretKeyRing wmKR,
|
||||
CachedPublicKeyRing wpKR,
|
||||
SaveKeyringParcel saveParcel)
|
||||
throws PgpGeneralMsgIdException, PGPException, SignatureException, IOException {
|
||||
|
||||
PGPSecretKeyRing mKR = wmKR.getRing();
|
||||
PGPPublicKeyRing pKR = wpKR.getRing();
|
||||
|
||||
updateProgress(R.string.progress_building_key, 0, 100);
|
||||
PGPSecretKey masterKey = saveParcel.keys.get(0);
|
||||
|
||||
if (saveParcel.oldPassphrase == null) {
|
||||
saveParcel.oldPassphrase = "";
|
||||
@@ -404,7 +382,7 @@ public class PgpKeyOperation {
|
||||
}
|
||||
}
|
||||
|
||||
masterKey = mKR.getSecretKey();
|
||||
PGPSecretKey masterKey = mKR.getSecretKey();
|
||||
PGPPublicKey masterPublicKey = masterKey.getPublicKey();
|
||||
|
||||
int usageId = saveParcel.keysUsages.get(0);
|
||||
@@ -686,7 +664,7 @@ public class PgpKeyOperation {
|
||||
|
||||
*/
|
||||
|
||||
return new Pair<PGPSecretKeyRing, PGPPublicKeyRing>(mKR, pKR);
|
||||
return new UncachedKeyRing(pKR, mKR);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,15 @@
|
||||
package org.sufficientlysecure.keychain.pgp;
|
||||
|
||||
import org.spongycastle.openpgp.PGPObjectFactory;
|
||||
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
||||
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
||||
import org.spongycastle.openpgp.PGPUtil;
|
||||
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class UncachedKeyRing {
|
||||
|
||||
@@ -9,8 +17,6 @@ public class UncachedKeyRing {
|
||||
final PGPSecretKeyRing mSecretRing;
|
||||
|
||||
UncachedKeyRing(PGPPublicKeyRing publicRing, PGPSecretKeyRing secretRing) {
|
||||
// this one must not be false!
|
||||
assert(publicRing != null);
|
||||
mPublicRing = publicRing;
|
||||
mSecretRing = secretRing;
|
||||
}
|
||||
@@ -26,4 +32,29 @@ public class UncachedKeyRing {
|
||||
public PGPSecretKeyRing getSecretRing() {
|
||||
return mSecretRing;
|
||||
}
|
||||
|
||||
public byte[] getFingerprint() {
|
||||
return mPublicRing.getPublicKey().getFingerprint();
|
||||
}
|
||||
|
||||
public static UncachedKeyRing decodePubkeyFromData(byte[] data)
|
||||
throws PgpGeneralException, IOException {
|
||||
BufferedInputStream bufferedInput =
|
||||
new BufferedInputStream(new ByteArrayInputStream(data));
|
||||
if (bufferedInput.available() > 0) {
|
||||
InputStream in = PGPUtil.getDecoderStream(bufferedInput);
|
||||
PGPObjectFactory objectFactory = new PGPObjectFactory(in);
|
||||
|
||||
// get first object in block
|
||||
Object obj;
|
||||
if ((obj = objectFactory.nextObject()) != null && obj instanceof PGPPublicKeyRing) {
|
||||
return new UncachedKeyRing((PGPPublicKeyRing) obj);
|
||||
} else {
|
||||
throw new PgpGeneralException("Object not recognized as PGPPublicKeyRing!");
|
||||
}
|
||||
} else {
|
||||
throw new PgpGeneralException("Object not recognized as PGPPublicKeyRing!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package org.sufficientlysecure.keychain.pgp;
|
||||
|
||||
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
||||
|
||||
public class UncachedSecretKeyRing {
|
||||
|
||||
final PGPSecretKeyRing mSecretRing;
|
||||
|
||||
UncachedSecretKeyRing(PGPSecretKeyRing secretRing) {
|
||||
mSecretRing = secretRing;
|
||||
}
|
||||
|
||||
// Breaking the pattern here, for key import!
|
||||
// TODO reduce this from public to default visibility!
|
||||
public PGPSecretKeyRing getSecretKeyRing() {
|
||||
return mSecretRing;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user