mirror of
https://github.com/moparisthebest/open-keychain
synced 2025-02-19 20:31:52 -05:00
Put PgpMain methods in separate opbject classes, handle passphrase dialog in EditKey not in SecretKeyList
This commit is contained in:
parent
121f8aaca0
commit
5aebd115d4
@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package org.sufficientlysecure.keychain;
|
package org.sufficientlysecure.keychain;
|
||||||
|
|
||||||
|
import org.spongycastle.jce.provider.BouncyCastleProvider;
|
||||||
|
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
|
|
||||||
public final class Constants {
|
public final class Constants {
|
||||||
@ -29,6 +31,10 @@ public final class Constants {
|
|||||||
// as defined in http://tools.ietf.org/html/rfc3156, section 7
|
// as defined in http://tools.ietf.org/html/rfc3156, section 7
|
||||||
public static final String NFC_MIME = "application/pgp-keys";
|
public static final String NFC_MIME = "application/pgp-keys";
|
||||||
|
|
||||||
|
// Not BC due to the use of Spongy Castle for Android
|
||||||
|
public static final String SC = BouncyCastleProvider.PROVIDER_NAME;
|
||||||
|
public static final String BOUNCY_CASTLE_PROVIDER_NAME = SC;
|
||||||
|
|
||||||
public static final String INTENT_PREFIX = PACKAGE_NAME + ".action.";
|
public static final String INTENT_PREFIX = PACKAGE_NAME + ".action.";
|
||||||
|
|
||||||
public static final class path {
|
public static final class path {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2012 Dominik Schürmann <dominik@dominikschuermann.de>
|
* Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
|
||||||
* Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
|
* Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -17,494 +17,203 @@
|
|||||||
|
|
||||||
package org.sufficientlysecure.keychain.pgp;
|
package org.sufficientlysecure.keychain.pgp;
|
||||||
|
|
||||||
import java.util.Calendar;
|
import java.io.File;
|
||||||
import java.util.Date;
|
import java.io.FileNotFoundException;
|
||||||
import java.util.GregorianCalendar;
|
import java.io.IOException;
|
||||||
import java.util.Locale;
|
import java.io.InputStream;
|
||||||
import java.util.Vector;
|
import java.io.RandomAccessFile;
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import org.spongycastle.bcpg.sig.KeyFlags;
|
import org.spongycastle.openpgp.PGPEncryptedDataList;
|
||||||
import org.spongycastle.openpgp.PGPPublicKey;
|
import org.spongycastle.openpgp.PGPObjectFactory;
|
||||||
|
import org.spongycastle.openpgp.PGPPublicKeyEncryptedData;
|
||||||
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
||||||
import org.spongycastle.openpgp.PGPSecretKey;
|
import org.spongycastle.openpgp.PGPSecretKey;
|
||||||
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
||||||
import org.spongycastle.openpgp.PGPSignature;
|
import org.spongycastle.openpgp.PGPUtil;
|
||||||
import org.spongycastle.openpgp.PGPSignatureSubpacketVector;
|
|
||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
|
import org.sufficientlysecure.keychain.Id;
|
||||||
import org.sufficientlysecure.keychain.R;
|
import org.sufficientlysecure.keychain.R;
|
||||||
|
import org.sufficientlysecure.keychain.pgp.exception.NoAsymmetricEncryptionException;
|
||||||
|
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
|
||||||
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||||
import org.sufficientlysecure.keychain.util.IterableIterator;
|
|
||||||
import org.sufficientlysecure.keychain.util.Log;
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
|
import org.sufficientlysecure.keychain.util.ProgressDialogUpdater;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.pm.PackageInfo;
|
||||||
|
import android.content.pm.PackageManager.NameNotFoundException;
|
||||||
|
|
||||||
public class PgpHelper {
|
public class PgpHelper {
|
||||||
|
|
||||||
public static Date getCreationDate(PGPPublicKey key) {
|
public static Pattern PGP_MESSAGE = Pattern.compile(
|
||||||
return key.getCreationTime();
|
".*?(-----BEGIN PGP MESSAGE-----.*?-----END PGP MESSAGE-----).*", Pattern.DOTALL);
|
||||||
|
|
||||||
|
public static Pattern PGP_SIGNED_MESSAGE = Pattern
|
||||||
|
.compile(
|
||||||
|
".*?(-----BEGIN PGP SIGNED MESSAGE-----.*?-----BEGIN PGP SIGNATURE-----.*?-----END PGP SIGNATURE-----).*",
|
||||||
|
Pattern.DOTALL);
|
||||||
|
|
||||||
|
public static Pattern PGP_PUBLIC_KEY = Pattern.compile(
|
||||||
|
".*?(-----BEGIN PGP PUBLIC KEY BLOCK-----.*?-----END PGP PUBLIC KEY BLOCK-----).*",
|
||||||
|
Pattern.DOTALL);
|
||||||
|
|
||||||
|
public static String getVersion(Context context) {
|
||||||
|
String version = null;
|
||||||
|
try {
|
||||||
|
PackageInfo pi = context.getPackageManager().getPackageInfo(Constants.PACKAGE_NAME, 0);
|
||||||
|
version = pi.versionName;
|
||||||
|
return version;
|
||||||
|
} catch (NameNotFoundException e) {
|
||||||
|
Log.e(Constants.TAG, "Version could not be retrieved!", e);
|
||||||
|
return "0.0.0";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Date getCreationDate(PGPSecretKey key) {
|
public static String getFullVersion(Context context) {
|
||||||
return key.getPublicKey().getCreationTime();
|
return "OpenPGP Keychain v" + getVersion(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
public static long getDecryptionKeyId(Context context, InputStream inputStream)
|
||||||
public static PGPPublicKey getMasterKey(PGPPublicKeyRing keyRing) {
|
throws PgpGeneralException, NoAsymmetricEncryptionException, IOException {
|
||||||
if (keyRing == null) {
|
InputStream in = PGPUtil.getDecoderStream(inputStream);
|
||||||
return null;
|
PGPObjectFactory pgpF = new PGPObjectFactory(in);
|
||||||
}
|
PGPEncryptedDataList enc;
|
||||||
for (PGPPublicKey key : new IterableIterator<PGPPublicKey>(keyRing.getPublicKeys())) {
|
Object o = pgpF.nextObject();
|
||||||
if (key.isMasterKey()) {
|
|
||||||
return key;
|
// the first object might be a PGP marker packet.
|
||||||
}
|
if (o instanceof PGPEncryptedDataList) {
|
||||||
|
enc = (PGPEncryptedDataList) o;
|
||||||
|
} else {
|
||||||
|
enc = (PGPEncryptedDataList) pgpF.nextObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
if (enc == null) {
|
||||||
}
|
throw new PgpGeneralException(context.getString(R.string.error_invalidData));
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public static PGPSecretKey getMasterKey(PGPSecretKeyRing keyRing) {
|
|
||||||
if (keyRing == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
for (PGPSecretKey key : new IterableIterator<PGPSecretKey>(keyRing.getSecretKeys())) {
|
|
||||||
if (key.isMasterKey()) {
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
// TODO: currently we always only look at the first known key
|
||||||
}
|
// find the secret key
|
||||||
|
PGPSecretKey secretKey = null;
|
||||||
@SuppressWarnings("unchecked")
|
Iterator<?> it = enc.getEncryptedDataObjects();
|
||||||
public static PGPSecretKey getKeyNum(PGPSecretKeyRing keyRing, long num) {
|
boolean gotAsymmetricEncryption = false;
|
||||||
long cnt = 0;
|
while (it.hasNext()) {
|
||||||
if (keyRing == null) {
|
Object obj = it.next();
|
||||||
return null;
|
if (obj instanceof PGPPublicKeyEncryptedData) {
|
||||||
}
|
gotAsymmetricEncryption = true;
|
||||||
for (PGPSecretKey key : new IterableIterator<PGPSecretKey>(keyRing.getSecretKeys())) {
|
PGPPublicKeyEncryptedData pbe = (PGPPublicKeyEncryptedData) obj;
|
||||||
if (cnt == num) {
|
secretKey = ProviderHelper.getPGPSecretKeyByKeyId(context, pbe.getKeyID());
|
||||||
return key;
|
if (secretKey != null) {
|
||||||
}
|
break;
|
||||||
cnt++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public static Vector<PGPPublicKey> getEncryptKeys(PGPPublicKeyRing keyRing) {
|
|
||||||
Vector<PGPPublicKey> encryptKeys = new Vector<PGPPublicKey>();
|
|
||||||
|
|
||||||
for (PGPPublicKey key : new IterableIterator<PGPPublicKey>(keyRing.getPublicKeys())) {
|
|
||||||
if (isEncryptionKey(key)) {
|
|
||||||
encryptKeys.add(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return encryptKeys;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public static Vector<PGPSecretKey> getCertificationKeys(PGPSecretKeyRing keyRing) {
|
|
||||||
Vector<PGPSecretKey> signingKeys = new Vector<PGPSecretKey>();
|
|
||||||
|
|
||||||
for (PGPSecretKey key : new IterableIterator<PGPSecretKey>(keyRing.getSecretKeys())) {
|
|
||||||
if (isCertificationKey(key)) {
|
|
||||||
signingKeys.add(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return signingKeys;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Vector<PGPPublicKey> getUsableEncryptKeys(PGPPublicKeyRing keyRing) {
|
|
||||||
Vector<PGPPublicKey> usableKeys = new Vector<PGPPublicKey>();
|
|
||||||
Vector<PGPPublicKey> encryptKeys = getEncryptKeys(keyRing);
|
|
||||||
PGPPublicKey masterKey = null;
|
|
||||||
for (int i = 0; i < encryptKeys.size(); ++i) {
|
|
||||||
PGPPublicKey key = encryptKeys.get(i);
|
|
||||||
if (!isExpired(key)) {
|
|
||||||
if (key.isMasterKey()) {
|
|
||||||
masterKey = key;
|
|
||||||
} else {
|
|
||||||
usableKeys.add(key);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (masterKey != null) {
|
|
||||||
usableKeys.add(masterKey);
|
|
||||||
}
|
|
||||||
return usableKeys;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isExpired(PGPPublicKey key) {
|
if (!gotAsymmetricEncryption) {
|
||||||
Date creationDate = getCreationDate(key);
|
throw new NoAsymmetricEncryptionException();
|
||||||
Date expiryDate = getExpiryDate(key);
|
|
||||||
Date now = new Date();
|
|
||||||
if (now.compareTo(creationDate) >= 0
|
|
||||||
&& (expiryDate == null || now.compareTo(expiryDate) <= 0)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isExpired(PGPSecretKey key) {
|
|
||||||
return isExpired(key.getPublicKey());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Vector<PGPSecretKey> getUsableCertificationKeys(PGPSecretKeyRing keyRing) {
|
|
||||||
Vector<PGPSecretKey> usableKeys = new Vector<PGPSecretKey>();
|
|
||||||
Vector<PGPSecretKey> signingKeys = getCertificationKeys(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;
|
|
||||||
}
|
|
||||||
|
|
||||||
public 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Date getExpiryDate(PGPPublicKey key) {
|
|
||||||
Date creationDate = getCreationDate(key);
|
|
||||||
if (key.getValidDays() == 0) {
|
|
||||||
// no expiry
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
Calendar calendar = GregorianCalendar.getInstance();
|
|
||||||
calendar.setTime(creationDate);
|
|
||||||
calendar.add(Calendar.DATE, key.getValidDays());
|
|
||||||
Date expiryDate = calendar.getTime();
|
|
||||||
|
|
||||||
return expiryDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Date getExpiryDate(PGPSecretKey key) {
|
|
||||||
return getExpiryDate(key.getPublicKey());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PGPPublicKey getEncryptPublicKey(Context context, long masterKeyId) {
|
|
||||||
PGPPublicKeyRing keyRing = ProviderHelper.getPGPPublicKeyRingByMasterKeyId(context,
|
|
||||||
masterKeyId);
|
|
||||||
if (keyRing == null) {
|
|
||||||
Log.e(Constants.TAG, "keyRing is null!");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
Vector<PGPPublicKey> encryptKeys = getUsableEncryptKeys(keyRing);
|
|
||||||
if (encryptKeys.size() == 0) {
|
|
||||||
Log.e(Constants.TAG, "encryptKeys is null!");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return encryptKeys.get(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PGPSecretKey getCertificationKey(Context context, long masterKeyId) {
|
|
||||||
PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(context,
|
|
||||||
masterKeyId);
|
|
||||||
if (keyRing == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
Vector<PGPSecretKey> signingKeys = getUsableCertificationKeys(keyRing);
|
|
||||||
if (signingKeys.size() == 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return signingKeys.get(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PGPSecretKey getSigningKey(Context context, long masterKeyId) {
|
|
||||||
PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(context,
|
|
||||||
masterKeyId);
|
|
||||||
if (keyRing == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
Vector<PGPSecretKey> signingKeys = getUsableSigningKeys(keyRing);
|
|
||||||
if (signingKeys.size() == 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return signingKeys.get(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public static String getMainUserId(PGPPublicKey key) {
|
|
||||||
for (String userId : new IterableIterator<String>(key.getUserIDs())) {
|
|
||||||
return userId;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public static String getMainUserId(PGPSecretKey key) {
|
|
||||||
for (String userId : new IterableIterator<String>(key.getUserIDs())) {
|
|
||||||
return userId;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getMainUserIdSafe(Context context, PGPPublicKey key) {
|
|
||||||
String userId = getMainUserId(key);
|
|
||||||
if (userId == null || userId.equals("")) {
|
|
||||||
userId = context.getString(R.string.unknownUserId);
|
|
||||||
}
|
|
||||||
return userId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getMainUserIdSafe(Context context, PGPSecretKey key) {
|
|
||||||
String userId = getMainUserId(key);
|
|
||||||
if (userId == null || userId.equals("")) {
|
|
||||||
userId = context.getString(R.string.unknownUserId);
|
|
||||||
}
|
|
||||||
return userId;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isEncryptionKey(PGPSecretKey key) {
|
|
||||||
return isEncryptionKey(key.getPublicKey());
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public static boolean isSigningKey(PGPPublicKey key) {
|
|
||||||
if (key.getVersion() <= 3) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// special case
|
|
||||||
if (key.getAlgorithm() == PGPPublicKey.RSA_SIGN) {
|
|
||||||
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.SIGN_DATA) != 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
PGPSignatureSubpacketVector unhashed = sig.getUnhashedSubPackets();
|
|
||||||
|
|
||||||
if (unhashed != null && (unhashed.getKeyFlags() & KeyFlags.SIGN_DATA) != 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isSigningKey(PGPSecretKey key) {
|
|
||||||
return isSigningKey(key.getPublicKey());
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public static boolean isCertificationKey(PGPPublicKey key) {
|
|
||||||
if (key.getVersion() <= 3) {
|
|
||||||
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.CERTIFY_OTHER) != 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
PGPSignatureSubpacketVector unhashed = sig.getUnhashedSubPackets();
|
|
||||||
|
|
||||||
if (unhashed != null && (unhashed.getKeyFlags() & KeyFlags.CERTIFY_OTHER) != 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isCertificationKey(PGPSecretKey key) {
|
|
||||||
return isCertificationKey(key.getPublicKey());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getAlgorithmInfo(PGPPublicKey key) {
|
|
||||||
return getAlgorithmInfo(key.getAlgorithm(), key.getBitStrength());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getAlgorithmInfo(PGPSecretKey key) {
|
|
||||||
return getAlgorithmInfo(key.getPublicKey());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getAlgorithmInfo(int algorithm, int keySize) {
|
|
||||||
String algorithmStr = null;
|
|
||||||
|
|
||||||
switch (algorithm) {
|
|
||||||
case PGPPublicKey.RSA_ENCRYPT:
|
|
||||||
case PGPPublicKey.RSA_GENERAL:
|
|
||||||
case PGPPublicKey.RSA_SIGN: {
|
|
||||||
algorithmStr = "RSA";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case PGPPublicKey.DSA: {
|
|
||||||
algorithmStr = "DSA";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case PGPPublicKey.ELGAMAL_ENCRYPT:
|
|
||||||
case PGPPublicKey.ELGAMAL_GENERAL: {
|
|
||||||
algorithmStr = "ElGamal";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default: {
|
|
||||||
algorithmStr = "???";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return algorithmStr + ", " + keySize + "bit";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String convertFingerprintToHex(byte[] fp) {
|
|
||||||
String fingerPrint = "";
|
|
||||||
for (int i = 0; i < fp.length; ++i) {
|
|
||||||
if (i != 0 && i % 10 == 0) {
|
|
||||||
fingerPrint += " ";
|
|
||||||
} else if (i != 0 && i % 2 == 0) {
|
|
||||||
fingerPrint += " ";
|
|
||||||
}
|
|
||||||
String chunk = Integer.toHexString((fp[i] + 256) % 256).toUpperCase(Locale.US);
|
|
||||||
while (chunk.length() < 2) {
|
|
||||||
chunk = "0" + chunk;
|
|
||||||
}
|
|
||||||
fingerPrint += chunk;
|
|
||||||
}
|
|
||||||
|
|
||||||
return fingerPrint;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getFingerPrint(Context context, long keyId) {
|
|
||||||
PGPPublicKey key = ProviderHelper.getPGPPublicKeyByKeyId(context, keyId);
|
|
||||||
// if it is no public key get it from your own keys...
|
|
||||||
if (key == null) {
|
|
||||||
PGPSecretKey secretKey = ProviderHelper.getPGPSecretKeyByKeyId(context, keyId);
|
|
||||||
if (secretKey == null) {
|
|
||||||
Log.e(Constants.TAG, "Key could not be found!");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
key = secretKey.getPublicKey();
|
|
||||||
}
|
|
||||||
|
|
||||||
return convertFingerprintToHex(key.getFingerprint());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isSecretKeyPrivateEmpty(PGPSecretKey secretKey) {
|
|
||||||
return secretKey.isPrivateKeyEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isSecretKeyPrivateEmpty(Context context, long keyId) {
|
|
||||||
PGPSecretKey secretKey = ProviderHelper.getPGPSecretKeyByKeyId(context, keyId);
|
|
||||||
if (secretKey == null) {
|
if (secretKey == null) {
|
||||||
Log.e(Constants.TAG, "Key could not be found!");
|
return Id.key.none;
|
||||||
return false; // could be a public key, assume it is not empty
|
|
||||||
}
|
}
|
||||||
return isSecretKeyPrivateEmpty(secretKey);
|
|
||||||
|
return secretKey.getKeyID();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getSmallFingerPrint(long keyId) {
|
public static int getStreamContent(Context context, InputStream inStream) throws IOException {
|
||||||
String fingerPrint = Long.toHexString(keyId & 0xffffffffL).toUpperCase(Locale.US);
|
InputStream in = PGPUtil.getDecoderStream(inStream);
|
||||||
while (fingerPrint.length() < 8) {
|
PGPObjectFactory pgpF = new PGPObjectFactory(in);
|
||||||
fingerPrint = "0" + fingerPrint;
|
Object object = pgpF.nextObject();
|
||||||
|
while (object != null) {
|
||||||
|
if (object instanceof PGPPublicKeyRing || object instanceof PGPSecretKeyRing) {
|
||||||
|
return Id.content.keys;
|
||||||
|
} else if (object instanceof PGPEncryptedDataList) {
|
||||||
|
return Id.content.encrypted_data;
|
||||||
|
}
|
||||||
|
object = pgpF.nextObject();
|
||||||
}
|
}
|
||||||
return fingerPrint;
|
|
||||||
|
return Id.content.unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String keyToHex(long keyId) {
|
/**
|
||||||
return getSmallFingerPrint(keyId >> 32) + getSmallFingerPrint(keyId);
|
* Generate a random filename
|
||||||
|
*
|
||||||
|
* @param length
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String generateRandomFilename(int length) {
|
||||||
|
SecureRandom random = new SecureRandom();
|
||||||
|
|
||||||
|
byte bytes[] = new byte[length];
|
||||||
|
random.nextBytes(bytes);
|
||||||
|
String result = "";
|
||||||
|
for (int i = 0; i < length; ++i) {
|
||||||
|
int v = (bytes[i] + 256) % 64;
|
||||||
|
if (v < 10) {
|
||||||
|
result += (char) ('0' + v);
|
||||||
|
} else if (v < 36) {
|
||||||
|
result += (char) ('A' + v - 10);
|
||||||
|
} else if (v < 62) {
|
||||||
|
result += (char) ('a' + v - 36);
|
||||||
|
} else if (v == 62) {
|
||||||
|
result += '_';
|
||||||
|
} else if (v == 63) {
|
||||||
|
result += '.';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static long keyFromHex(String data) {
|
/**
|
||||||
int len = data.length();
|
* Go once through stream to get length of stream. The length is later used to display progress
|
||||||
String s2 = data.substring(len - 8);
|
* when encrypting/decrypting
|
||||||
String s1 = data.substring(0, len - 8);
|
*
|
||||||
return (Long.parseLong(s1, 16) << 32) | Long.parseLong(s2, 16);
|
* @param in
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public static long getLengthOfStream(InputStream in) throws IOException {
|
||||||
|
long size = 0;
|
||||||
|
long n = 0;
|
||||||
|
byte dummy[] = new byte[0x10000];
|
||||||
|
while ((n = in.read(dummy)) > 0) {
|
||||||
|
size += n;
|
||||||
|
}
|
||||||
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes file securely by overwriting it with random data before deleting it.
|
||||||
|
*
|
||||||
|
* TODO: Does this really help on flash storage?
|
||||||
|
*
|
||||||
|
* @param context
|
||||||
|
* @param progress
|
||||||
|
* @param file
|
||||||
|
* @throws FileNotFoundException
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public static void deleteFileSecurely(Context context, ProgressDialogUpdater progress, File file)
|
||||||
|
throws FileNotFoundException, IOException {
|
||||||
|
long length = file.length();
|
||||||
|
SecureRandom random = new SecureRandom();
|
||||||
|
RandomAccessFile raf = new RandomAccessFile(file, "rws");
|
||||||
|
raf.seek(0);
|
||||||
|
raf.getFilePointer();
|
||||||
|
byte[] data = new byte[1 << 16];
|
||||||
|
int pos = 0;
|
||||||
|
String msg = context.getString(R.string.progress_deletingSecurely, file.getName());
|
||||||
|
while (pos < length) {
|
||||||
|
if (progress != null)
|
||||||
|
progress.setProgress(msg, (int) (100 * pos / length), 100);
|
||||||
|
random.nextBytes(data);
|
||||||
|
raf.write(data);
|
||||||
|
pos += data.length;
|
||||||
|
}
|
||||||
|
raf.close();
|
||||||
|
file.delete();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,280 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
|
||||||
|
* Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.sufficientlysecure.keychain.pgp;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import org.spongycastle.bcpg.ArmoredOutputStream;
|
||||||
|
import org.spongycastle.openpgp.PGPException;
|
||||||
|
import org.spongycastle.openpgp.PGPKeyRing;
|
||||||
|
import org.spongycastle.openpgp.PGPObjectFactory;
|
||||||
|
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
||||||
|
import org.spongycastle.openpgp.PGPSecretKey;
|
||||||
|
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
||||||
|
import org.spongycastle.openpgp.PGPUtil;
|
||||||
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
|
import org.sufficientlysecure.keychain.Id;
|
||||||
|
import org.sufficientlysecure.keychain.R;
|
||||||
|
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
|
||||||
|
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||||
|
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
||||||
|
import org.sufficientlysecure.keychain.util.HkpKeyServer;
|
||||||
|
import org.sufficientlysecure.keychain.util.InputData;
|
||||||
|
import org.sufficientlysecure.keychain.util.IterableIterator;
|
||||||
|
import org.sufficientlysecure.keychain.util.KeyServer.AddKeyException;
|
||||||
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
|
import org.sufficientlysecure.keychain.util.PositionAwareInputStream;
|
||||||
|
import org.sufficientlysecure.keychain.util.ProgressDialogUpdater;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Environment;
|
||||||
|
|
||||||
|
public class PgpImportExport {
|
||||||
|
private Context mContext;
|
||||||
|
private ProgressDialogUpdater mProgress;
|
||||||
|
|
||||||
|
public PgpImportExport(Context context, ProgressDialogUpdater progress) {
|
||||||
|
super();
|
||||||
|
this.mContext = context;
|
||||||
|
this.mProgress = progress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateProgress(int message, int current, int total) {
|
||||||
|
if (mProgress != null) {
|
||||||
|
mProgress.setProgress(message, current, total);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateProgress(int current, int total) {
|
||||||
|
if (mProgress != null) {
|
||||||
|
mProgress.setProgress(current, total);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean uploadKeyRingToServer(HkpKeyServer server, PGPPublicKeyRing keyring) {
|
||||||
|
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
|
ArmoredOutputStream aos = new ArmoredOutputStream(bos);
|
||||||
|
try {
|
||||||
|
aos.write(keyring.getEncoded());
|
||||||
|
aos.close();
|
||||||
|
|
||||||
|
String armouredKey = bos.toString("UTF-8");
|
||||||
|
server.add(armouredKey);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} catch (IOException e) {
|
||||||
|
return false;
|
||||||
|
} catch (AddKeyException e) {
|
||||||
|
// TODO: tell the user?
|
||||||
|
return false;
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
bos.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Bundle importKeyRings(InputData data) throws PgpGeneralException, FileNotFoundException,
|
||||||
|
PGPException, IOException {
|
||||||
|
Bundle returnData = new Bundle();
|
||||||
|
|
||||||
|
updateProgress(R.string.progress_importingSecretKeys, 0, 100);
|
||||||
|
|
||||||
|
if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
|
||||||
|
throw new PgpGeneralException(
|
||||||
|
mContext.getString(R.string.error_externalStorageNotReady));
|
||||||
|
}
|
||||||
|
|
||||||
|
PositionAwareInputStream progressIn = new PositionAwareInputStream(data.getInputStream());
|
||||||
|
|
||||||
|
// need to have access to the bufferedInput, so we can reuse it for the possible
|
||||||
|
// PGPObject chunks after the first one, e.g. files with several consecutive ASCII
|
||||||
|
// armour blocks
|
||||||
|
BufferedInputStream bufferedInput = new BufferedInputStream(progressIn);
|
||||||
|
int newKeys = 0;
|
||||||
|
int oldKeys = 0;
|
||||||
|
int badKeys = 0;
|
||||||
|
try {
|
||||||
|
|
||||||
|
// read all available blocks... (asc files can contain many blocks with BEGIN END)
|
||||||
|
while (bufferedInput.available() > 0) {
|
||||||
|
InputStream in = PGPUtil.getDecoderStream(bufferedInput);
|
||||||
|
PGPObjectFactory objectFactory = new PGPObjectFactory(in);
|
||||||
|
|
||||||
|
// go through all objects in this block
|
||||||
|
Object obj;
|
||||||
|
while ((obj = objectFactory.nextObject()) != null) {
|
||||||
|
Log.d(Constants.TAG, "Found class: " + obj.getClass());
|
||||||
|
|
||||||
|
if (obj instanceof PGPKeyRing) {
|
||||||
|
PGPKeyRing keyring = (PGPKeyRing) obj;
|
||||||
|
|
||||||
|
int status = Integer.MIN_VALUE; // out of bounds value
|
||||||
|
|
||||||
|
status = storeKeyRingInCache(keyring);
|
||||||
|
|
||||||
|
if (status == Id.return_value.error) {
|
||||||
|
throw new PgpGeneralException(
|
||||||
|
mContext.getString(R.string.error_savingKeys));
|
||||||
|
}
|
||||||
|
|
||||||
|
// update the counts to display to the user at the end
|
||||||
|
if (status == Id.return_value.updated) {
|
||||||
|
++oldKeys;
|
||||||
|
} else if (status == Id.return_value.ok) {
|
||||||
|
++newKeys;
|
||||||
|
} else if (status == Id.return_value.bad) {
|
||||||
|
++badKeys;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateProgress((int) (100 * progressIn.position() / data.getSize()), 100);
|
||||||
|
} else {
|
||||||
|
Log.e(Constants.TAG, "Object not recognized as PGPKeyRing!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(Constants.TAG, "Exception on parsing key file!", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
returnData.putInt(KeychainIntentService.RESULT_IMPORT_ADDED, newKeys);
|
||||||
|
returnData.putInt(KeychainIntentService.RESULT_IMPORT_UPDATED, oldKeys);
|
||||||
|
returnData.putInt(KeychainIntentService.RESULT_IMPORT_BAD, badKeys);
|
||||||
|
|
||||||
|
updateProgress(R.string.progress_done, 100, 100);
|
||||||
|
|
||||||
|
return returnData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Bundle exportKeyRings(ArrayList<Long> keyRingMasterKeyIds, int keyType,
|
||||||
|
OutputStream outStream) throws PgpGeneralException, FileNotFoundException,
|
||||||
|
PGPException, IOException {
|
||||||
|
Bundle returnData = new Bundle();
|
||||||
|
|
||||||
|
if (keyRingMasterKeyIds.size() == 1) {
|
||||||
|
updateProgress(R.string.progress_exportingKey, 0, 100);
|
||||||
|
} else {
|
||||||
|
updateProgress(R.string.progress_exportingKeys, 0, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
|
||||||
|
throw new PgpGeneralException(
|
||||||
|
mContext.getString(R.string.error_externalStorageNotReady));
|
||||||
|
}
|
||||||
|
|
||||||
|
// export public keyrings...
|
||||||
|
ArmoredOutputStream outPub = new ArmoredOutputStream(outStream);
|
||||||
|
outPub.setHeader("Version", PgpHelper.getFullVersion(mContext));
|
||||||
|
|
||||||
|
int numKeys = 0;
|
||||||
|
for (int i = 0; i < keyRingMasterKeyIds.size(); ++i) {
|
||||||
|
// double the needed time if exporting both public and secret parts
|
||||||
|
if (keyType == Id.type.secret_key) {
|
||||||
|
updateProgress(i * 100 / keyRingMasterKeyIds.size() / 2, 100);
|
||||||
|
} else {
|
||||||
|
updateProgress(i * 100 / keyRingMasterKeyIds.size(), 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
PGPPublicKeyRing publicKeyRing = ProviderHelper.getPGPPublicKeyRingByMasterKeyId(
|
||||||
|
mContext, keyRingMasterKeyIds.get(i));
|
||||||
|
|
||||||
|
if (publicKeyRing != null) {
|
||||||
|
publicKeyRing.encode(outPub);
|
||||||
|
}
|
||||||
|
++numKeys;
|
||||||
|
}
|
||||||
|
outPub.close();
|
||||||
|
|
||||||
|
// if we export secret keyrings, append all secret parts after the public parts
|
||||||
|
if (keyType == Id.type.secret_key) {
|
||||||
|
ArmoredOutputStream outSec = new ArmoredOutputStream(outStream);
|
||||||
|
outSec.setHeader("Version", PgpHelper.getFullVersion(mContext));
|
||||||
|
|
||||||
|
for (int i = 0; i < keyRingMasterKeyIds.size(); ++i) {
|
||||||
|
updateProgress(i * 100 / keyRingMasterKeyIds.size() / 2, 100);
|
||||||
|
|
||||||
|
PGPSecretKeyRing secretKeyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(
|
||||||
|
mContext, keyRingMasterKeyIds.get(i));
|
||||||
|
|
||||||
|
if (secretKeyRing != null) {
|
||||||
|
secretKeyRing.encode(outSec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
outSec.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
returnData.putInt(KeychainIntentService.RESULT_EXPORT, numKeys);
|
||||||
|
|
||||||
|
updateProgress(R.string.progress_done, 100, 100);
|
||||||
|
|
||||||
|
return returnData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: implement Id.return_value.updated as status when key already existed
|
||||||
|
*
|
||||||
|
* @param context
|
||||||
|
* @param keyring
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public int storeKeyRingInCache(PGPKeyRing keyring) {
|
||||||
|
int status = Integer.MIN_VALUE; // out of bounds value (Id.return_value.*)
|
||||||
|
try {
|
||||||
|
if (keyring instanceof PGPSecretKeyRing) {
|
||||||
|
PGPSecretKeyRing secretKeyRing = (PGPSecretKeyRing) keyring;
|
||||||
|
boolean save = true;
|
||||||
|
|
||||||
|
for (PGPSecretKey testSecretKey : new IterableIterator<PGPSecretKey>(
|
||||||
|
secretKeyRing.getSecretKeys())) {
|
||||||
|
if (!testSecretKey.isMasterKey()) {
|
||||||
|
if (PgpKeyHelper.isSecretKeyPrivateEmpty(testSecretKey)) {
|
||||||
|
// this is bad, something is very wrong...
|
||||||
|
save = false;
|
||||||
|
status = Id.return_value.bad;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (save) {
|
||||||
|
ProviderHelper.saveKeyRing(mContext, secretKeyRing);
|
||||||
|
// TODO: remove status returns, use exceptions!
|
||||||
|
status = Id.return_value.ok;
|
||||||
|
}
|
||||||
|
} else if (keyring instanceof PGPPublicKeyRing) {
|
||||||
|
PGPPublicKeyRing publicKeyRing = (PGPPublicKeyRing) keyring;
|
||||||
|
ProviderHelper.saveKeyRing(mContext, publicKeyRing);
|
||||||
|
// TODO: remove status returns, use exceptions!
|
||||||
|
status = Id.return_value.ok;
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
status = Id.return_value.error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,510 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
|
||||||
|
* Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.sufficientlysecure.keychain.pgp;
|
||||||
|
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.GregorianCalendar;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
import org.spongycastle.bcpg.sig.KeyFlags;
|
||||||
|
import org.spongycastle.openpgp.PGPPublicKey;
|
||||||
|
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
||||||
|
import org.spongycastle.openpgp.PGPSecretKey;
|
||||||
|
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
||||||
|
import org.spongycastle.openpgp.PGPSignature;
|
||||||
|
import org.spongycastle.openpgp.PGPSignatureSubpacketVector;
|
||||||
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
|
import org.sufficientlysecure.keychain.R;
|
||||||
|
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||||
|
import org.sufficientlysecure.keychain.util.IterableIterator;
|
||||||
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
public class PgpKeyHelper {
|
||||||
|
|
||||||
|
public static Date getCreationDate(PGPPublicKey key) {
|
||||||
|
return key.getCreationTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Date getCreationDate(PGPSecretKey key) {
|
||||||
|
return key.getPublicKey().getCreationTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static PGPPublicKey getMasterKey(PGPPublicKeyRing keyRing) {
|
||||||
|
if (keyRing == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
for (PGPPublicKey key : new IterableIterator<PGPPublicKey>(keyRing.getPublicKeys())) {
|
||||||
|
if (key.isMasterKey()) {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static PGPSecretKey getMasterKey(PGPSecretKeyRing keyRing) {
|
||||||
|
if (keyRing == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
for (PGPSecretKey key : new IterableIterator<PGPSecretKey>(keyRing.getSecretKeys())) {
|
||||||
|
if (key.isMasterKey()) {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static PGPSecretKey getKeyNum(PGPSecretKeyRing keyRing, long num) {
|
||||||
|
long cnt = 0;
|
||||||
|
if (keyRing == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
for (PGPSecretKey key : new IterableIterator<PGPSecretKey>(keyRing.getSecretKeys())) {
|
||||||
|
if (cnt == num) {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static Vector<PGPPublicKey> getEncryptKeys(PGPPublicKeyRing keyRing) {
|
||||||
|
Vector<PGPPublicKey> encryptKeys = new Vector<PGPPublicKey>();
|
||||||
|
|
||||||
|
for (PGPPublicKey key : new IterableIterator<PGPPublicKey>(keyRing.getPublicKeys())) {
|
||||||
|
if (isEncryptionKey(key)) {
|
||||||
|
encryptKeys.add(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return encryptKeys;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static Vector<PGPSecretKey> getCertificationKeys(PGPSecretKeyRing keyRing) {
|
||||||
|
Vector<PGPSecretKey> signingKeys = new Vector<PGPSecretKey>();
|
||||||
|
|
||||||
|
for (PGPSecretKey key : new IterableIterator<PGPSecretKey>(keyRing.getSecretKeys())) {
|
||||||
|
if (isCertificationKey(key)) {
|
||||||
|
signingKeys.add(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return signingKeys;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector<PGPPublicKey> getUsableEncryptKeys(PGPPublicKeyRing keyRing) {
|
||||||
|
Vector<PGPPublicKey> usableKeys = new Vector<PGPPublicKey>();
|
||||||
|
Vector<PGPPublicKey> encryptKeys = getEncryptKeys(keyRing);
|
||||||
|
PGPPublicKey masterKey = null;
|
||||||
|
for (int i = 0; i < encryptKeys.size(); ++i) {
|
||||||
|
PGPPublicKey key = encryptKeys.get(i);
|
||||||
|
if (!isExpired(key)) {
|
||||||
|
if (key.isMasterKey()) {
|
||||||
|
masterKey = key;
|
||||||
|
} else {
|
||||||
|
usableKeys.add(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (masterKey != null) {
|
||||||
|
usableKeys.add(masterKey);
|
||||||
|
}
|
||||||
|
return usableKeys;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isExpired(PGPSecretKey key) {
|
||||||
|
return isExpired(key.getPublicKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector<PGPSecretKey> getUsableCertificationKeys(PGPSecretKeyRing keyRing) {
|
||||||
|
Vector<PGPSecretKey> usableKeys = new Vector<PGPSecretKey>();
|
||||||
|
Vector<PGPSecretKey> signingKeys = getCertificationKeys(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
public 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Date getExpiryDate(PGPPublicKey key) {
|
||||||
|
Date creationDate = getCreationDate(key);
|
||||||
|
if (key.getValidDays() == 0) {
|
||||||
|
// no expiry
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Calendar calendar = GregorianCalendar.getInstance();
|
||||||
|
calendar.setTime(creationDate);
|
||||||
|
calendar.add(Calendar.DATE, key.getValidDays());
|
||||||
|
Date expiryDate = calendar.getTime();
|
||||||
|
|
||||||
|
return expiryDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Date getExpiryDate(PGPSecretKey key) {
|
||||||
|
return getExpiryDate(key.getPublicKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PGPPublicKey getEncryptPublicKey(Context context, long masterKeyId) {
|
||||||
|
PGPPublicKeyRing keyRing = ProviderHelper.getPGPPublicKeyRingByMasterKeyId(context,
|
||||||
|
masterKeyId);
|
||||||
|
if (keyRing == null) {
|
||||||
|
Log.e(Constants.TAG, "keyRing is null!");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Vector<PGPPublicKey> encryptKeys = getUsableEncryptKeys(keyRing);
|
||||||
|
if (encryptKeys.size() == 0) {
|
||||||
|
Log.e(Constants.TAG, "encryptKeys is null!");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return encryptKeys.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PGPSecretKey getCertificationKey(Context context, long masterKeyId) {
|
||||||
|
PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(context,
|
||||||
|
masterKeyId);
|
||||||
|
if (keyRing == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Vector<PGPSecretKey> signingKeys = getUsableCertificationKeys(keyRing);
|
||||||
|
if (signingKeys.size() == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return signingKeys.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PGPSecretKey getSigningKey(Context context, long masterKeyId) {
|
||||||
|
PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(context,
|
||||||
|
masterKeyId);
|
||||||
|
if (keyRing == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Vector<PGPSecretKey> signingKeys = getUsableSigningKeys(keyRing);
|
||||||
|
if (signingKeys.size() == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return signingKeys.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static String getMainUserId(PGPPublicKey key) {
|
||||||
|
for (String userId : new IterableIterator<String>(key.getUserIDs())) {
|
||||||
|
return userId;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static String getMainUserId(PGPSecretKey key) {
|
||||||
|
for (String userId : new IterableIterator<String>(key.getUserIDs())) {
|
||||||
|
return userId;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getMainUserIdSafe(Context context, PGPPublicKey key) {
|
||||||
|
String userId = getMainUserId(key);
|
||||||
|
if (userId == null || userId.equals("")) {
|
||||||
|
userId = context.getString(R.string.unknownUserId);
|
||||||
|
}
|
||||||
|
return userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getMainUserIdSafe(Context context, PGPSecretKey key) {
|
||||||
|
String userId = getMainUserId(key);
|
||||||
|
if (userId == null || userId.equals("")) {
|
||||||
|
userId = context.getString(R.string.unknownUserId);
|
||||||
|
}
|
||||||
|
return userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isEncryptionKey(PGPSecretKey key) {
|
||||||
|
return isEncryptionKey(key.getPublicKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static boolean isSigningKey(PGPPublicKey key) {
|
||||||
|
if (key.getVersion() <= 3) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// special case
|
||||||
|
if (key.getAlgorithm() == PGPPublicKey.RSA_SIGN) {
|
||||||
|
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.SIGN_DATA) != 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
PGPSignatureSubpacketVector unhashed = sig.getUnhashedSubPackets();
|
||||||
|
|
||||||
|
if (unhashed != null && (unhashed.getKeyFlags() & KeyFlags.SIGN_DATA) != 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isSigningKey(PGPSecretKey key) {
|
||||||
|
return isSigningKey(key.getPublicKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static boolean isCertificationKey(PGPPublicKey key) {
|
||||||
|
if (key.getVersion() <= 3) {
|
||||||
|
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.CERTIFY_OTHER) != 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
PGPSignatureSubpacketVector unhashed = sig.getUnhashedSubPackets();
|
||||||
|
|
||||||
|
if (unhashed != null && (unhashed.getKeyFlags() & KeyFlags.CERTIFY_OTHER) != 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isCertificationKey(PGPSecretKey key) {
|
||||||
|
return isCertificationKey(key.getPublicKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getAlgorithmInfo(PGPPublicKey key) {
|
||||||
|
return getAlgorithmInfo(key.getAlgorithm(), key.getBitStrength());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getAlgorithmInfo(PGPSecretKey key) {
|
||||||
|
return getAlgorithmInfo(key.getPublicKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getAlgorithmInfo(int algorithm, int keySize) {
|
||||||
|
String algorithmStr = null;
|
||||||
|
|
||||||
|
switch (algorithm) {
|
||||||
|
case PGPPublicKey.RSA_ENCRYPT:
|
||||||
|
case PGPPublicKey.RSA_GENERAL:
|
||||||
|
case PGPPublicKey.RSA_SIGN: {
|
||||||
|
algorithmStr = "RSA";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PGPPublicKey.DSA: {
|
||||||
|
algorithmStr = "DSA";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PGPPublicKey.ELGAMAL_ENCRYPT:
|
||||||
|
case PGPPublicKey.ELGAMAL_GENERAL: {
|
||||||
|
algorithmStr = "ElGamal";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default: {
|
||||||
|
algorithmStr = "???";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return algorithmStr + ", " + keySize + "bit";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String convertFingerprintToHex(byte[] fp) {
|
||||||
|
String fingerPrint = "";
|
||||||
|
for (int i = 0; i < fp.length; ++i) {
|
||||||
|
if (i != 0 && i % 10 == 0) {
|
||||||
|
fingerPrint += " ";
|
||||||
|
} else if (i != 0 && i % 2 == 0) {
|
||||||
|
fingerPrint += " ";
|
||||||
|
}
|
||||||
|
String chunk = Integer.toHexString((fp[i] + 256) % 256).toUpperCase(Locale.US);
|
||||||
|
while (chunk.length() < 2) {
|
||||||
|
chunk = "0" + chunk;
|
||||||
|
}
|
||||||
|
fingerPrint += chunk;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fingerPrint;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getFingerPrint(Context context, long keyId) {
|
||||||
|
PGPPublicKey key = ProviderHelper.getPGPPublicKeyByKeyId(context, keyId);
|
||||||
|
// if it is no public key get it from your own keys...
|
||||||
|
if (key == null) {
|
||||||
|
PGPSecretKey secretKey = ProviderHelper.getPGPSecretKeyByKeyId(context, keyId);
|
||||||
|
if (secretKey == null) {
|
||||||
|
Log.e(Constants.TAG, "Key could not be found!");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
key = secretKey.getPublicKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
return convertFingerprintToHex(key.getFingerprint());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isSecretKeyPrivateEmpty(PGPSecretKey secretKey) {
|
||||||
|
return secretKey.isPrivateKeyEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isSecretKeyPrivateEmpty(Context context, long keyId) {
|
||||||
|
PGPSecretKey secretKey = ProviderHelper.getPGPSecretKeyByKeyId(context, keyId);
|
||||||
|
if (secretKey == null) {
|
||||||
|
Log.e(Constants.TAG, "Key could not be found!");
|
||||||
|
return false; // could be a public key, assume it is not empty
|
||||||
|
}
|
||||||
|
return isSecretKeyPrivateEmpty(secretKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getSmallFingerPrint(long keyId) {
|
||||||
|
String fingerPrint = Long.toHexString(keyId & 0xffffffffL).toUpperCase(Locale.US);
|
||||||
|
while (fingerPrint.length() < 8) {
|
||||||
|
fingerPrint = "0" + fingerPrint;
|
||||||
|
}
|
||||||
|
return fingerPrint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String keyToHex(long keyId) {
|
||||||
|
return getSmallFingerPrint(keyId >> 32) + getSmallFingerPrint(keyId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long keyFromHex(String data) {
|
||||||
|
int len = data.length();
|
||||||
|
String s2 = data.substring(len - 8);
|
||||||
|
String s1 = data.substring(0, len - 8);
|
||||||
|
return (Long.parseLong(s1, 16) << 32) | Long.parseLong(s2, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,457 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
|
||||||
|
* Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.sufficientlysecure.keychain.pgp;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.security.InvalidAlgorithmParameterException;
|
||||||
|
import java.security.KeyPairGenerator;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.NoSuchProviderException;
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
import java.security.SignatureException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import org.spongycastle.bcpg.CompressionAlgorithmTags;
|
||||||
|
import org.spongycastle.bcpg.HashAlgorithmTags;
|
||||||
|
import org.spongycastle.bcpg.SymmetricKeyAlgorithmTags;
|
||||||
|
import org.spongycastle.bcpg.sig.KeyFlags;
|
||||||
|
import org.spongycastle.jce.provider.BouncyCastleProvider;
|
||||||
|
import org.spongycastle.jce.spec.ElGamalParameterSpec;
|
||||||
|
import org.spongycastle.openpgp.PGPEncryptedData;
|
||||||
|
import org.spongycastle.openpgp.PGPException;
|
||||||
|
import org.spongycastle.openpgp.PGPKeyPair;
|
||||||
|
import org.spongycastle.openpgp.PGPKeyRingGenerator;
|
||||||
|
import org.spongycastle.openpgp.PGPPrivateKey;
|
||||||
|
import org.spongycastle.openpgp.PGPPublicKey;
|
||||||
|
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
||||||
|
import org.spongycastle.openpgp.PGPSecretKey;
|
||||||
|
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;
|
||||||
|
import org.spongycastle.openpgp.operator.PGPContentSignerBuilder;
|
||||||
|
import org.spongycastle.openpgp.operator.PGPDigestCalculator;
|
||||||
|
import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder;
|
||||||
|
import org.spongycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder;
|
||||||
|
import org.spongycastle.openpgp.operator.jcajce.JcaPGPKeyPair;
|
||||||
|
import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
|
||||||
|
import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyEncryptorBuilder;
|
||||||
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
|
import org.sufficientlysecure.keychain.Id;
|
||||||
|
import org.sufficientlysecure.keychain.R;
|
||||||
|
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
|
||||||
|
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||||
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
|
import org.sufficientlysecure.keychain.util.Primes;
|
||||||
|
import org.sufficientlysecure.keychain.util.ProgressDialogUpdater;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
public class PgpKeyOperation {
|
||||||
|
private Context mContext;
|
||||||
|
private ProgressDialogUpdater mProgress;
|
||||||
|
|
||||||
|
private static final int[] PREFERRED_SYMMETRIC_ALGORITHMS = new int[] {
|
||||||
|
SymmetricKeyAlgorithmTags.AES_256, SymmetricKeyAlgorithmTags.AES_192,
|
||||||
|
SymmetricKeyAlgorithmTags.AES_128, SymmetricKeyAlgorithmTags.CAST5,
|
||||||
|
SymmetricKeyAlgorithmTags.TRIPLE_DES };
|
||||||
|
private static final int[] PREFERRED_HASH_ALGORITHMS = new int[] { HashAlgorithmTags.SHA1,
|
||||||
|
HashAlgorithmTags.SHA256, HashAlgorithmTags.RIPEMD160 };
|
||||||
|
private static final int[] PREFERRED_COMPRESSION_ALGORITHMS = new int[] {
|
||||||
|
CompressionAlgorithmTags.ZLIB, CompressionAlgorithmTags.BZIP2,
|
||||||
|
CompressionAlgorithmTags.ZIP };
|
||||||
|
|
||||||
|
public PgpKeyOperation(Context context, ProgressDialogUpdater progress) {
|
||||||
|
super();
|
||||||
|
this.mContext = context;
|
||||||
|
this.mProgress = progress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateProgress(int message, int current, int total) {
|
||||||
|
if (mProgress != null) {
|
||||||
|
mProgress.setProgress(message, current, total);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateProgress(int current, int total) {
|
||||||
|
if (mProgress != null) {
|
||||||
|
mProgress.setProgress(current, total);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates new secret key. The returned PGPSecretKeyRing contains only one newly generated key
|
||||||
|
* when this key is the new masterkey. If a masterkey is supplied in the parameters
|
||||||
|
* PGPSecretKeyRing contains the masterkey and the new key as a subkey (certified by the
|
||||||
|
* masterkey).
|
||||||
|
*
|
||||||
|
* @param context
|
||||||
|
* @param algorithmChoice
|
||||||
|
* @param keySize
|
||||||
|
* @param passPhrase
|
||||||
|
* @param masterSecretKey
|
||||||
|
* @return
|
||||||
|
* @throws NoSuchAlgorithmException
|
||||||
|
* @throws PGPException
|
||||||
|
* @throws NoSuchProviderException
|
||||||
|
* @throws PgpGeneralException
|
||||||
|
* @throws InvalidAlgorithmParameterException
|
||||||
|
*/
|
||||||
|
public PGPSecretKeyRing createKey(int algorithmChoice, int keySize, String passPhrase,
|
||||||
|
PGPSecretKey masterSecretKey) throws NoSuchAlgorithmException, PGPException,
|
||||||
|
NoSuchProviderException, PgpGeneralException, InvalidAlgorithmParameterException {
|
||||||
|
|
||||||
|
if (keySize < 512) {
|
||||||
|
throw new PgpGeneralException(mContext.getString(R.string.error_keySizeMinimum512bit));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (passPhrase == null) {
|
||||||
|
passPhrase = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
int algorithm = 0;
|
||||||
|
KeyPairGenerator keyGen = null;
|
||||||
|
|
||||||
|
switch (algorithmChoice) {
|
||||||
|
case Id.choice.algorithm.dsa: {
|
||||||
|
keyGen = KeyPairGenerator.getInstance("DSA", Constants.BOUNCY_CASTLE_PROVIDER_NAME);
|
||||||
|
keyGen.initialize(keySize, new SecureRandom());
|
||||||
|
algorithm = PGPPublicKey.DSA;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Id.choice.algorithm.elgamal: {
|
||||||
|
if (masterSecretKey == null) {
|
||||||
|
throw new PgpGeneralException(
|
||||||
|
mContext.getString(R.string.error_masterKeyMustNotBeElGamal));
|
||||||
|
}
|
||||||
|
keyGen = KeyPairGenerator.getInstance("ElGamal", Constants.BOUNCY_CASTLE_PROVIDER_NAME);
|
||||||
|
BigInteger p = Primes.getBestPrime(keySize);
|
||||||
|
BigInteger g = new BigInteger("2");
|
||||||
|
|
||||||
|
ElGamalParameterSpec elParams = new ElGamalParameterSpec(p, g);
|
||||||
|
|
||||||
|
keyGen.initialize(elParams);
|
||||||
|
algorithm = PGPPublicKey.ELGAMAL_ENCRYPT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Id.choice.algorithm.rsa: {
|
||||||
|
keyGen = KeyPairGenerator.getInstance("RSA", Constants.BOUNCY_CASTLE_PROVIDER_NAME);
|
||||||
|
keyGen.initialize(keySize, new SecureRandom());
|
||||||
|
|
||||||
|
algorithm = PGPPublicKey.RSA_GENERAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default: {
|
||||||
|
throw new PgpGeneralException(mContext.getString(R.string.error_unknownAlgorithmChoice));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// build new key pair
|
||||||
|
PGPKeyPair keyPair = new JcaPGPKeyPair(algorithm, keyGen.generateKeyPair(), new Date());
|
||||||
|
|
||||||
|
// define hashing and signing algos
|
||||||
|
PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder().build().get(
|
||||||
|
HashAlgorithmTags.SHA1);
|
||||||
|
|
||||||
|
// Build key encrypter and decrypter based on passphrase
|
||||||
|
PBESecretKeyEncryptor keyEncryptor = new JcePBESecretKeyEncryptorBuilder(
|
||||||
|
PGPEncryptedData.CAST5, sha1Calc)
|
||||||
|
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(passPhrase.toCharArray());
|
||||||
|
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(
|
||||||
|
Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(passPhrase.toCharArray());
|
||||||
|
|
||||||
|
PGPKeyRingGenerator ringGen = null;
|
||||||
|
PGPContentSignerBuilder certificationSignerBuilder = null;
|
||||||
|
if (masterSecretKey == null) {
|
||||||
|
certificationSignerBuilder = new JcaPGPContentSignerBuilder(keyPair.getPublicKey()
|
||||||
|
.getAlgorithm(), HashAlgorithmTags.SHA1);
|
||||||
|
|
||||||
|
// build keyRing with only this one master key in it!
|
||||||
|
ringGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, keyPair, "",
|
||||||
|
sha1Calc, null, null, certificationSignerBuilder, keyEncryptor);
|
||||||
|
} else {
|
||||||
|
PGPPublicKey masterPublicKey = masterSecretKey.getPublicKey();
|
||||||
|
PGPPrivateKey masterPrivateKey = masterSecretKey.extractPrivateKey(keyDecryptor);
|
||||||
|
PGPKeyPair masterKeyPair = new PGPKeyPair(masterPublicKey, masterPrivateKey);
|
||||||
|
|
||||||
|
certificationSignerBuilder = new JcaPGPContentSignerBuilder(masterKeyPair
|
||||||
|
.getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA1);
|
||||||
|
|
||||||
|
// build keyRing with master key and new key as subkey (certified by masterkey)
|
||||||
|
ringGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, masterKeyPair,
|
||||||
|
"", sha1Calc, null, null, certificationSignerBuilder, keyEncryptor);
|
||||||
|
|
||||||
|
ringGen.addSubKey(keyPair);
|
||||||
|
}
|
||||||
|
|
||||||
|
PGPSecretKeyRing secKeyRing = ringGen.generateSecretKeyRing();
|
||||||
|
|
||||||
|
return secKeyRing;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void changeSecretKeyPassphrase(PGPSecretKeyRing keyRing, String oldPassPhrase,
|
||||||
|
String newPassPhrase) throws IOException, PGPException, PGPException,
|
||||||
|
NoSuchProviderException {
|
||||||
|
|
||||||
|
updateProgress(R.string.progress_buildingKey, 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()));
|
||||||
|
|
||||||
|
updateProgress(R.string.progress_savingKeyRing, 50, 100);
|
||||||
|
|
||||||
|
ProviderHelper.saveKeyRing(mContext, newKeyRing);
|
||||||
|
|
||||||
|
updateProgress(R.string.progress_done, 100, 100);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void buildSecretKey(ArrayList<String> userIds, ArrayList<PGPSecretKey> keys,
|
||||||
|
ArrayList<Integer> keysUsages, long masterKeyId, String oldPassPhrase,
|
||||||
|
String newPassPhrase) throws PgpGeneralException, NoSuchProviderException,
|
||||||
|
PGPException, NoSuchAlgorithmException, SignatureException, IOException {
|
||||||
|
|
||||||
|
Log.d(Constants.TAG, "userIds: " + userIds.toString());
|
||||||
|
|
||||||
|
updateProgress(R.string.progress_buildingKey, 0, 100);
|
||||||
|
|
||||||
|
if (oldPassPhrase == null) {
|
||||||
|
oldPassPhrase = "";
|
||||||
|
}
|
||||||
|
if (newPassPhrase == null) {
|
||||||
|
newPassPhrase = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
updateProgress(R.string.progress_preparingMasterKey, 10, 100);
|
||||||
|
|
||||||
|
int usageId = keysUsages.get(0);
|
||||||
|
boolean canSign = (usageId == Id.choice.usage.sign_only || usageId == Id.choice.usage.sign_and_encrypt);
|
||||||
|
boolean canEncrypt = (usageId == Id.choice.usage.encrypt_only || usageId == Id.choice.usage.sign_and_encrypt);
|
||||||
|
|
||||||
|
String mainUserId = userIds.get(0);
|
||||||
|
|
||||||
|
PGPSecretKey masterKey = keys.get(0);
|
||||||
|
|
||||||
|
// this removes all userIds and certifications previously attached to the masterPublicKey
|
||||||
|
PGPPublicKey tmpKey = masterKey.getPublicKey();
|
||||||
|
PGPPublicKey masterPublicKey = new PGPPublicKey(tmpKey.getAlgorithm(),
|
||||||
|
tmpKey.getKey(new BouncyCastleProvider()), tmpKey.getCreationTime());
|
||||||
|
|
||||||
|
// already done by code above:
|
||||||
|
// PGPPublicKey masterPublicKey = masterKey.getPublicKey();
|
||||||
|
// // Somehow, the PGPPublicKey already has an empty certification attached to it when the
|
||||||
|
// // keyRing is generated the first time, we remove that when it exists, before adding the
|
||||||
|
// new
|
||||||
|
// // ones
|
||||||
|
// PGPPublicKey masterPublicKeyRmCert = PGPPublicKey.removeCertification(masterPublicKey,
|
||||||
|
// "");
|
||||||
|
// if (masterPublicKeyRmCert != null) {
|
||||||
|
// masterPublicKey = masterPublicKeyRmCert;
|
||||||
|
// }
|
||||||
|
|
||||||
|
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(
|
||||||
|
Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(oldPassPhrase.toCharArray());
|
||||||
|
PGPPrivateKey masterPrivateKey = masterKey.extractPrivateKey(keyDecryptor);
|
||||||
|
|
||||||
|
updateProgress(R.string.progress_certifyingMasterKey, 20, 100);
|
||||||
|
|
||||||
|
for (String userId : userIds) {
|
||||||
|
PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder(
|
||||||
|
masterPublicKey.getAlgorithm(), HashAlgorithmTags.SHA1)
|
||||||
|
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
|
||||||
|
PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder);
|
||||||
|
|
||||||
|
sGen.init(PGPSignature.POSITIVE_CERTIFICATION, masterPrivateKey);
|
||||||
|
|
||||||
|
PGPSignature certification = sGen.generateCertification(userId, masterPublicKey);
|
||||||
|
|
||||||
|
masterPublicKey = PGPPublicKey.addCertification(masterPublicKey, userId, certification);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: cross-certify the master key with every sub key (APG 1)
|
||||||
|
|
||||||
|
PGPKeyPair masterKeyPair = new PGPKeyPair(masterPublicKey, masterPrivateKey);
|
||||||
|
|
||||||
|
PGPSignatureSubpacketGenerator hashedPacketsGen = new PGPSignatureSubpacketGenerator();
|
||||||
|
PGPSignatureSubpacketGenerator unhashedPacketsGen = new PGPSignatureSubpacketGenerator();
|
||||||
|
|
||||||
|
int keyFlags = KeyFlags.CERTIFY_OTHER | KeyFlags.SIGN_DATA;
|
||||||
|
if (canEncrypt) {
|
||||||
|
keyFlags |= KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE;
|
||||||
|
}
|
||||||
|
hashedPacketsGen.setKeyFlags(true, keyFlags);
|
||||||
|
|
||||||
|
hashedPacketsGen.setPreferredSymmetricAlgorithms(true, PREFERRED_SYMMETRIC_ALGORITHMS);
|
||||||
|
hashedPacketsGen.setPreferredHashAlgorithms(true, PREFERRED_HASH_ALGORITHMS);
|
||||||
|
hashedPacketsGen.setPreferredCompressionAlgorithms(true, PREFERRED_COMPRESSION_ALGORITHMS);
|
||||||
|
|
||||||
|
// TODO: this doesn't work quite right yet (APG 1)
|
||||||
|
// if (keyEditor.getExpiryDate() != null) {
|
||||||
|
// GregorianCalendar creationDate = new GregorianCalendar();
|
||||||
|
// creationDate.setTime(getCreationDate(masterKey));
|
||||||
|
// GregorianCalendar expiryDate = keyEditor.getExpiryDate();
|
||||||
|
// long numDays = Utils.getNumDaysBetween(creationDate, expiryDate);
|
||||||
|
// if (numDays <= 0) {
|
||||||
|
// throw new GeneralException(
|
||||||
|
// context.getString(R.string.error_expiryMustComeAfterCreation));
|
||||||
|
// }
|
||||||
|
// hashedPacketsGen.setKeyExpirationTime(true, numDays * 86400);
|
||||||
|
// }
|
||||||
|
|
||||||
|
updateProgress(R.string.progress_buildingMasterKeyRing, 30, 100);
|
||||||
|
|
||||||
|
// define hashing and signing algos
|
||||||
|
PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder().build().get(
|
||||||
|
HashAlgorithmTags.SHA1);
|
||||||
|
PGPContentSignerBuilder certificationSignerBuilder = new JcaPGPContentSignerBuilder(
|
||||||
|
masterKeyPair.getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA1);
|
||||||
|
|
||||||
|
// Build key encrypter based on passphrase
|
||||||
|
PBESecretKeyEncryptor keyEncryptor = new JcePBESecretKeyEncryptorBuilder(
|
||||||
|
PGPEncryptedData.CAST5, sha1Calc)
|
||||||
|
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(
|
||||||
|
newPassPhrase.toCharArray());
|
||||||
|
|
||||||
|
PGPKeyRingGenerator keyGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION,
|
||||||
|
masterKeyPair, mainUserId, sha1Calc, hashedPacketsGen.generate(),
|
||||||
|
unhashedPacketsGen.generate(), certificationSignerBuilder, keyEncryptor);
|
||||||
|
|
||||||
|
updateProgress(R.string.progress_addingSubKeys, 40, 100);
|
||||||
|
|
||||||
|
for (int i = 1; i < keys.size(); ++i) {
|
||||||
|
updateProgress(40 + 50 * (i - 1) / (keys.size() - 1), 100);
|
||||||
|
|
||||||
|
PGPSecretKey subKey = keys.get(i);
|
||||||
|
PGPPublicKey subPublicKey = subKey.getPublicKey();
|
||||||
|
|
||||||
|
PBESecretKeyDecryptor keyDecryptor2 = new JcePBESecretKeyDecryptorBuilder()
|
||||||
|
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(
|
||||||
|
oldPassPhrase.toCharArray());
|
||||||
|
PGPPrivateKey subPrivateKey = subKey.extractPrivateKey(keyDecryptor2);
|
||||||
|
|
||||||
|
// TODO: now used without algorithm and creation time?! (APG 1)
|
||||||
|
PGPKeyPair subKeyPair = new PGPKeyPair(subPublicKey, subPrivateKey);
|
||||||
|
|
||||||
|
hashedPacketsGen = new PGPSignatureSubpacketGenerator();
|
||||||
|
unhashedPacketsGen = new PGPSignatureSubpacketGenerator();
|
||||||
|
|
||||||
|
keyFlags = 0;
|
||||||
|
|
||||||
|
usageId = keysUsages.get(i);
|
||||||
|
canSign = (usageId == Id.choice.usage.sign_only || usageId == Id.choice.usage.sign_and_encrypt);
|
||||||
|
canEncrypt = (usageId == Id.choice.usage.encrypt_only || usageId == Id.choice.usage.sign_and_encrypt);
|
||||||
|
if (canSign) {
|
||||||
|
keyFlags |= KeyFlags.SIGN_DATA;
|
||||||
|
}
|
||||||
|
if (canEncrypt) {
|
||||||
|
keyFlags |= KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE;
|
||||||
|
}
|
||||||
|
hashedPacketsGen.setKeyFlags(true, keyFlags);
|
||||||
|
|
||||||
|
// TODO: this doesn't work quite right yet (APG 1)
|
||||||
|
// if (keyEditor.getExpiryDate() != null) {
|
||||||
|
// GregorianCalendar creationDate = new GregorianCalendar();
|
||||||
|
// creationDate.setTime(getCreationDate(masterKey));
|
||||||
|
// GregorianCalendar expiryDate = keyEditor.getExpiryDate();
|
||||||
|
// long numDays = Utils.getNumDaysBetween(creationDate, expiryDate);
|
||||||
|
// if (numDays <= 0) {
|
||||||
|
// throw new GeneralException(
|
||||||
|
// context.getString(R.string.error_expiryMustComeAfterCreation));
|
||||||
|
// }
|
||||||
|
// hashedPacketsGen.setKeyExpirationTime(true, numDays * 86400);
|
||||||
|
// }
|
||||||
|
|
||||||
|
keyGen.addSubKey(subKeyPair, hashedPacketsGen.generate(), unhashedPacketsGen.generate());
|
||||||
|
}
|
||||||
|
|
||||||
|
PGPSecretKeyRing secretKeyRing = keyGen.generateSecretKeyRing();
|
||||||
|
PGPPublicKeyRing publicKeyRing = keyGen.generatePublicKeyRing();
|
||||||
|
|
||||||
|
updateProgress(R.string.progress_savingKeyRing, 90, 100);
|
||||||
|
|
||||||
|
ProviderHelper.saveKeyRing(mContext, secretKeyRing);
|
||||||
|
ProviderHelper.saveKeyRing(mContext, publicKeyRing);
|
||||||
|
|
||||||
|
updateProgress(R.string.progress_done, 100, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PGPPublicKeyRing signKey(long masterKeyId, long pubKeyId, String passphrase)
|
||||||
|
throws PgpGeneralException, NoSuchAlgorithmException, NoSuchProviderException,
|
||||||
|
PGPException, SignatureException {
|
||||||
|
if (passphrase == null || passphrase.length() <= 0) {
|
||||||
|
throw new PgpGeneralException("Unable to obtain passphrase");
|
||||||
|
} else {
|
||||||
|
PGPPublicKeyRing pubring = ProviderHelper
|
||||||
|
.getPGPPublicKeyRingByKeyId(mContext, pubKeyId);
|
||||||
|
|
||||||
|
PGPSecretKey signingKey = PgpKeyHelper.getCertificationKey(mContext, masterKeyId);
|
||||||
|
if (signingKey == null) {
|
||||||
|
throw new PgpGeneralException(mContext.getString(R.string.error_signatureFailed));
|
||||||
|
}
|
||||||
|
|
||||||
|
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(
|
||||||
|
Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(passphrase.toCharArray());
|
||||||
|
PGPPrivateKey signaturePrivateKey = signingKey.extractPrivateKey(keyDecryptor);
|
||||||
|
if (signaturePrivateKey == null) {
|
||||||
|
throw new PgpGeneralException(
|
||||||
|
mContext.getString(R.string.error_couldNotExtractPrivateKey));
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: SHA256 fixed?
|
||||||
|
JcaPGPContentSignerBuilder contentSignerBuilder = new JcaPGPContentSignerBuilder(
|
||||||
|
signingKey.getPublicKey().getAlgorithm(), PGPUtil.SHA256)
|
||||||
|
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
|
||||||
|
|
||||||
|
PGPSignatureGenerator signatureGenerator = new PGPSignatureGenerator(
|
||||||
|
contentSignerBuilder);
|
||||||
|
|
||||||
|
signatureGenerator.init(PGPSignature.DIRECT_KEY, signaturePrivateKey);
|
||||||
|
|
||||||
|
PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator();
|
||||||
|
|
||||||
|
PGPSignatureSubpacketVector packetVector = spGen.generate();
|
||||||
|
signatureGenerator.setHashedSubpackets(packetVector);
|
||||||
|
|
||||||
|
PGPPublicKey signedKey = PGPPublicKey.addCertification(pubring.getPublicKey(pubKeyId),
|
||||||
|
signatureGenerator.generate());
|
||||||
|
pubring = PGPPublicKeyRing.insertPublicKey(pubring, signedKey);
|
||||||
|
|
||||||
|
return pubring;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -251,7 +251,7 @@ public class PgpToX509 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
X509Certificate selfSignedCert = createSelfSignedCert(
|
X509Certificate selfSignedCert = createSelfSignedCert(
|
||||||
pgpPubKey.getKey(PgpMain.BOUNCY_CASTLE_PROVIDER_NAME), pgpPrivKey.getKey(),
|
pgpPubKey.getKey(Constants.BOUNCY_CASTLE_PROVIDER_NAME), pgpPrivKey.getKey(),
|
||||||
x509name, creationTime, validTo, subjAltNameURI);
|
x509name, creationTime, validTo, subjAltNameURI);
|
||||||
|
|
||||||
return selfSignedCert;
|
return selfSignedCert;
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
package org.sufficientlysecure.keychain.pgp.exception;
|
||||||
|
|
||||||
|
public class NoAsymmetricEncryptionException extends Exception {
|
||||||
|
static final long serialVersionUID = 0xf812773343L;
|
||||||
|
|
||||||
|
public NoAsymmetricEncryptionException() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package org.sufficientlysecure.keychain.pgp.exception;
|
||||||
|
|
||||||
|
public class PgpGeneralException extends Exception {
|
||||||
|
static final long serialVersionUID = 0xf812773342L;
|
||||||
|
|
||||||
|
public PgpGeneralException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
@ -31,7 +31,7 @@ import org.spongycastle.openpgp.PGPSecretKeyRing;
|
|||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpConversionHelper;
|
import org.sufficientlysecure.keychain.pgp.PgpConversionHelper;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpHelper;
|
import org.sufficientlysecure.keychain.pgp.PgpHelper;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpMain;
|
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
|
||||||
import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps;
|
import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps;
|
||||||
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
|
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
|
||||||
import org.sufficientlysecure.keychain.provider.KeychainContract.Keys;
|
import org.sufficientlysecure.keychain.provider.KeychainContract.Keys;
|
||||||
@ -320,11 +320,11 @@ public class ProviderHelper {
|
|||||||
values.put(Keys.IS_MASTER_KEY, key.isMasterKey());
|
values.put(Keys.IS_MASTER_KEY, key.isMasterKey());
|
||||||
values.put(Keys.ALGORITHM, key.getAlgorithm());
|
values.put(Keys.ALGORITHM, key.getAlgorithm());
|
||||||
values.put(Keys.KEY_SIZE, key.getBitStrength());
|
values.put(Keys.KEY_SIZE, key.getBitStrength());
|
||||||
values.put(Keys.CAN_SIGN, PgpHelper.isSigningKey(key));
|
values.put(Keys.CAN_SIGN, PgpKeyHelper.isSigningKey(key));
|
||||||
values.put(Keys.CAN_ENCRYPT, PgpHelper.isEncryptionKey(key));
|
values.put(Keys.CAN_ENCRYPT, PgpKeyHelper.isEncryptionKey(key));
|
||||||
values.put(Keys.IS_REVOKED, key.isRevoked());
|
values.put(Keys.IS_REVOKED, key.isRevoked());
|
||||||
values.put(Keys.CREATION, PgpHelper.getCreationDate(key).getTime() / 1000);
|
values.put(Keys.CREATION, PgpKeyHelper.getCreationDate(key).getTime() / 1000);
|
||||||
Date expiryDate = PgpHelper.getExpiryDate(key);
|
Date expiryDate = PgpKeyHelper.getExpiryDate(key);
|
||||||
if (expiryDate != null) {
|
if (expiryDate != null) {
|
||||||
values.put(Keys.EXPIRY, expiryDate.getTime() / 1000);
|
values.put(Keys.EXPIRY, expiryDate.getTime() / 1000);
|
||||||
}
|
}
|
||||||
@ -375,7 +375,7 @@ public class ProviderHelper {
|
|||||||
|
|
||||||
boolean has_private = true;
|
boolean has_private = true;
|
||||||
if (key.isMasterKey()) {
|
if (key.isMasterKey()) {
|
||||||
if (PgpHelper.isSecretKeyPrivateEmpty(key)) {
|
if (PgpKeyHelper.isSecretKeyPrivateEmpty(key)) {
|
||||||
has_private = false;
|
has_private = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -384,12 +384,12 @@ public class ProviderHelper {
|
|||||||
values.put(Keys.IS_MASTER_KEY, key.isMasterKey());
|
values.put(Keys.IS_MASTER_KEY, key.isMasterKey());
|
||||||
values.put(Keys.ALGORITHM, key.getPublicKey().getAlgorithm());
|
values.put(Keys.ALGORITHM, key.getPublicKey().getAlgorithm());
|
||||||
values.put(Keys.KEY_SIZE, key.getPublicKey().getBitStrength());
|
values.put(Keys.KEY_SIZE, key.getPublicKey().getBitStrength());
|
||||||
values.put(Keys.CAN_CERTIFY, (PgpHelper.isCertificationKey(key) && has_private));
|
values.put(Keys.CAN_CERTIFY, (PgpKeyHelper.isCertificationKey(key) && has_private));
|
||||||
values.put(Keys.CAN_SIGN, (PgpHelper.isSigningKey(key) && has_private));
|
values.put(Keys.CAN_SIGN, (PgpKeyHelper.isSigningKey(key) && has_private));
|
||||||
values.put(Keys.CAN_ENCRYPT, PgpHelper.isEncryptionKey(key));
|
values.put(Keys.CAN_ENCRYPT, PgpKeyHelper.isEncryptionKey(key));
|
||||||
values.put(Keys.IS_REVOKED, key.getPublicKey().isRevoked());
|
values.put(Keys.IS_REVOKED, key.getPublicKey().isRevoked());
|
||||||
values.put(Keys.CREATION, PgpHelper.getCreationDate(key).getTime() / 1000);
|
values.put(Keys.CREATION, PgpKeyHelper.getCreationDate(key).getTime() / 1000);
|
||||||
Date expiryDate = PgpHelper.getExpiryDate(key);
|
Date expiryDate = PgpKeyHelper.getExpiryDate(key);
|
||||||
if (expiryDate != null) {
|
if (expiryDate != null) {
|
||||||
values.put(Keys.EXPIRY, expiryDate.getTime() / 1000);
|
values.put(Keys.EXPIRY, expiryDate.getTime() / 1000);
|
||||||
}
|
}
|
||||||
@ -617,7 +617,7 @@ public class ProviderHelper {
|
|||||||
|
|
||||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
ArmoredOutputStream aos = new ArmoredOutputStream(bos);
|
ArmoredOutputStream aos = new ArmoredOutputStream(bos);
|
||||||
aos.setHeader("Version", PgpMain.getFullVersion(context));
|
aos.setHeader("Version", PgpHelper.getFullVersion(context));
|
||||||
|
|
||||||
if (keyRing instanceof PGPSecretKeyRing) {
|
if (keyRing instanceof PGPSecretKeyRing) {
|
||||||
aos.write(((PGPSecretKeyRing) keyRing).getEncoded());
|
aos.write(((PGPSecretKeyRing) keyRing).getEncoded());
|
||||||
|
@ -38,8 +38,11 @@ import org.sufficientlysecure.keychain.helper.FileHelper;
|
|||||||
import org.sufficientlysecure.keychain.helper.OtherHelper;
|
import org.sufficientlysecure.keychain.helper.OtherHelper;
|
||||||
import org.sufficientlysecure.keychain.helper.Preferences;
|
import org.sufficientlysecure.keychain.helper.Preferences;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpConversionHelper;
|
import org.sufficientlysecure.keychain.pgp.PgpConversionHelper;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpMain;
|
import org.sufficientlysecure.keychain.pgp.PgpHelper;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpMain.PgpGeneralException;
|
import org.sufficientlysecure.keychain.pgp.PgpImportExport;
|
||||||
|
import org.sufficientlysecure.keychain.pgp.PgpKeyOperation;
|
||||||
|
import org.sufficientlysecure.keychain.pgp.PgpOperation;
|
||||||
|
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
|
||||||
import org.sufficientlysecure.keychain.provider.KeychainContract.DataStream;
|
import org.sufficientlysecure.keychain.provider.KeychainContract.DataStream;
|
||||||
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||||
import org.sufficientlysecure.keychain.util.HkpKeyServer;
|
import org.sufficientlysecure.keychain.util.HkpKeyServer;
|
||||||
@ -288,16 +291,15 @@ public class KeychainIntentService extends IntentService implements ProgressDial
|
|||||||
|
|
||||||
// InputStream
|
// InputStream
|
||||||
InputStream in = getContentResolver().openInputStream(providerUri);
|
InputStream in = getContentResolver().openInputStream(providerUri);
|
||||||
inLength = PgpMain.getLengthOfStream(in);
|
inLength = PgpHelper.getLengthOfStream(in);
|
||||||
inputData = new InputData(in, inLength);
|
inputData = new InputData(in, inLength);
|
||||||
|
|
||||||
// OutputStream
|
// OutputStream
|
||||||
try {
|
try {
|
||||||
while (true) {
|
while (true) {
|
||||||
streamFilename = PgpMain.generateRandomFilename(32);
|
streamFilename = PgpHelper.generateRandomFilename(32);
|
||||||
if (streamFilename == null) {
|
if (streamFilename == null) {
|
||||||
throw new PgpMain.PgpGeneralException(
|
throw new PgpGeneralException("couldn't generate random file name");
|
||||||
"couldn't generate random file name");
|
|
||||||
}
|
}
|
||||||
openFileInput(streamFilename).close();
|
openFileInput(streamFilename).close();
|
||||||
}
|
}
|
||||||
@ -309,31 +311,30 @@ public class KeychainIntentService extends IntentService implements ProgressDial
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new PgpMain.PgpGeneralException("No target choosen!");
|
throw new PgpGeneralException("No target choosen!");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Operation */
|
/* Operation */
|
||||||
|
PgpOperation operation = new PgpOperation(this, this, inputData, outStream);
|
||||||
if (generateSignature) {
|
if (generateSignature) {
|
||||||
Log.d(Constants.TAG, "generating signature...");
|
Log.d(Constants.TAG, "generating signature...");
|
||||||
PgpMain.generateSignature(this, this, inputData, outStream, useAsciiArmor,
|
operation.generateSignature(useAsciiArmor, false, secretKeyId,
|
||||||
false, secretKeyId, PassphraseCacheService.getCachedPassphrase(this,
|
|
||||||
secretKeyId), Preferences.getPreferences(this)
|
|
||||||
.getDefaultHashAlgorithm(), Preferences.getPreferences(this)
|
|
||||||
.getForceV3Signatures());
|
|
||||||
} else if (signOnly) {
|
|
||||||
Log.d(Constants.TAG, "sign only...");
|
|
||||||
PgpMain.signText(this, this, inputData, outStream, secretKeyId,
|
|
||||||
PassphraseCacheService.getCachedPassphrase(this, secretKeyId),
|
PassphraseCacheService.getCachedPassphrase(this, secretKeyId),
|
||||||
Preferences.getPreferences(this).getDefaultHashAlgorithm(), Preferences
|
Preferences.getPreferences(this).getDefaultHashAlgorithm(), Preferences
|
||||||
.getPreferences(this).getForceV3Signatures());
|
.getPreferences(this).getForceV3Signatures());
|
||||||
|
} else if (signOnly) {
|
||||||
|
Log.d(Constants.TAG, "sign only...");
|
||||||
|
operation.signText(secretKeyId, PassphraseCacheService.getCachedPassphrase(
|
||||||
|
this, secretKeyId), Preferences.getPreferences(this)
|
||||||
|
.getDefaultHashAlgorithm(), Preferences.getPreferences(this)
|
||||||
|
.getForceV3Signatures());
|
||||||
} else {
|
} else {
|
||||||
Log.d(Constants.TAG, "encrypt...");
|
Log.d(Constants.TAG, "encrypt...");
|
||||||
PgpMain.encryptAndSign(this, this, inputData, outStream, useAsciiArmor,
|
operation.encryptAndSign(useAsciiArmor, compressionId, encryptionKeyIds,
|
||||||
compressionId, encryptionKeyIds, encryptionPassphrase, Preferences
|
encryptionPassphrase, Preferences.getPreferences(this)
|
||||||
.getPreferences(this).getDefaultEncryptionAlgorithm(),
|
.getDefaultEncryptionAlgorithm(), secretKeyId, Preferences
|
||||||
secretKeyId,
|
.getPreferences(this).getDefaultHashAlgorithm(), Preferences
|
||||||
Preferences.getPreferences(this).getDefaultHashAlgorithm(), Preferences
|
|
||||||
.getPreferences(this).getForceV3Signatures(),
|
.getPreferences(this).getForceV3Signatures(),
|
||||||
PassphraseCacheService.getCachedPassphrase(this, secretKeyId));
|
PassphraseCacheService.getCachedPassphrase(this, secretKeyId));
|
||||||
}
|
}
|
||||||
@ -437,16 +438,15 @@ public class KeychainIntentService extends IntentService implements ProgressDial
|
|||||||
|
|
||||||
// InputStream
|
// InputStream
|
||||||
InputStream in = getContentResolver().openInputStream(providerUri);
|
InputStream in = getContentResolver().openInputStream(providerUri);
|
||||||
inLength = PgpMain.getLengthOfStream(in);
|
inLength = PgpHelper.getLengthOfStream(in);
|
||||||
inputData = new InputData(in, inLength);
|
inputData = new InputData(in, inLength);
|
||||||
|
|
||||||
// OutputStream
|
// OutputStream
|
||||||
try {
|
try {
|
||||||
while (true) {
|
while (true) {
|
||||||
streamFilename = PgpMain.generateRandomFilename(32);
|
streamFilename = PgpHelper.generateRandomFilename(32);
|
||||||
if (streamFilename == null) {
|
if (streamFilename == null) {
|
||||||
throw new PgpMain.PgpGeneralException(
|
throw new PgpGeneralException("couldn't generate random file name");
|
||||||
"couldn't generate random file name");
|
|
||||||
}
|
}
|
||||||
openFileInput(streamFilename).close();
|
openFileInput(streamFilename).close();
|
||||||
}
|
}
|
||||||
@ -458,7 +458,7 @@ public class KeychainIntentService extends IntentService implements ProgressDial
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new PgpMain.PgpGeneralException("No target choosen!");
|
throw new PgpGeneralException("No target choosen!");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -468,11 +468,11 @@ public class KeychainIntentService extends IntentService implements ProgressDial
|
|||||||
|
|
||||||
// verifyText and decrypt returning additional resultData values for the
|
// verifyText and decrypt returning additional resultData values for the
|
||||||
// verification of signatures
|
// verification of signatures
|
||||||
|
PgpOperation operation = new PgpOperation(this, this, inputData, outStream);
|
||||||
if (signedOnly) {
|
if (signedOnly) {
|
||||||
resultData = PgpMain.verifyText(this, this, inputData, outStream,
|
resultData = operation.verifyText(lookupUnknownKey);
|
||||||
lookupUnknownKey);
|
|
||||||
} else {
|
} else {
|
||||||
resultData = PgpMain.decryptAndVerify(this, this, inputData, outStream,
|
resultData = operation.decryptAndVerify(
|
||||||
PassphraseCacheService.getCachedPassphrase(this, secretKeyId),
|
PassphraseCacheService.getCachedPassphrase(this, secretKeyId),
|
||||||
assumeSymmetricEncryption);
|
assumeSymmetricEncryption);
|
||||||
}
|
}
|
||||||
@ -530,14 +530,15 @@ public class KeychainIntentService extends IntentService implements ProgressDial
|
|||||||
ArrayList<Integer> keysUsages = data.getIntegerArrayList(SAVE_KEYRING_KEYS_USAGES);
|
ArrayList<Integer> keysUsages = data.getIntegerArrayList(SAVE_KEYRING_KEYS_USAGES);
|
||||||
long masterKeyId = data.getLong(SAVE_KEYRING_MASTER_KEY_ID);
|
long masterKeyId = data.getLong(SAVE_KEYRING_MASTER_KEY_ID);
|
||||||
|
|
||||||
|
PgpKeyOperation keyOperations = new PgpKeyOperation(this, this);
|
||||||
/* Operation */
|
/* Operation */
|
||||||
if (!canSign) {
|
if (!canSign) {
|
||||||
PgpMain.changeSecretKeyPassphrase(this,
|
keyOperations.changeSecretKeyPassphrase(
|
||||||
ProviderHelper.getPGPSecretKeyRingByKeyId(this, masterKeyId),
|
ProviderHelper.getPGPSecretKeyRingByKeyId(this, masterKeyId),
|
||||||
oldPassPhrase, newPassPhrase, this);
|
oldPassPhrase, newPassPhrase);
|
||||||
} else {
|
} else {
|
||||||
PgpMain.buildSecretKey(this, userIds, keys, keysUsages, masterKeyId,
|
keyOperations.buildSecretKey(userIds, keys, keysUsages, masterKeyId,
|
||||||
oldPassPhrase, newPassPhrase, this);
|
oldPassPhrase, newPassPhrase);
|
||||||
}
|
}
|
||||||
PassphraseCacheService.addCachedPassphrase(this, masterKeyId, newPassPhrase);
|
PassphraseCacheService.addCachedPassphrase(this, masterKeyId, newPassPhrase);
|
||||||
|
|
||||||
@ -559,7 +560,8 @@ public class KeychainIntentService extends IntentService implements ProgressDial
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Operation */
|
/* Operation */
|
||||||
PGPSecretKeyRing newKeyRing = PgpMain.createKey(this, algorithm, keysize,
|
PgpKeyOperation keyOperations = new PgpKeyOperation(this, this);
|
||||||
|
PGPSecretKeyRing newKeyRing = keyOperations.createKey(algorithm, keysize,
|
||||||
passphrase, masterKey);
|
passphrase, masterKey);
|
||||||
|
|
||||||
/* Output */
|
/* Output */
|
||||||
@ -580,10 +582,12 @@ public class KeychainIntentService extends IntentService implements ProgressDial
|
|||||||
String passphrase = data.getString(GENERATE_KEY_SYMMETRIC_PASSPHRASE);
|
String passphrase = data.getString(GENERATE_KEY_SYMMETRIC_PASSPHRASE);
|
||||||
|
|
||||||
/* Operation */
|
/* Operation */
|
||||||
PGPSecretKeyRing masterKeyRing = PgpMain.createKey(this, Id.choice.algorithm.rsa,
|
PgpKeyOperation keyOperations = new PgpKeyOperation(this, this);
|
||||||
|
|
||||||
|
PGPSecretKeyRing masterKeyRing = keyOperations.createKey(Id.choice.algorithm.rsa,
|
||||||
4096, passphrase, null);
|
4096, passphrase, null);
|
||||||
|
|
||||||
PGPSecretKeyRing subKeyRing = PgpMain.createKey(this, Id.choice.algorithm.rsa,
|
PGPSecretKeyRing subKeyRing = keyOperations.createKey(Id.choice.algorithm.rsa,
|
||||||
4096, passphrase, masterKeyRing.getSecretKey());
|
4096, passphrase, masterKeyRing.getSecretKey());
|
||||||
|
|
||||||
/* Output */
|
/* Output */
|
||||||
@ -606,13 +610,13 @@ public class KeychainIntentService extends IntentService implements ProgressDial
|
|||||||
|
|
||||||
/* Operation */
|
/* Operation */
|
||||||
try {
|
try {
|
||||||
PgpMain.deleteFileSecurely(this, this, new File(deleteFile));
|
PgpHelper.deleteFileSecurely(this, this, new File(deleteFile));
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
throw new PgpMain.PgpGeneralException(getString(R.string.error_fileNotFound,
|
throw new PgpGeneralException(
|
||||||
deleteFile));
|
getString(R.string.error_fileNotFound, deleteFile));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new PgpMain.PgpGeneralException(getString(
|
throw new PgpGeneralException(getString(R.string.error_fileDeleteFailed,
|
||||||
R.string.error_fileDeleteFailed, deleteFile));
|
deleteFile));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Output */
|
/* Output */
|
||||||
@ -661,7 +665,9 @@ public class KeychainIntentService extends IntentService implements ProgressDial
|
|||||||
}
|
}
|
||||||
|
|
||||||
Bundle resultData = new Bundle();
|
Bundle resultData = new Bundle();
|
||||||
resultData = PgpMain.importKeyRings(this, inputData, this);
|
|
||||||
|
PgpImportExport pgpImportExport = new PgpImportExport(this, this);
|
||||||
|
resultData = pgpImportExport.importKeyRings(inputData);
|
||||||
|
|
||||||
sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, resultData);
|
sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, resultData);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -708,8 +714,10 @@ public class KeychainIntentService extends IntentService implements ProgressDial
|
|||||||
}
|
}
|
||||||
|
|
||||||
Bundle resultData = new Bundle();
|
Bundle resultData = new Bundle();
|
||||||
resultData = PgpMain.exportKeyRings(this, keyRingMasterKeyIds, keyType, outStream,
|
|
||||||
this);
|
PgpImportExport pgpImportExport = new PgpImportExport(this, this);
|
||||||
|
resultData = pgpImportExport
|
||||||
|
.exportKeyRings(keyRingMasterKeyIds, keyType, outStream);
|
||||||
|
|
||||||
sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, resultData);
|
sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, resultData);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -728,7 +736,9 @@ public class KeychainIntentService extends IntentService implements ProgressDial
|
|||||||
PGPPublicKeyRing keyring = ProviderHelper.getPGPPublicKeyRingByRowId(this,
|
PGPPublicKeyRing keyring = ProviderHelper.getPGPPublicKeyRingByRowId(this,
|
||||||
keyRingRowId);
|
keyRingRowId);
|
||||||
if (keyring != null) {
|
if (keyring != null) {
|
||||||
boolean uploaded = PgpMain.uploadKeyRingToServer(server,
|
PgpImportExport pgpImportExport = new PgpImportExport(this, null);
|
||||||
|
|
||||||
|
boolean uploaded = pgpImportExport.uploadKeyRingToServer(server,
|
||||||
(PGPPublicKeyRing) keyring);
|
(PGPPublicKeyRing) keyring);
|
||||||
if (!uploaded) {
|
if (!uploaded) {
|
||||||
throw new PgpGeneralException("Unable to export key to selected server");
|
throw new PgpGeneralException("Unable to export key to selected server");
|
||||||
@ -778,11 +788,13 @@ public class KeychainIntentService extends IntentService implements ProgressDial
|
|||||||
String signaturePassPhrase = PassphraseCacheService.getCachedPassphrase(this,
|
String signaturePassPhrase = PassphraseCacheService.getCachedPassphrase(this,
|
||||||
masterKeyId);
|
masterKeyId);
|
||||||
|
|
||||||
PGPPublicKeyRing signedPubKeyRing = PgpMain.signKey(this, masterKeyId, pubKeyId,
|
PgpKeyOperation keyOperation = new PgpKeyOperation(this, this);
|
||||||
|
PGPPublicKeyRing signedPubKeyRing = keyOperation.signKey(masterKeyId, pubKeyId,
|
||||||
signaturePassPhrase);
|
signaturePassPhrase);
|
||||||
|
|
||||||
// store the signed key in our local cache
|
// store the signed key in our local cache
|
||||||
int retval = PgpMain.storeKeyRingInCache(this, signedPubKeyRing);
|
PgpImportExport pgpImportExport = new PgpImportExport(this, null);
|
||||||
|
int retval = pgpImportExport.storeKeyRingInCache(signedPubKeyRing);
|
||||||
if (retval != Id.return_value.ok && retval != Id.return_value.updated) {
|
if (retval != Id.return_value.ok && retval != Id.return_value.updated) {
|
||||||
throw new PgpGeneralException("Failed to store signed key in local cache");
|
throw new PgpGeneralException("Failed to store signed key in local cache");
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
|
|||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
import org.sufficientlysecure.keychain.Id;
|
import org.sufficientlysecure.keychain.Id;
|
||||||
import org.sufficientlysecure.keychain.helper.Preferences;
|
import org.sufficientlysecure.keychain.helper.Preferences;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpHelper;
|
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
|
||||||
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||||
|
|
||||||
import android.app.AlarmManager;
|
import android.app.AlarmManager;
|
||||||
@ -173,7 +173,7 @@ public class PassphraseCacheService extends Service {
|
|||||||
if (keyRing == null) {
|
if (keyRing == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
PGPSecretKey masterKey = PgpHelper.getMasterKey(keyRing);
|
PGPSecretKey masterKey = PgpKeyHelper.getMasterKey(keyRing);
|
||||||
if (masterKey == null) {
|
if (masterKey == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -210,7 +210,7 @@ public class PassphraseCacheService extends Service {
|
|||||||
public static boolean hasPassphrase(Context context, long secretKeyId) {
|
public static boolean hasPassphrase(Context context, long secretKeyId) {
|
||||||
// check if the key has no passphrase
|
// check if the key has no passphrase
|
||||||
try {
|
try {
|
||||||
PGPSecretKey secretKey = PgpHelper.getMasterKey(ProviderHelper
|
PGPSecretKey secretKey = PgpKeyHelper.getMasterKey(ProviderHelper
|
||||||
.getPGPSecretKeyRingByKeyId(context, secretKeyId));
|
.getPGPSecretKeyRingByKeyId(context, secretKeyId));
|
||||||
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(
|
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(
|
||||||
"SC").build("".toCharArray());
|
"SC").build("".toCharArray());
|
||||||
|
@ -26,7 +26,7 @@ import org.spongycastle.openpgp.PGPSecretKeyRing;
|
|||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
import org.sufficientlysecure.keychain.Id;
|
import org.sufficientlysecure.keychain.Id;
|
||||||
import org.sufficientlysecure.keychain.R;
|
import org.sufficientlysecure.keychain.R;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpHelper;
|
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
|
||||||
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||||
import org.sufficientlysecure.keychain.ui.SelectSecretKeyActivity;
|
import org.sufficientlysecure.keychain.ui.SelectSecretKeyActivity;
|
||||||
import org.sufficientlysecure.keychain.util.KeyValueSpinnerAdapter;
|
import org.sufficientlysecure.keychain.util.KeyValueSpinnerAdapter;
|
||||||
@ -259,9 +259,9 @@ public class AppSettingsFragment extends Fragment {
|
|||||||
PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(
|
PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(
|
||||||
getActivity(), secretKeyId);
|
getActivity(), secretKeyId);
|
||||||
if (keyRing != null) {
|
if (keyRing != null) {
|
||||||
PGPSecretKey key = PgpHelper.getMasterKey(keyRing);
|
PGPSecretKey key = PgpKeyHelper.getMasterKey(keyRing);
|
||||||
if (key != null) {
|
if (key != null) {
|
||||||
String userId = PgpHelper.getMainUserIdSafe(getActivity(), key);
|
String userId = PgpKeyHelper.getMainUserIdSafe(getActivity(), key);
|
||||||
String chunks[] = userId.split(" <", 2);
|
String chunks[] = userId.split(" <", 2);
|
||||||
uid = chunks[0];
|
uid = chunks[0];
|
||||||
if (chunks.length > 1) {
|
if (chunks.length > 1) {
|
||||||
|
@ -29,8 +29,7 @@ import org.spongycastle.openpgp.PGPPrivateKey;
|
|||||||
import org.spongycastle.openpgp.PGPSecretKey;
|
import org.spongycastle.openpgp.PGPSecretKey;
|
||||||
import org.spongycastle.openssl.PEMWriter;
|
import org.spongycastle.openssl.PEMWriter;
|
||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpHelper;
|
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpMain;
|
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpToX509;
|
import org.sufficientlysecure.keychain.pgp.PgpToX509;
|
||||||
import org.sufficientlysecure.keychain.util.Log;
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
|
|
||||||
@ -53,13 +52,13 @@ public class ExtendedApiService extends RemoteService {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
long keyId = appSettings.getKeyId();
|
long keyId = appSettings.getKeyId();
|
||||||
PGPSecretKey pgpSecretKey = PgpHelper.getSigningKey(this, keyId);
|
PGPSecretKey pgpSecretKey = PgpKeyHelper.getSigningKey(this, keyId);
|
||||||
|
|
||||||
PasswordCallback pgpSecKeyPasswordCallBack = new PasswordCallback("pgp passphrase?",
|
PasswordCallback pgpSecKeyPasswordCallBack = new PasswordCallback("pgp passphrase?",
|
||||||
false);
|
false);
|
||||||
pgpPwdCallbackHandler.handle(new Callback[] { pgpSecKeyPasswordCallBack });
|
pgpPwdCallbackHandler.handle(new Callback[] { pgpSecKeyPasswordCallBack });
|
||||||
PGPPrivateKey pgpPrivKey = pgpSecretKey.extractPrivateKey(
|
PGPPrivateKey pgpPrivKey = pgpSecretKey.extractPrivateKey(
|
||||||
pgpSecKeyPasswordCallBack.getPassword(), PgpMain.BOUNCY_CASTLE_PROVIDER_NAME);
|
pgpSecKeyPasswordCallBack.getPassword(), Constants.BOUNCY_CASTLE_PROVIDER_NAME);
|
||||||
pgpSecKeyPasswordCallBack.clearPassword();
|
pgpSecKeyPasswordCallBack.clearPassword();
|
||||||
|
|
||||||
X509Certificate selfSignedCert = PgpToX509.createSelfSignedCert(pgpSecretKey,
|
X509Certificate selfSignedCert = PgpToX509.createSelfSignedCert(pgpSecretKey,
|
||||||
|
@ -32,7 +32,10 @@ import org.sufficientlysecure.keychain.Constants;
|
|||||||
import org.sufficientlysecure.keychain.Id;
|
import org.sufficientlysecure.keychain.Id;
|
||||||
import org.sufficientlysecure.keychain.R;
|
import org.sufficientlysecure.keychain.R;
|
||||||
import org.sufficientlysecure.keychain.helper.Preferences;
|
import org.sufficientlysecure.keychain.helper.Preferences;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpMain;
|
import org.sufficientlysecure.keychain.pgp.PgpHelper;
|
||||||
|
import org.sufficientlysecure.keychain.pgp.PgpOperation;
|
||||||
|
import org.sufficientlysecure.keychain.pgp.exception.NoAsymmetricEncryptionException;
|
||||||
|
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
|
||||||
import org.sufficientlysecure.keychain.provider.KeychainContract;
|
import org.sufficientlysecure.keychain.provider.KeychainContract;
|
||||||
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
||||||
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
|
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
|
||||||
@ -230,6 +233,7 @@ public class OpenPgpService extends RemoteService {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PgpOperation operation = new PgpOperation(getContext(), null, inputData, outputStream);
|
||||||
if (sign) {
|
if (sign) {
|
||||||
String passphrase = getCachedPassphrase(appSettings.getKeyId());
|
String passphrase = getCachedPassphrase(appSettings.getKeyId());
|
||||||
if (passphrase == null) {
|
if (passphrase == null) {
|
||||||
@ -238,13 +242,11 @@ public class OpenPgpService extends RemoteService {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
PgpMain.encryptAndSign(getContext(), null, inputData, outputStream, asciiArmor,
|
operation.encryptAndSign(asciiArmor, appSettings.getCompression(), keyIds, null,
|
||||||
appSettings.getCompression(), keyIds, null,
|
|
||||||
appSettings.getEncryptionAlgorithm(), appSettings.getKeyId(),
|
appSettings.getEncryptionAlgorithm(), appSettings.getKeyId(),
|
||||||
appSettings.getHashAlgorithm(), true, passphrase);
|
appSettings.getHashAlgorithm(), true, passphrase);
|
||||||
} else {
|
} else {
|
||||||
PgpMain.encryptAndSign(getContext(), null, inputData, outputStream, asciiArmor,
|
operation.encryptAndSign(asciiArmor, appSettings.getCompression(), keyIds, null,
|
||||||
appSettings.getCompression(), keyIds, null,
|
|
||||||
appSettings.getEncryptionAlgorithm(), Id.key.none,
|
appSettings.getEncryptionAlgorithm(), Id.key.none,
|
||||||
appSettings.getHashAlgorithm(), true, null);
|
appSettings.getHashAlgorithm(), true, null);
|
||||||
}
|
}
|
||||||
@ -286,9 +288,9 @@ public class OpenPgpService extends RemoteService {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
PgpMain.signText(this, null, inputData, outputStream, appSettings.getKeyId(),
|
PgpOperation operation = new PgpOperation(getContext(), null, inputData, outputStream);
|
||||||
passphrase, appSettings.getHashAlgorithm(), Preferences.getPreferences(this)
|
operation.signText(appSettings.getKeyId(), passphrase, appSettings.getHashAlgorithm(),
|
||||||
.getForceV3Signatures());
|
Preferences.getPreferences(this).getForceV3Signatures());
|
||||||
|
|
||||||
outputStream.close();
|
outputStream.close();
|
||||||
|
|
||||||
@ -315,7 +317,7 @@ public class OpenPgpService extends RemoteService {
|
|||||||
String message = new String(inputBytes);
|
String message = new String(inputBytes);
|
||||||
Log.d(Constants.TAG, "in: " + message);
|
Log.d(Constants.TAG, "in: " + message);
|
||||||
boolean signedOnly = false;
|
boolean signedOnly = false;
|
||||||
Matcher matcher = PgpMain.PGP_MESSAGE.matcher(message);
|
Matcher matcher = PgpHelper.PGP_MESSAGE.matcher(message);
|
||||||
if (matcher.matches()) {
|
if (matcher.matches()) {
|
||||||
Log.d(Constants.TAG, "PGP_MESSAGE matched");
|
Log.d(Constants.TAG, "PGP_MESSAGE matched");
|
||||||
message = matcher.group(1);
|
message = matcher.group(1);
|
||||||
@ -325,7 +327,7 @@ public class OpenPgpService extends RemoteService {
|
|||||||
// overwrite inputBytes
|
// overwrite inputBytes
|
||||||
inputBytes = message.getBytes();
|
inputBytes = message.getBytes();
|
||||||
} else {
|
} else {
|
||||||
matcher = PgpMain.PGP_SIGNED_MESSAGE.matcher(message);
|
matcher = PgpHelper.PGP_SIGNED_MESSAGE.matcher(message);
|
||||||
if (matcher.matches()) {
|
if (matcher.matches()) {
|
||||||
signedOnly = true;
|
signedOnly = true;
|
||||||
Log.d(Constants.TAG, "PGP_SIGNED_MESSAGE matched");
|
Log.d(Constants.TAG, "PGP_SIGNED_MESSAGE matched");
|
||||||
@ -368,19 +370,18 @@ public class OpenPgpService extends RemoteService {
|
|||||||
// than 0.
|
// than 0.
|
||||||
inputStream2.mark(200);
|
inputStream2.mark(200);
|
||||||
}
|
}
|
||||||
secretKeyId = PgpMain.getDecryptionKeyId(this, inputStream2);
|
secretKeyId = PgpHelper.getDecryptionKeyId(this, inputStream2);
|
||||||
if (secretKeyId == Id.key.none) {
|
if (secretKeyId == Id.key.none) {
|
||||||
throw new PgpMain.PgpGeneralException(
|
throw new PgpGeneralException(getString(R.string.error_noSecretKeyFound));
|
||||||
getString(R.string.error_noSecretKeyFound));
|
|
||||||
}
|
}
|
||||||
assumeSymmetricEncryption = false;
|
assumeSymmetricEncryption = false;
|
||||||
} catch (PgpMain.NoAsymmetricEncryptionException e) {
|
} catch (NoAsymmetricEncryptionException e) {
|
||||||
if (inputStream2.markSupported()) {
|
if (inputStream2.markSupported()) {
|
||||||
inputStream2.reset();
|
inputStream2.reset();
|
||||||
}
|
}
|
||||||
secretKeyId = Id.key.symmetric;
|
secretKeyId = Id.key.symmetric;
|
||||||
if (!PgpMain.hasSymmetricEncryption(this, inputStream2)) {
|
if (!PgpOperation.hasSymmetricEncryption(this, inputStream2)) {
|
||||||
throw new PgpMain.PgpGeneralException(
|
throw new PgpGeneralException(
|
||||||
getString(R.string.error_noKnownEncryptionFound));
|
getString(R.string.error_noKnownEncryptionFound));
|
||||||
}
|
}
|
||||||
assumeSymmetricEncryption = true;
|
assumeSymmetricEncryption = true;
|
||||||
@ -404,13 +405,13 @@ public class OpenPgpService extends RemoteService {
|
|||||||
OutputStream outputStream = new ByteArrayOutputStream();
|
OutputStream outputStream = new ByteArrayOutputStream();
|
||||||
|
|
||||||
Bundle outputBundle;
|
Bundle outputBundle;
|
||||||
|
PgpOperation operation = new PgpOperation(getContext(), null, inputData, outputStream);
|
||||||
if (signedOnly) {
|
if (signedOnly) {
|
||||||
// TODO: download missing keys from keyserver?
|
// TODO: download missing keys from keyserver?
|
||||||
outputBundle = PgpMain.verifyText(this, null, inputData, outputStream, false);
|
outputBundle = operation.verifyText(false);
|
||||||
} else {
|
} else {
|
||||||
// TODO: assume symmetric: callback to enter symmetric pass
|
// TODO: assume symmetric: callback to enter symmetric pass
|
||||||
outputBundle = PgpMain.decryptAndVerify(this, null, inputData, outputStream,
|
outputBundle = operation.decryptAndVerify(passphrase, assumeSymmetricEncryption);
|
||||||
passphrase, assumeSymmetricEncryption);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
outputStream.close();
|
outputStream.close();
|
||||||
|
@ -24,7 +24,7 @@ import org.sufficientlysecure.keychain.Constants;
|
|||||||
import org.sufficientlysecure.keychain.Id;
|
import org.sufficientlysecure.keychain.Id;
|
||||||
import org.sufficientlysecure.keychain.R;
|
import org.sufficientlysecure.keychain.R;
|
||||||
import org.sufficientlysecure.keychain.helper.ActionBarHelper;
|
import org.sufficientlysecure.keychain.helper.ActionBarHelper;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpMain;
|
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
|
||||||
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||||
import org.sufficientlysecure.keychain.ui.SelectPublicKeyFragment;
|
import org.sufficientlysecure.keychain.ui.SelectPublicKeyFragment;
|
||||||
import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment;
|
import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment;
|
||||||
@ -316,7 +316,7 @@ public class RemoteServiceActivity extends SherlockFragmentActivity {
|
|||||||
messenger, secretKeyId);
|
messenger, secretKeyId);
|
||||||
|
|
||||||
passphraseDialog.show(getSupportFragmentManager(), "passphraseDialog");
|
passphraseDialog.show(getSupportFragmentManager(), "passphraseDialog");
|
||||||
} catch (PgpMain.PgpGeneralException e) {
|
} catch (PgpGeneralException e) {
|
||||||
Log.d(Constants.TAG, "No passphrase for this secret key, encrypt directly!");
|
Log.d(Constants.TAG, "No passphrase for this secret key, encrypt directly!");
|
||||||
// send message to handler to start encryption directly
|
// send message to handler to start encryption directly
|
||||||
returnHandler.sendEmptyMessage(PassphraseDialogFragment.MESSAGE_OKAY);
|
returnHandler.sendEmptyMessage(PassphraseDialogFragment.MESSAGE_OKAY);
|
||||||
|
@ -33,7 +33,10 @@ import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
|
|||||||
import org.sufficientlysecure.keychain.helper.ActionBarHelper;
|
import org.sufficientlysecure.keychain.helper.ActionBarHelper;
|
||||||
import org.sufficientlysecure.keychain.helper.FileHelper;
|
import org.sufficientlysecure.keychain.helper.FileHelper;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpHelper;
|
import org.sufficientlysecure.keychain.pgp.PgpHelper;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpMain;
|
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
|
||||||
|
import org.sufficientlysecure.keychain.pgp.PgpOperation;
|
||||||
|
import org.sufficientlysecure.keychain.pgp.exception.NoAsymmetricEncryptionException;
|
||||||
|
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
|
||||||
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||||
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
||||||
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
|
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
|
||||||
@ -252,9 +255,9 @@ public class DecryptActivity extends SherlockFragmentActivity {
|
|||||||
|
|
||||||
String data = "";
|
String data = "";
|
||||||
if (clipboardText != null) {
|
if (clipboardText != null) {
|
||||||
Matcher matcher = PgpMain.PGP_MESSAGE.matcher(clipboardText);
|
Matcher matcher = PgpHelper.PGP_MESSAGE.matcher(clipboardText);
|
||||||
if (!matcher.matches()) {
|
if (!matcher.matches()) {
|
||||||
matcher = PgpMain.PGP_SIGNED_MESSAGE.matcher(clipboardText);
|
matcher = PgpHelper.PGP_SIGNED_MESSAGE.matcher(clipboardText);
|
||||||
}
|
}
|
||||||
if (matcher.matches()) {
|
if (matcher.matches()) {
|
||||||
data = matcher.group(1);
|
data = matcher.group(1);
|
||||||
@ -357,7 +360,7 @@ public class DecryptActivity extends SherlockFragmentActivity {
|
|||||||
*/
|
*/
|
||||||
if (ACTION_DECRYPT.equals(action) && textData != null) {
|
if (ACTION_DECRYPT.equals(action) && textData != null) {
|
||||||
Log.d(Constants.TAG, "textData null, matching text ...");
|
Log.d(Constants.TAG, "textData null, matching text ...");
|
||||||
Matcher matcher = PgpMain.PGP_MESSAGE.matcher(textData);
|
Matcher matcher = PgpHelper.PGP_MESSAGE.matcher(textData);
|
||||||
if (matcher.matches()) {
|
if (matcher.matches()) {
|
||||||
Log.d(Constants.TAG, "PGP_MESSAGE matched");
|
Log.d(Constants.TAG, "PGP_MESSAGE matched");
|
||||||
textData = matcher.group(1);
|
textData = matcher.group(1);
|
||||||
@ -365,7 +368,7 @@ public class DecryptActivity extends SherlockFragmentActivity {
|
|||||||
textData = textData.replaceAll("\\xa0", " ");
|
textData = textData.replaceAll("\\xa0", " ");
|
||||||
mMessage.setText(textData);
|
mMessage.setText(textData);
|
||||||
} else {
|
} else {
|
||||||
matcher = PgpMain.PGP_SIGNED_MESSAGE.matcher(textData);
|
matcher = PgpHelper.PGP_SIGNED_MESSAGE.matcher(textData);
|
||||||
if (matcher.matches()) {
|
if (matcher.matches()) {
|
||||||
Log.d(Constants.TAG, "PGP_SIGNED_MESSAGE matched");
|
Log.d(Constants.TAG, "PGP_SIGNED_MESSAGE matched");
|
||||||
textData = matcher.group(1);
|
textData = matcher.group(1);
|
||||||
@ -478,7 +481,7 @@ public class DecryptActivity extends SherlockFragmentActivity {
|
|||||||
|
|
||||||
if (mDecryptTarget == Id.target.message) {
|
if (mDecryptTarget == Id.target.message) {
|
||||||
String messageData = mMessage.getText().toString();
|
String messageData = mMessage.getText().toString();
|
||||||
Matcher matcher = PgpMain.PGP_SIGNED_MESSAGE.matcher(messageData);
|
Matcher matcher = PgpHelper.PGP_SIGNED_MESSAGE.matcher(messageData);
|
||||||
if (matcher.matches()) {
|
if (matcher.matches()) {
|
||||||
mSignedOnly = true;
|
mSignedOnly = true;
|
||||||
decryptStart();
|
decryptStart();
|
||||||
@ -532,7 +535,7 @@ public class DecryptActivity extends SherlockFragmentActivity {
|
|||||||
messenger, mSecretKeyId);
|
messenger, mSecretKeyId);
|
||||||
|
|
||||||
passphraseDialog.show(getSupportFragmentManager(), "passphraseDialog");
|
passphraseDialog.show(getSupportFragmentManager(), "passphraseDialog");
|
||||||
} catch (PgpMain.PgpGeneralException e) {
|
} catch (PgpGeneralException e) {
|
||||||
Log.d(Constants.TAG, "No passphrase for this secret key, encrypt directly!");
|
Log.d(Constants.TAG, "No passphrase for this secret key, encrypt directly!");
|
||||||
// send message to handler to start encryption directly
|
// send message to handler to start encryption directly
|
||||||
returnHandler.sendEmptyMessage(PassphraseDialogFragment.MESSAGE_OKAY);
|
returnHandler.sendEmptyMessage(PassphraseDialogFragment.MESSAGE_OKAY);
|
||||||
@ -578,20 +581,18 @@ public class DecryptActivity extends SherlockFragmentActivity {
|
|||||||
inStream.mark(200); // should probably set this to the max size of two pgpF
|
inStream.mark(200); // should probably set this to the max size of two pgpF
|
||||||
// objects, if it even needs to be anything other than 0.
|
// objects, if it even needs to be anything other than 0.
|
||||||
}
|
}
|
||||||
mSecretKeyId = PgpMain.getDecryptionKeyId(this, inStream);
|
mSecretKeyId = PgpHelper.getDecryptionKeyId(this, inStream);
|
||||||
if (mSecretKeyId == Id.key.none) {
|
if (mSecretKeyId == Id.key.none) {
|
||||||
throw new PgpMain.PgpGeneralException(
|
throw new PgpGeneralException(getString(R.string.error_noSecretKeyFound));
|
||||||
getString(R.string.error_noSecretKeyFound));
|
|
||||||
}
|
}
|
||||||
mAssumeSymmetricEncryption = false;
|
mAssumeSymmetricEncryption = false;
|
||||||
} catch (PgpMain.NoAsymmetricEncryptionException e) {
|
} catch (NoAsymmetricEncryptionException e) {
|
||||||
if (inStream.markSupported()) {
|
if (inStream.markSupported()) {
|
||||||
inStream.reset();
|
inStream.reset();
|
||||||
}
|
}
|
||||||
mSecretKeyId = Id.key.symmetric;
|
mSecretKeyId = Id.key.symmetric;
|
||||||
if (!PgpMain.hasSymmetricEncryption(this, inStream)) {
|
if (!PgpOperation.hasSymmetricEncryption(this, inStream)) {
|
||||||
throw new PgpMain.PgpGeneralException(
|
throw new PgpGeneralException(getString(R.string.error_noKnownEncryptionFound));
|
||||||
getString(R.string.error_noKnownEncryptionFound));
|
|
||||||
}
|
}
|
||||||
mAssumeSymmetricEncryption = true;
|
mAssumeSymmetricEncryption = true;
|
||||||
}
|
}
|
||||||
@ -771,8 +772,8 @@ public class DecryptActivity extends SherlockFragmentActivity {
|
|||||||
.getString(KeychainIntentService.RESULT_SIGNATURE_USER_ID);
|
.getString(KeychainIntentService.RESULT_SIGNATURE_USER_ID);
|
||||||
mSignatureKeyId = returnData
|
mSignatureKeyId = returnData
|
||||||
.getLong(KeychainIntentService.RESULT_SIGNATURE_KEY_ID);
|
.getLong(KeychainIntentService.RESULT_SIGNATURE_KEY_ID);
|
||||||
mUserIdRest
|
mUserIdRest.setText("id: "
|
||||||
.setText("id: " + PgpHelper.getSmallFingerPrint(mSignatureKeyId));
|
+ PgpKeyHelper.getSmallFingerPrint(mSignatureKeyId));
|
||||||
if (userId == null) {
|
if (userId == null) {
|
||||||
userId = getResources().getString(R.string.unknownUserId);
|
userId = getResources().getString(R.string.unknownUserId);
|
||||||
}
|
}
|
||||||
|
@ -28,12 +28,13 @@ import org.sufficientlysecure.keychain.Id;
|
|||||||
import org.sufficientlysecure.keychain.R;
|
import org.sufficientlysecure.keychain.R;
|
||||||
import org.sufficientlysecure.keychain.helper.ActionBarHelper;
|
import org.sufficientlysecure.keychain.helper.ActionBarHelper;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpConversionHelper;
|
import org.sufficientlysecure.keychain.pgp.PgpConversionHelper;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpHelper;
|
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpMain;
|
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpMain.PgpGeneralException;
|
|
||||||
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||||
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
||||||
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
|
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
|
||||||
|
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
|
||||||
|
import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment;
|
||||||
import org.sufficientlysecure.keychain.ui.dialog.SetPassphraseDialogFragment;
|
import org.sufficientlysecure.keychain.ui.dialog.SetPassphraseDialogFragment;
|
||||||
import org.sufficientlysecure.keychain.ui.widget.KeyEditor;
|
import org.sufficientlysecure.keychain.ui.widget.KeyEditor;
|
||||||
import org.sufficientlysecure.keychain.ui.widget.SectionView;
|
import org.sufficientlysecure.keychain.ui.widget.SectionView;
|
||||||
@ -288,6 +289,38 @@ public class EditKeyActivity extends SherlockFragmentActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void showPassphraseDialog(final long masterKeyId, final boolean masterCanSign) {
|
||||||
|
// Message is received after passphrase is cached
|
||||||
|
final boolean mCanSign = masterCanSign;
|
||||||
|
Handler returnHandler = new Handler() {
|
||||||
|
@Override
|
||||||
|
public void handleMessage(Message message) {
|
||||||
|
if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) {
|
||||||
|
String passPhrase = PassphraseCacheService.getCachedPassphrase(
|
||||||
|
EditKeyActivity.this, masterKeyId);
|
||||||
|
mCurrentPassPhrase = passPhrase;
|
||||||
|
finallyEdit(masterKeyId, masterCanSign);
|
||||||
|
} else {
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create a new Messenger for the communication back
|
||||||
|
Messenger messenger = new Messenger(returnHandler);
|
||||||
|
|
||||||
|
try {
|
||||||
|
PassphraseDialogFragment passphraseDialog = PassphraseDialogFragment.newInstance(
|
||||||
|
EditKeyActivity.this, messenger, masterKeyId);
|
||||||
|
|
||||||
|
passphraseDialog.show(getSupportFragmentManager(), "passphraseDialog");
|
||||||
|
} catch (PgpGeneralException e) {
|
||||||
|
Log.d(Constants.TAG, "No passphrase for this secret key!");
|
||||||
|
// send message to handler to start encryption directly
|
||||||
|
returnHandler.sendEmptyMessage(PassphraseDialogFragment.MESSAGE_OKAY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle intent action to edit existing key
|
* Handle intent action to edit existing key
|
||||||
*
|
*
|
||||||
@ -299,7 +332,32 @@ public class EditKeyActivity extends SherlockFragmentActivity {
|
|||||||
|
|
||||||
mActionBar.setTitle(R.string.title_editKey);
|
mActionBar.setTitle(R.string.title_editKey);
|
||||||
|
|
||||||
mCurrentPassPhrase = PgpMain.getEditPassPhrase();
|
if (extras != null) {
|
||||||
|
if (extras.containsKey(EXTRA_MASTER_CAN_SIGN)) {
|
||||||
|
masterCanSign = extras.getBoolean(EXTRA_MASTER_CAN_SIGN);
|
||||||
|
}
|
||||||
|
if (extras.containsKey(EXTRA_MASTER_KEY_ID)) {
|
||||||
|
long masterKeyId = extras.getLong(EXTRA_MASTER_KEY_ID);
|
||||||
|
|
||||||
|
// build layout in edit()
|
||||||
|
mBuildLayout = false;
|
||||||
|
|
||||||
|
String passPhrase = PassphraseCacheService.getCachedPassphrase(this, masterKeyId);
|
||||||
|
if (passPhrase == null) {
|
||||||
|
showPassphraseDialog(masterKeyId, masterCanSign);
|
||||||
|
} else {
|
||||||
|
// PgpMain.setEditPassPhrase(passPhrase);
|
||||||
|
mCurrentPassPhrase = passPhrase;
|
||||||
|
|
||||||
|
finallyEdit(masterKeyId, masterCanSign);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void finallyEdit(final long masterKeyId, final boolean masterCanSign) {
|
||||||
|
// TODO: ???
|
||||||
if (mCurrentPassPhrase == null) {
|
if (mCurrentPassPhrase == null) {
|
||||||
mCurrentPassPhrase = "";
|
mCurrentPassPhrase = "";
|
||||||
}
|
}
|
||||||
@ -310,37 +368,28 @@ public class EditKeyActivity extends SherlockFragmentActivity {
|
|||||||
mChangePassPhrase.setVisibility(View.GONE);
|
mChangePassPhrase.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (extras != null) {
|
if (masterKeyId != 0) {
|
||||||
if (extras.containsKey(EXTRA_MASTER_CAN_SIGN)) {
|
PGPSecretKey masterKey = null;
|
||||||
masterCanSign = extras.getBoolean(EXTRA_MASTER_CAN_SIGN);
|
mKeyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(this, masterKeyId);
|
||||||
|
if (mKeyRing != null) {
|
||||||
|
masterKey = PgpKeyHelper.getMasterKey(mKeyRing);
|
||||||
|
for (PGPSecretKey key : new IterableIterator<PGPSecretKey>(mKeyRing.getSecretKeys())) {
|
||||||
|
mKeys.add(key);
|
||||||
|
mKeysUsages.add(-1); // get usage when view is created
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log.e(Constants.TAG, "Keyring not found with masterKeyId: " + masterKeyId);
|
||||||
|
Toast.makeText(this, R.string.error_noSecretKeyFound, Toast.LENGTH_LONG).show();
|
||||||
}
|
}
|
||||||
if (extras.containsKey(EXTRA_MASTER_KEY_ID)) {
|
if (masterKey != null) {
|
||||||
long masterKeyId = extras.getLong(EXTRA_MASTER_KEY_ID);
|
for (String userId : new IterableIterator<String>(masterKey.getUserIDs())) {
|
||||||
|
Log.d(Constants.TAG, "Added userId " + userId);
|
||||||
if (masterKeyId != 0) {
|
mUserIds.add(userId);
|
||||||
PGPSecretKey masterKey = null;
|
|
||||||
mKeyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(this, masterKeyId);
|
|
||||||
if (mKeyRing != null) {
|
|
||||||
masterKey = PgpHelper.getMasterKey(mKeyRing);
|
|
||||||
for (PGPSecretKey key : new IterableIterator<PGPSecretKey>(
|
|
||||||
mKeyRing.getSecretKeys())) {
|
|
||||||
mKeys.add(key);
|
|
||||||
mKeysUsages.add(-1); // get usage when view is created
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.e(Constants.TAG, "Keyring not found with masterKeyId: " + masterKeyId);
|
|
||||||
Toast.makeText(this, R.string.error_noSecretKeyFound, Toast.LENGTH_LONG)
|
|
||||||
.show();
|
|
||||||
}
|
|
||||||
if (masterKey != null) {
|
|
||||||
for (String userId : new IterableIterator<String>(masterKey.getUserIDs())) {
|
|
||||||
Log.d(Constants.TAG, "Added userId " + userId);
|
|
||||||
mUserIds.add(userId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
buildLayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -424,7 +473,7 @@ public class EditKeyActivity extends SherlockFragmentActivity {
|
|||||||
private void saveClicked() {
|
private void saveClicked() {
|
||||||
try {
|
try {
|
||||||
if (!isPassphraseSet()) {
|
if (!isPassphraseSet()) {
|
||||||
throw new PgpMain.PgpGeneralException(this.getString(R.string.setAPassPhrase));
|
throw new PgpGeneralException(this.getString(R.string.setAPassPhrase));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send all information needed to service to edit key in other thread
|
// Send all information needed to service to edit key in other thread
|
||||||
@ -480,7 +529,7 @@ public class EditKeyActivity extends SherlockFragmentActivity {
|
|||||||
|
|
||||||
// start service with intent
|
// start service with intent
|
||||||
startService(intent);
|
startService(intent);
|
||||||
} catch (PgpMain.PgpGeneralException e) {
|
} catch (PgpGeneralException e) {
|
||||||
Toast.makeText(this, getString(R.string.errorMessage, e.getMessage()),
|
Toast.makeText(this, getString(R.string.errorMessage, e.getMessage()),
|
||||||
Toast.LENGTH_SHORT).show();
|
Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
@ -497,8 +546,7 @@ public class EditKeyActivity extends SherlockFragmentActivity {
|
|||||||
* @param userIdsView
|
* @param userIdsView
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private ArrayList<String> getUserIds(SectionView userIdsView)
|
private ArrayList<String> getUserIds(SectionView userIdsView) throws PgpGeneralException {
|
||||||
throws PgpMain.PgpGeneralException {
|
|
||||||
ArrayList<String> userIds = new ArrayList<String>();
|
ArrayList<String> userIds = new ArrayList<String>();
|
||||||
|
|
||||||
ViewGroup userIdEditors = userIdsView.getEditors();
|
ViewGroup userIdEditors = userIdsView.getEditors();
|
||||||
@ -510,13 +558,12 @@ public class EditKeyActivity extends SherlockFragmentActivity {
|
|||||||
try {
|
try {
|
||||||
userId = editor.getValue();
|
userId = editor.getValue();
|
||||||
} catch (UserIdEditor.NoNameException e) {
|
} catch (UserIdEditor.NoNameException e) {
|
||||||
throw new PgpMain.PgpGeneralException(
|
throw new PgpGeneralException(this.getString(R.string.error_userIdNeedsAName));
|
||||||
this.getString(R.string.error_userIdNeedsAName));
|
|
||||||
} catch (UserIdEditor.NoEmailException e) {
|
} catch (UserIdEditor.NoEmailException e) {
|
||||||
throw new PgpMain.PgpGeneralException(
|
throw new PgpGeneralException(
|
||||||
this.getString(R.string.error_userIdNeedsAnEmailAddress));
|
this.getString(R.string.error_userIdNeedsAnEmailAddress));
|
||||||
} catch (UserIdEditor.InvalidEmailException e) {
|
} catch (UserIdEditor.InvalidEmailException e) {
|
||||||
throw new PgpMain.PgpGeneralException(e.getMessage());
|
throw new PgpGeneralException(e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (userId.equals("")) {
|
if (userId.equals("")) {
|
||||||
@ -532,12 +579,11 @@ public class EditKeyActivity extends SherlockFragmentActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (userIds.size() == 0) {
|
if (userIds.size() == 0) {
|
||||||
throw new PgpMain.PgpGeneralException(getString(R.string.error_keyNeedsAUserId));
|
throw new PgpGeneralException(getString(R.string.error_keyNeedsAUserId));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gotMainUserId) {
|
if (!gotMainUserId) {
|
||||||
throw new PgpMain.PgpGeneralException(
|
throw new PgpGeneralException(getString(R.string.error_mainUserIdMustNotBeEmpty));
|
||||||
getString(R.string.error_mainUserIdMustNotBeEmpty));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return userIds;
|
return userIds;
|
||||||
@ -549,14 +595,13 @@ public class EditKeyActivity extends SherlockFragmentActivity {
|
|||||||
* @param keysView
|
* @param keysView
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private ArrayList<PGPSecretKey> getKeys(SectionView keysView)
|
private ArrayList<PGPSecretKey> getKeys(SectionView keysView) throws PgpGeneralException {
|
||||||
throws PgpMain.PgpGeneralException {
|
|
||||||
ArrayList<PGPSecretKey> keys = new ArrayList<PGPSecretKey>();
|
ArrayList<PGPSecretKey> keys = new ArrayList<PGPSecretKey>();
|
||||||
|
|
||||||
ViewGroup keyEditors = keysView.getEditors();
|
ViewGroup keyEditors = keysView.getEditors();
|
||||||
|
|
||||||
if (keyEditors.getChildCount() == 0) {
|
if (keyEditors.getChildCount() == 0) {
|
||||||
throw new PgpMain.PgpGeneralException(getString(R.string.error_keyNeedsMasterKey));
|
throw new PgpGeneralException(getString(R.string.error_keyNeedsMasterKey));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < keyEditors.getChildCount(); ++i) {
|
for (int i = 0; i < keyEditors.getChildCount(); ++i) {
|
||||||
@ -573,14 +618,13 @@ public class EditKeyActivity extends SherlockFragmentActivity {
|
|||||||
* @param keysView
|
* @param keysView
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private ArrayList<Integer> getKeysUsages(SectionView keysView)
|
private ArrayList<Integer> getKeysUsages(SectionView keysView) throws PgpGeneralException {
|
||||||
throws PgpMain.PgpGeneralException {
|
|
||||||
ArrayList<Integer> getKeysUsages = new ArrayList<Integer>();
|
ArrayList<Integer> getKeysUsages = new ArrayList<Integer>();
|
||||||
|
|
||||||
ViewGroup keyEditors = keysView.getEditors();
|
ViewGroup keyEditors = keysView.getEditors();
|
||||||
|
|
||||||
if (keyEditors.getChildCount() == 0) {
|
if (keyEditors.getChildCount() == 0) {
|
||||||
throw new PgpMain.PgpGeneralException(getString(R.string.error_keyNeedsMasterKey));
|
throw new PgpGeneralException(getString(R.string.error_keyNeedsMasterKey));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < keyEditors.getChildCount(); ++i) {
|
for (int i = 0; i < keyEditors.getChildCount(); ++i) {
|
||||||
|
@ -31,8 +31,8 @@ import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
|
|||||||
import org.sufficientlysecure.keychain.helper.ActionBarHelper;
|
import org.sufficientlysecure.keychain.helper.ActionBarHelper;
|
||||||
import org.sufficientlysecure.keychain.helper.FileHelper;
|
import org.sufficientlysecure.keychain.helper.FileHelper;
|
||||||
import org.sufficientlysecure.keychain.helper.Preferences;
|
import org.sufficientlysecure.keychain.helper.Preferences;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpHelper;
|
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpMain;
|
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
|
||||||
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||||
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
||||||
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
|
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
|
||||||
@ -302,9 +302,9 @@ public class EncryptActivity extends SherlockFragmentActivity {
|
|||||||
preselectedSignatureKeyId);
|
preselectedSignatureKeyId);
|
||||||
PGPSecretKey masterKey = null;
|
PGPSecretKey masterKey = null;
|
||||||
if (keyRing != null) {
|
if (keyRing != null) {
|
||||||
masterKey = PgpHelper.getMasterKey(keyRing);
|
masterKey = PgpKeyHelper.getMasterKey(keyRing);
|
||||||
if (masterKey != null) {
|
if (masterKey != null) {
|
||||||
Vector<PGPSecretKey> signKeys = PgpHelper.getUsableSigningKeys(keyRing);
|
Vector<PGPSecretKey> signKeys = PgpKeyHelper.getUsableSigningKeys(keyRing);
|
||||||
if (signKeys.size() > 0) {
|
if (signKeys.size() > 0) {
|
||||||
mSecretKeyId = masterKey.getKeyID();
|
mSecretKeyId = masterKey.getKeyID();
|
||||||
}
|
}
|
||||||
@ -321,11 +321,11 @@ public class EncryptActivity extends SherlockFragmentActivity {
|
|||||||
if (keyRing == null) {
|
if (keyRing == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
masterKey = PgpHelper.getMasterKey(keyRing);
|
masterKey = PgpKeyHelper.getMasterKey(keyRing);
|
||||||
if (masterKey == null) {
|
if (masterKey == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Vector<PGPPublicKey> encryptKeys = PgpHelper.getUsableEncryptKeys(keyRing);
|
Vector<PGPPublicKey> encryptKeys = PgpKeyHelper.getUsableEncryptKeys(keyRing);
|
||||||
if (encryptKeys.size() == 0) {
|
if (encryptKeys.size() == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -570,7 +570,7 @@ public class EncryptActivity extends SherlockFragmentActivity {
|
|||||||
EncryptActivity.this, messenger, mSecretKeyId);
|
EncryptActivity.this, messenger, mSecretKeyId);
|
||||||
|
|
||||||
passphraseDialog.show(getSupportFragmentManager(), "passphraseDialog");
|
passphraseDialog.show(getSupportFragmentManager(), "passphraseDialog");
|
||||||
} catch (PgpMain.PgpGeneralException e) {
|
} catch (PgpGeneralException e) {
|
||||||
Log.d(Constants.TAG, "No passphrase for this secret key, encrypt directly!");
|
Log.d(Constants.TAG, "No passphrase for this secret key, encrypt directly!");
|
||||||
// send message to handler to start encryption directly
|
// send message to handler to start encryption directly
|
||||||
returnHandler.sendEmptyMessage(PassphraseDialogFragment.MESSAGE_OKAY);
|
returnHandler.sendEmptyMessage(PassphraseDialogFragment.MESSAGE_OKAY);
|
||||||
@ -914,9 +914,9 @@ public class EncryptActivity extends SherlockFragmentActivity {
|
|||||||
PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(this,
|
PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(this,
|
||||||
mSecretKeyId);
|
mSecretKeyId);
|
||||||
if (keyRing != null) {
|
if (keyRing != null) {
|
||||||
PGPSecretKey key = PgpHelper.getMasterKey(keyRing);
|
PGPSecretKey key = PgpKeyHelper.getMasterKey(keyRing);
|
||||||
if (key != null) {
|
if (key != null) {
|
||||||
String userId = PgpHelper.getMainUserIdSafe(this, key);
|
String userId = PgpKeyHelper.getMainUserIdSafe(this, key);
|
||||||
String chunks[] = userId.split(" <", 2);
|
String chunks[] = userId.split(" <", 2);
|
||||||
uid = chunks[0];
|
uid = chunks[0];
|
||||||
if (chunks.length > 1) {
|
if (chunks.length > 1) {
|
||||||
|
@ -19,7 +19,7 @@ package org.sufficientlysecure.keychain.ui;
|
|||||||
|
|
||||||
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
||||||
import org.sufficientlysecure.keychain.Id;
|
import org.sufficientlysecure.keychain.Id;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpHelper;
|
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
|
||||||
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||||
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
|
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
|
||||||
import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds;
|
import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds;
|
||||||
@ -97,7 +97,7 @@ public class KeyListPublicFragment extends KeyListFragment implements
|
|||||||
PGPPublicKeyRing updateKeyRing = ProviderHelper.getPGPPublicKeyRingByRowId(
|
PGPPublicKeyRing updateKeyRing = ProviderHelper.getPGPPublicKeyRingByRowId(
|
||||||
mKeyListActivity, keyRingRowId);
|
mKeyListActivity, keyRingRowId);
|
||||||
if (updateKeyRing != null) {
|
if (updateKeyRing != null) {
|
||||||
updateKeyId = PgpHelper.getMasterKey(updateKeyRing).getKeyID();
|
updateKeyId = PgpKeyHelper.getMasterKey(updateKeyRing).getKeyID();
|
||||||
}
|
}
|
||||||
if (updateKeyId == 0) {
|
if (updateKeyId == 0) {
|
||||||
// this shouldn't happen
|
// this shouldn't happen
|
||||||
@ -126,7 +126,7 @@ public class KeyListPublicFragment extends KeyListFragment implements
|
|||||||
PGPPublicKeyRing signKeyRing = ProviderHelper.getPGPPublicKeyRingByRowId(
|
PGPPublicKeyRing signKeyRing = ProviderHelper.getPGPPublicKeyRingByRowId(
|
||||||
mKeyListActivity, keyRingRowId);
|
mKeyListActivity, keyRingRowId);
|
||||||
if (signKeyRing != null) {
|
if (signKeyRing != null) {
|
||||||
keyId = PgpHelper.getMasterKey(signKeyRing).getKeyID();
|
keyId = PgpKeyHelper.getMasterKey(signKeyRing).getKeyID();
|
||||||
}
|
}
|
||||||
if (keyId == 0) {
|
if (keyId == 0) {
|
||||||
// this shouldn't happen
|
// this shouldn't happen
|
||||||
|
@ -19,20 +19,13 @@ package org.sufficientlysecure.keychain.ui;
|
|||||||
|
|
||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
import org.sufficientlysecure.keychain.Id;
|
import org.sufficientlysecure.keychain.Id;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpMain;
|
|
||||||
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
|
|
||||||
import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment;
|
|
||||||
import org.sufficientlysecure.keychain.util.Log;
|
|
||||||
import org.sufficientlysecure.keychain.R;
|
import org.sufficientlysecure.keychain.R;
|
||||||
|
|
||||||
import com.actionbarsherlock.view.Menu;
|
|
||||||
import com.actionbarsherlock.view.MenuItem;
|
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
|
||||||
import android.os.Message;
|
import com.actionbarsherlock.view.Menu;
|
||||||
import android.os.Messenger;
|
import com.actionbarsherlock.view.MenuItem;
|
||||||
|
|
||||||
public class KeyListSecretActivity extends KeyListActivity {
|
public class KeyListSecretActivity extends KeyListActivity {
|
||||||
|
|
||||||
@ -77,48 +70,7 @@ public class KeyListSecretActivity extends KeyListActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void checkPassPhraseAndEdit(long masterKeyId, boolean masterCanSign) {
|
|
||||||
String passPhrase = PassphraseCacheService.getCachedPassphrase(this, masterKeyId);
|
|
||||||
if (passPhrase == null) {
|
|
||||||
showPassphraseDialog(masterKeyId, masterCanSign);
|
|
||||||
} else {
|
|
||||||
PgpMain.setEditPassPhrase(passPhrase);
|
|
||||||
editKey(masterKeyId, masterCanSign);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void showPassphraseDialog(final long masterKeyId, boolean masterCanSign) {
|
|
||||||
// Message is received after passphrase is cached
|
|
||||||
final boolean mCanSign = masterCanSign;
|
|
||||||
Handler returnHandler = new Handler() {
|
|
||||||
@Override
|
|
||||||
public void handleMessage(Message message) {
|
|
||||||
if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) {
|
|
||||||
String passPhrase = PassphraseCacheService.getCachedPassphrase(
|
|
||||||
KeyListSecretActivity.this, masterKeyId);
|
|
||||||
PgpMain.setEditPassPhrase(passPhrase);
|
|
||||||
editKey(masterKeyId, mCanSign);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Create a new Messenger for the communication back
|
|
||||||
Messenger messenger = new Messenger(returnHandler);
|
|
||||||
|
|
||||||
try {
|
|
||||||
PassphraseDialogFragment passphraseDialog = PassphraseDialogFragment.newInstance(
|
|
||||||
KeyListSecretActivity.this, messenger, masterKeyId);
|
|
||||||
|
|
||||||
passphraseDialog.show(getSupportFragmentManager(), "passphraseDialog");
|
|
||||||
} catch (PgpMain.PgpGeneralException e) {
|
|
||||||
Log.d(Constants.TAG, "No passphrase for this secret key, encrypt directly!");
|
|
||||||
// send message to handler to start encryption directly
|
|
||||||
returnHandler.sendEmptyMessage(PassphraseDialogFragment.MESSAGE_OKAY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createKey() {
|
private void createKey() {
|
||||||
PgpMain.setEditPassPhrase("");
|
|
||||||
Intent intent = new Intent(this, EditKeyActivity.class);
|
Intent intent = new Intent(this, EditKeyActivity.class);
|
||||||
intent.setAction(EditKeyActivity.ACTION_CREATE_KEY);
|
intent.setAction(EditKeyActivity.ACTION_CREATE_KEY);
|
||||||
intent.putExtra(EditKeyActivity.EXTRA_GENERATE_DEFAULT_KEYS, true);
|
intent.putExtra(EditKeyActivity.EXTRA_GENERATE_DEFAULT_KEYS, true);
|
||||||
@ -127,13 +79,12 @@ public class KeyListSecretActivity extends KeyListActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void createKeyExpert() {
|
private void createKeyExpert() {
|
||||||
PgpMain.setEditPassPhrase("");
|
|
||||||
Intent intent = new Intent(this, EditKeyActivity.class);
|
Intent intent = new Intent(this, EditKeyActivity.class);
|
||||||
intent.setAction(EditKeyActivity.ACTION_CREATE_KEY);
|
intent.setAction(EditKeyActivity.ACTION_CREATE_KEY);
|
||||||
startActivityForResult(intent, 0);
|
startActivityForResult(intent, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void editKey(long masterKeyId, boolean masterCanSign) {
|
void editKey(long masterKeyId, boolean masterCanSign) {
|
||||||
Intent intent = new Intent(this, EditKeyActivity.class);
|
Intent intent = new Intent(this, EditKeyActivity.class);
|
||||||
intent.setAction(EditKeyActivity.ACTION_EDIT_KEY);
|
intent.setAction(EditKeyActivity.ACTION_EDIT_KEY);
|
||||||
intent.putExtra(EditKeyActivity.EXTRA_MASTER_KEY_ID, masterKeyId);
|
intent.putExtra(EditKeyActivity.EXTRA_MASTER_KEY_ID, masterKeyId);
|
||||||
|
@ -91,7 +91,7 @@ public class KeyListSecretFragment extends KeyListFragment implements
|
|||||||
|
|
||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
case Id.menu.edit:
|
case Id.menu.edit:
|
||||||
mKeyListSecretActivity.checkPassPhraseAndEdit(masterKeyId, masterCanSign);
|
mKeyListSecretActivity.editKey(masterKeyId, masterCanSign);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ import java.util.List;
|
|||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
import org.sufficientlysecure.keychain.Id;
|
import org.sufficientlysecure.keychain.Id;
|
||||||
import org.sufficientlysecure.keychain.helper.Preferences;
|
import org.sufficientlysecure.keychain.helper.Preferences;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpHelper;
|
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
|
||||||
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
||||||
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
|
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
|
||||||
import org.sufficientlysecure.keychain.util.Log;
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
@ -140,7 +140,7 @@ public class KeyServerQueryActivity extends SherlockFragmentActivity {
|
|||||||
if (ACTION_LOOK_UP_KEY_ID.equals(action) || ACTION_LOOK_UP_KEY_ID_AND_RETURN.equals(action)) {
|
if (ACTION_LOOK_UP_KEY_ID.equals(action) || ACTION_LOOK_UP_KEY_ID_AND_RETURN.equals(action)) {
|
||||||
long keyId = intent.getLongExtra(EXTRA_KEY_ID, 0);
|
long keyId = intent.getLongExtra(EXTRA_KEY_ID, 0);
|
||||||
if (keyId != 0) {
|
if (keyId != 0) {
|
||||||
String query = "0x" + PgpHelper.keyToHex(keyId);
|
String query = "0x" + PgpKeyHelper.keyToHex(keyId);
|
||||||
mQuery.setText(query);
|
mQuery.setText(query);
|
||||||
search(query);
|
search(query);
|
||||||
}
|
}
|
||||||
@ -308,7 +308,7 @@ public class KeyServerQueryActivity extends SherlockFragmentActivity {
|
|||||||
mainUserId.setText(userId);
|
mainUserId.setText(userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
keyId.setText(PgpHelper.getSmallFingerPrint(keyInfo.keyId));
|
keyId.setText(PgpKeyHelper.getSmallFingerPrint(keyInfo.keyId));
|
||||||
|
|
||||||
if (mainUserIdRest.getText().length() == 0) {
|
if (mainUserIdRest.getText().length() == 0) {
|
||||||
mainUserIdRest.setVisibility(View.GONE);
|
mainUserIdRest.setVisibility(View.GONE);
|
||||||
|
@ -22,18 +22,15 @@ import org.spongycastle.openpgp.PGPPublicKeyRing;
|
|||||||
import org.spongycastle.openpgp.PGPSignature;
|
import org.spongycastle.openpgp.PGPSignature;
|
||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
import org.sufficientlysecure.keychain.Id;
|
import org.sufficientlysecure.keychain.Id;
|
||||||
|
import org.sufficientlysecure.keychain.R;
|
||||||
import org.sufficientlysecure.keychain.helper.Preferences;
|
import org.sufficientlysecure.keychain.helper.Preferences;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpMain;
|
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
|
||||||
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||||
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
||||||
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
|
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
|
||||||
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
|
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
|
||||||
import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment;
|
import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment;
|
||||||
import org.sufficientlysecure.keychain.util.Log;
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
import org.sufficientlysecure.keychain.R;
|
|
||||||
|
|
||||||
import com.actionbarsherlock.app.ActionBar;
|
|
||||||
import com.actionbarsherlock.app.SherlockFragmentActivity;
|
|
||||||
|
|
||||||
import android.app.ProgressDialog;
|
import android.app.ProgressDialog;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
@ -51,6 +48,9 @@ import android.widget.CompoundButton.OnCheckedChangeListener;
|
|||||||
import android.widget.Spinner;
|
import android.widget.Spinner;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.actionbarsherlock.app.ActionBar;
|
||||||
|
import com.actionbarsherlock.app.SherlockFragmentActivity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gpg --sign-key
|
* gpg --sign-key
|
||||||
*
|
*
|
||||||
@ -144,7 +144,7 @@ public class SignKeyActivity extends SherlockFragmentActivity {
|
|||||||
messenger, secretKeyId);
|
messenger, secretKeyId);
|
||||||
|
|
||||||
passphraseDialog.show(getSupportFragmentManager(), "passphraseDialog");
|
passphraseDialog.show(getSupportFragmentManager(), "passphraseDialog");
|
||||||
} catch (PgpMain.PgpGeneralException e) {
|
} catch (PgpGeneralException e) {
|
||||||
Log.d(Constants.TAG, "No passphrase for this secret key, encrypt directly!");
|
Log.d(Constants.TAG, "No passphrase for this secret key, encrypt directly!");
|
||||||
// send message to handler to start encryption directly
|
// send message to handler to start encryption directly
|
||||||
returnHandler.sendEmptyMessage(PassphraseDialogFragment.MESSAGE_OKAY);
|
returnHandler.sendEmptyMessage(PassphraseDialogFragment.MESSAGE_OKAY);
|
||||||
|
@ -21,7 +21,7 @@ import org.spongycastle.openpgp.PGPPublicKeyRing;
|
|||||||
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
import org.sufficientlysecure.keychain.Id;
|
import org.sufficientlysecure.keychain.Id;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpHelper;
|
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
|
||||||
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||||
import org.sufficientlysecure.keychain.util.Log;
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
import org.sufficientlysecure.keychain.R;
|
import org.sufficientlysecure.keychain.R;
|
||||||
@ -79,11 +79,11 @@ public class DeleteKeyDialogFragment extends DialogFragment {
|
|||||||
if (keyType == Id.type.public_key) {
|
if (keyType == Id.type.public_key) {
|
||||||
PGPPublicKeyRing keyRing = ProviderHelper.getPGPPublicKeyRingByRowId(activity,
|
PGPPublicKeyRing keyRing = ProviderHelper.getPGPPublicKeyRingByRowId(activity,
|
||||||
deleteKeyRingRowId);
|
deleteKeyRingRowId);
|
||||||
userId = PgpHelper.getMainUserIdSafe(activity, PgpHelper.getMasterKey(keyRing));
|
userId = PgpKeyHelper.getMainUserIdSafe(activity, PgpKeyHelper.getMasterKey(keyRing));
|
||||||
} else {
|
} else {
|
||||||
PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByRowId(activity,
|
PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByRowId(activity,
|
||||||
deleteKeyRingRowId);
|
deleteKeyRingRowId);
|
||||||
userId = PgpHelper.getMainUserIdSafe(activity, PgpHelper.getMasterKey(keyRing));
|
userId = PgpKeyHelper.getMainUserIdSafe(activity, PgpKeyHelper.getMasterKey(keyRing));
|
||||||
}
|
}
|
||||||
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
|
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
|
||||||
|
@ -19,7 +19,7 @@ package org.sufficientlysecure.keychain.ui.dialog;
|
|||||||
|
|
||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
import org.sufficientlysecure.keychain.Id;
|
import org.sufficientlysecure.keychain.Id;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpHelper;
|
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
|
||||||
import org.sufficientlysecure.keychain.ui.KeyServerQueryActivity;
|
import org.sufficientlysecure.keychain.ui.KeyServerQueryActivity;
|
||||||
import org.sufficientlysecure.keychain.util.Log;
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
import org.sufficientlysecure.keychain.R;
|
import org.sufficientlysecure.keychain.R;
|
||||||
@ -79,7 +79,7 @@ public class LookupUnknownKeyDialogFragment extends DialogFragment {
|
|||||||
alert.setIcon(android.R.drawable.ic_dialog_alert);
|
alert.setIcon(android.R.drawable.ic_dialog_alert);
|
||||||
alert.setTitle(R.string.title_unknownSignatureKey);
|
alert.setTitle(R.string.title_unknownSignatureKey);
|
||||||
alert.setMessage(getString(R.string.lookupUnknownKey,
|
alert.setMessage(getString(R.string.lookupUnknownKey,
|
||||||
PgpHelper.getSmallFingerPrint(unknownKeyId)));
|
PgpKeyHelper.getSmallFingerPrint(unknownKeyId)));
|
||||||
|
|
||||||
alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
||||||
|
|
||||||
|
@ -24,13 +24,12 @@ import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor;
|
|||||||
import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
|
import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
|
||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
import org.sufficientlysecure.keychain.Id;
|
import org.sufficientlysecure.keychain.Id;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpHelper;
|
import org.sufficientlysecure.keychain.R;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpMain;
|
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpMain.PgpGeneralException;
|
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
|
||||||
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||||
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
|
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
|
||||||
import org.sufficientlysecure.keychain.util.Log;
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
import org.sufficientlysecure.keychain.R;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
@ -80,7 +79,7 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor
|
|||||||
// check if secret key has a passphrase
|
// check if secret key has a passphrase
|
||||||
if (!(secretKeyId == Id.key.symmetric || secretKeyId == Id.key.none)) {
|
if (!(secretKeyId == Id.key.symmetric || secretKeyId == Id.key.none)) {
|
||||||
if (!PassphraseCacheService.hasPassphrase(context, secretKeyId)) {
|
if (!PassphraseCacheService.hasPassphrase(context, secretKeyId)) {
|
||||||
throw new PgpMain.PgpGeneralException("No passphrase! No passphrase dialog needed!");
|
throw new PgpGeneralException("No passphrase! No passphrase dialog needed!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,7 +118,7 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor
|
|||||||
alert.setMessage(R.string.passPhraseForSymmetricEncryption);
|
alert.setMessage(R.string.passPhraseForSymmetricEncryption);
|
||||||
} else {
|
} else {
|
||||||
// TODO: by master key id???
|
// TODO: by master key id???
|
||||||
secretKey = PgpHelper.getMasterKey(ProviderHelper.getPGPSecretKeyRingByKeyId(activity,
|
secretKey = PgpKeyHelper.getMasterKey(ProviderHelper.getPGPSecretKeyRingByKeyId(activity,
|
||||||
secretKeyId));
|
secretKeyId));
|
||||||
// secretKey = PGPHelper.getMasterKey(PGPMain.getSecretKeyRing(secretKeyId));
|
// secretKey = PGPHelper.getMasterKey(PGPMain.getSecretKeyRing(secretKeyId));
|
||||||
|
|
||||||
@ -135,7 +134,7 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor
|
|||||||
canKB = false;
|
canKB = false;
|
||||||
return alert.create();
|
return alert.create();
|
||||||
}
|
}
|
||||||
String userId = PgpHelper.getMainUserIdSafe(activity, secretKey);
|
String userId = PgpKeyHelper.getMainUserIdSafe(activity, secretKey);
|
||||||
|
|
||||||
Log.d(Constants.TAG, "User id: '" + userId + "'");
|
Log.d(Constants.TAG, "User id: '" + userId + "'");
|
||||||
alert.setMessage(getString(R.string.passPhraseFor, userId));
|
alert.setMessage(getString(R.string.passPhraseFor, userId));
|
||||||
@ -163,7 +162,7 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor
|
|||||||
if (clickSecretKey != null) { // check again for loop
|
if (clickSecretKey != null) { // check again for loop
|
||||||
try {
|
try {
|
||||||
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder()
|
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder()
|
||||||
.setProvider(PgpMain.BOUNCY_CASTLE_PROVIDER_NAME).build(
|
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(
|
||||||
passPhrase.toCharArray());
|
passPhrase.toCharArray());
|
||||||
PGPPrivateKey testKey = clickSecretKey
|
PGPPrivateKey testKey = clickSecretKey
|
||||||
.extractPrivateKey(keyDecryptor);
|
.extractPrivateKey(keyDecryptor);
|
||||||
@ -176,7 +175,7 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor
|
|||||||
sendMessageToHandler(MESSAGE_CANCEL);
|
sendMessageToHandler(MESSAGE_CANCEL);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
clickSecretKey = PgpHelper.getKeyNum(ProviderHelper
|
clickSecretKey = PgpKeyHelper.getKeyNum(ProviderHelper
|
||||||
.getPGPSecretKeyRingByKeyId(activity, secretKeyId),
|
.getPGPSecretKeyRingByKeyId(activity, secretKeyId),
|
||||||
curKeyIndex);
|
curKeyIndex);
|
||||||
curKeyIndex++; // does post-increment work like C?
|
curKeyIndex++; // does post-increment work like C?
|
||||||
|
@ -32,7 +32,7 @@ import org.spongycastle.openpgp.PGPObjectFactory;
|
|||||||
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
||||||
import org.spongycastle.openpgp.PGPUtil;
|
import org.spongycastle.openpgp.PGPUtil;
|
||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpHelper;
|
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
|
||||||
import org.sufficientlysecure.keychain.util.InputData;
|
import org.sufficientlysecure.keychain.util.InputData;
|
||||||
import org.sufficientlysecure.keychain.util.Log;
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
import org.sufficientlysecure.keychain.util.PositionAwareInputStream;
|
import org.sufficientlysecure.keychain.util.PositionAwareInputStream;
|
||||||
@ -142,13 +142,13 @@ public class ImportKeysListLoader extends AsyncTaskLoader<List<Map<String, Strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void addToData(PGPKeyRing keyring) {
|
private void addToData(PGPKeyRing keyring) {
|
||||||
String userId = PgpHelper.getMainUserId(keyring.getPublicKey());
|
String userId = PgpKeyHelper.getMainUserId(keyring.getPublicKey());
|
||||||
|
|
||||||
if (keyring instanceof PGPSecretKeyRing) {
|
if (keyring instanceof PGPSecretKeyRing) {
|
||||||
userId = mContext.getString(R.string.secretKeyring) + " " + userId;
|
userId = mContext.getString(R.string.secretKeyring) + " " + userId;
|
||||||
}
|
}
|
||||||
|
|
||||||
String fingerprint = PgpHelper.convertFingerprintToHex(keyring.getPublicKey()
|
String fingerprint = PgpKeyHelper.convertFingerprintToHex(keyring.getPublicKey()
|
||||||
.getFingerprint());
|
.getFingerprint());
|
||||||
|
|
||||||
Map<String, String> attrs = new HashMap<String, String>();
|
Map<String, String> attrs = new HashMap<String, String>();
|
||||||
|
@ -19,7 +19,7 @@ package org.sufficientlysecure.keychain.ui.widget;
|
|||||||
import org.spongycastle.openpgp.PGPPublicKey;
|
import org.spongycastle.openpgp.PGPPublicKey;
|
||||||
import org.spongycastle.openpgp.PGPSecretKey;
|
import org.spongycastle.openpgp.PGPSecretKey;
|
||||||
import org.sufficientlysecure.keychain.Id;
|
import org.sufficientlysecure.keychain.Id;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpHelper;
|
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
|
||||||
import org.sufficientlysecure.keychain.util.Choice;
|
import org.sufficientlysecure.keychain.util.Choice;
|
||||||
import org.sufficientlysecure.keychain.R;
|
import org.sufficientlysecure.keychain.R;
|
||||||
|
|
||||||
@ -151,9 +151,9 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener {
|
|||||||
mDeleteButton.setVisibility(View.INVISIBLE);
|
mDeleteButton.setVisibility(View.INVISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
mAlgorithm.setText(PgpHelper.getAlgorithmInfo(key));
|
mAlgorithm.setText(PgpKeyHelper.getAlgorithmInfo(key));
|
||||||
String keyId1Str = PgpHelper.getSmallFingerPrint(key.getKeyID());
|
String keyId1Str = PgpKeyHelper.getSmallFingerPrint(key.getKeyID());
|
||||||
String keyId2Str = PgpHelper.getSmallFingerPrint(key.getKeyID() >> 32);
|
String keyId2Str = PgpKeyHelper.getSmallFingerPrint(key.getKeyID() >> 32);
|
||||||
mKeyId.setText(keyId1Str + " " + keyId2Str);
|
mKeyId.setText(keyId1Str + " " + keyId2Str);
|
||||||
|
|
||||||
Vector<Choice> choices = new Vector<Choice>();
|
Vector<Choice> choices = new Vector<Choice>();
|
||||||
@ -179,8 +179,8 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener {
|
|||||||
|
|
||||||
// Set value in choice dropdown to key
|
// Set value in choice dropdown to key
|
||||||
int selectId = 0;
|
int selectId = 0;
|
||||||
if (PgpHelper.isEncryptionKey(key)) {
|
if (PgpKeyHelper.isEncryptionKey(key)) {
|
||||||
if (PgpHelper.isSigningKey(key)) {
|
if (PgpKeyHelper.isSigningKey(key)) {
|
||||||
selectId = Id.choice.usage.sign_and_encrypt;
|
selectId = Id.choice.usage.sign_and_encrypt;
|
||||||
} else {
|
} else {
|
||||||
selectId = Id.choice.usage.encrypt_only;
|
selectId = Id.choice.usage.encrypt_only;
|
||||||
@ -203,14 +203,14 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
GregorianCalendar cal = new GregorianCalendar();
|
GregorianCalendar cal = new GregorianCalendar();
|
||||||
cal.setTime(PgpHelper.getCreationDate(key));
|
cal.setTime(PgpKeyHelper.getCreationDate(key));
|
||||||
mCreationDate.setText(DateFormat.getDateInstance().format(cal.getTime()));
|
mCreationDate.setText(DateFormat.getDateInstance().format(cal.getTime()));
|
||||||
cal = new GregorianCalendar();
|
cal = new GregorianCalendar();
|
||||||
Date date = PgpHelper.getExpiryDate(key);
|
Date date = PgpKeyHelper.getExpiryDate(key);
|
||||||
if (date == null) {
|
if (date == null) {
|
||||||
setExpiryDate(null);
|
setExpiryDate(null);
|
||||||
} else {
|
} else {
|
||||||
cal.setTime(PgpHelper.getExpiryDate(key));
|
cal.setTime(PgpKeyHelper.getExpiryDate(key));
|
||||||
setExpiryDate(cal);
|
setExpiryDate(cal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ package org.sufficientlysecure.keychain.ui.widget;
|
|||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
import org.sufficientlysecure.keychain.Id;
|
import org.sufficientlysecure.keychain.Id;
|
||||||
import org.sufficientlysecure.keychain.helper.OtherHelper;
|
import org.sufficientlysecure.keychain.helper.OtherHelper;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpHelper;
|
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
|
||||||
import org.sufficientlysecure.keychain.provider.KeychainContract.Keys;
|
import org.sufficientlysecure.keychain.provider.KeychainContract.Keys;
|
||||||
import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds;
|
import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds;
|
||||||
import org.sufficientlysecure.keychain.util.Log;
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
@ -117,7 +117,7 @@ public class KeyListAdapter extends CursorTreeAdapter {
|
|||||||
keyLayout.setVisibility(View.GONE);
|
keyLayout.setVisibility(View.GONE);
|
||||||
userIdLayout.setVisibility(View.VISIBLE);
|
userIdLayout.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
String fingerprint = PgpHelper.getFingerPrint(context,
|
String fingerprint = PgpKeyHelper.getFingerPrint(context,
|
||||||
cursor.getLong(cursor.getColumnIndex(Keys.KEY_ID)));
|
cursor.getLong(cursor.getColumnIndex(Keys.KEY_ID)));
|
||||||
fingerprint = fingerprint.replace(" ", "\n");
|
fingerprint = fingerprint.replace(" ", "\n");
|
||||||
|
|
||||||
@ -132,9 +132,9 @@ public class KeyListAdapter extends CursorTreeAdapter {
|
|||||||
keyLayout.setVisibility(View.VISIBLE);
|
keyLayout.setVisibility(View.VISIBLE);
|
||||||
userIdLayout.setVisibility(View.GONE);
|
userIdLayout.setVisibility(View.GONE);
|
||||||
|
|
||||||
String keyIdStr = PgpHelper.getSmallFingerPrint(cursor.getLong(cursor
|
String keyIdStr = PgpKeyHelper.getSmallFingerPrint(cursor.getLong(cursor
|
||||||
.getColumnIndex(Keys.KEY_ID)));
|
.getColumnIndex(Keys.KEY_ID)));
|
||||||
String algorithmStr = PgpHelper.getAlgorithmInfo(
|
String algorithmStr = PgpKeyHelper.getAlgorithmInfo(
|
||||||
cursor.getInt(cursor.getColumnIndex(Keys.ALGORITHM)),
|
cursor.getInt(cursor.getColumnIndex(Keys.ALGORITHM)),
|
||||||
cursor.getInt(cursor.getColumnIndex(Keys.KEY_SIZE)));
|
cursor.getInt(cursor.getColumnIndex(Keys.KEY_SIZE)));
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ package org.sufficientlysecure.keychain.ui.widget;
|
|||||||
|
|
||||||
import org.sufficientlysecure.keychain.Id;
|
import org.sufficientlysecure.keychain.Id;
|
||||||
import org.sufficientlysecure.keychain.helper.OtherHelper;
|
import org.sufficientlysecure.keychain.helper.OtherHelper;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpHelper;
|
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
|
||||||
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
|
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
|
||||||
import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds;
|
import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds;
|
||||||
import org.sufficientlysecure.keychain.R;
|
import org.sufficientlysecure.keychain.R;
|
||||||
@ -87,7 +87,7 @@ public class SelectKeyCursorAdapter extends CursorAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
long masterKeyId = cursor.getLong(cursor.getColumnIndex(KeyRings.MASTER_KEY_ID));
|
long masterKeyId = cursor.getLong(cursor.getColumnIndex(KeyRings.MASTER_KEY_ID));
|
||||||
keyId.setText(PgpHelper.getSmallFingerPrint(masterKeyId));
|
keyId.setText(PgpKeyHelper.getSmallFingerPrint(masterKeyId));
|
||||||
|
|
||||||
if (mainUserIdRest.getText().length() == 0) {
|
if (mainUserIdRest.getText().length() == 0) {
|
||||||
mainUserIdRest.setVisibility(View.GONE);
|
mainUserIdRest.setVisibility(View.GONE);
|
||||||
|
@ -44,7 +44,7 @@ import org.apache.http.impl.client.DefaultHttpClient;
|
|||||||
import org.apache.http.message.BasicNameValuePair;
|
import org.apache.http.message.BasicNameValuePair;
|
||||||
import org.apache.http.util.EntityUtils;
|
import org.apache.http.util.EntityUtils;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpHelper;
|
import org.sufficientlysecure.keychain.pgp.PgpHelper;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpMain;
|
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
|
||||||
|
|
||||||
import android.text.Html;
|
import android.text.Html;
|
||||||
|
|
||||||
@ -179,8 +179,8 @@ public class HkpKeyServer extends KeyServer {
|
|||||||
KeyInfo info = new KeyInfo();
|
KeyInfo info = new KeyInfo();
|
||||||
info.size = Integer.parseInt(matcher.group(1));
|
info.size = Integer.parseInt(matcher.group(1));
|
||||||
info.algorithm = matcher.group(2);
|
info.algorithm = matcher.group(2);
|
||||||
info.keyId = PgpHelper.keyFromHex(matcher.group(3));
|
info.keyId = PgpKeyHelper.keyFromHex(matcher.group(3));
|
||||||
info.fingerPrint = PgpHelper.getSmallFingerPrint(info.keyId);
|
info.fingerPrint = PgpKeyHelper.getSmallFingerPrint(info.keyId);
|
||||||
String chunks[] = matcher.group(4).split("-");
|
String chunks[] = matcher.group(4).split("-");
|
||||||
info.date = new GregorianCalendar(Integer.parseInt(chunks[0]),
|
info.date = new GregorianCalendar(Integer.parseInt(chunks[0]),
|
||||||
Integer.parseInt(chunks[1]), Integer.parseInt(chunks[2])).getTime();
|
Integer.parseInt(chunks[1]), Integer.parseInt(chunks[2])).getTime();
|
||||||
@ -211,7 +211,7 @@ public class HkpKeyServer extends KeyServer {
|
|||||||
HttpClient client = new DefaultHttpClient();
|
HttpClient client = new DefaultHttpClient();
|
||||||
try {
|
try {
|
||||||
HttpGet get = new HttpGet("http://" + mHost + ":" + mPort
|
HttpGet get = new HttpGet("http://" + mHost + ":" + mPort
|
||||||
+ "/pks/lookup?op=get&search=0x" + PgpHelper.keyToHex(keyId));
|
+ "/pks/lookup?op=get&search=0x" + PgpKeyHelper.keyToHex(keyId));
|
||||||
|
|
||||||
HttpResponse response = client.execute(get);
|
HttpResponse response = client.execute(get);
|
||||||
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
|
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
|
||||||
@ -221,7 +221,7 @@ public class HkpKeyServer extends KeyServer {
|
|||||||
HttpEntity entity = response.getEntity();
|
HttpEntity entity = response.getEntity();
|
||||||
InputStream is = entity.getContent();
|
InputStream is = entity.getContent();
|
||||||
String data = readAll(is, EntityUtils.getContentCharSet(entity));
|
String data = readAll(is, EntityUtils.getContentCharSet(entity));
|
||||||
Matcher matcher = PgpMain.PGP_PUBLIC_KEY.matcher(data);
|
Matcher matcher = PgpHelper.PGP_PUBLIC_KEY.matcher(data);
|
||||||
if (matcher.find()) {
|
if (matcher.find()) {
|
||||||
return matcher.group(1);
|
return matcher.group(1);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user