Put PgpMain methods in separate opbject classes, handle passphrase dialog in EditKey not in SecretKeyList

This commit is contained in:
Dominik Schürmann 2013-09-15 16:42:08 +02:00
parent 121f8aaca0
commit 5aebd115d4
33 changed files with 2774 additions and 2603 deletions

View File

@ -16,6 +16,8 @@
package org.sufficientlysecure.keychain;
import org.spongycastle.jce.provider.BouncyCastleProvider;
import android.os.Environment;
public final class Constants {
@ -29,6 +31,10 @@ public final class Constants {
// as defined in http://tools.ietf.org/html/rfc3156, section 7
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 class path {

View File

@ -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>
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -17,494 +17,203 @@
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 java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
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.PGPPublicKey;
import org.spongycastle.openpgp.PGPEncryptedDataList;
import org.spongycastle.openpgp.PGPObjectFactory;
import org.spongycastle.openpgp.PGPPublicKeyEncryptedData;
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.spongycastle.openpgp.PGPUtil;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.Id;
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.util.IterableIterator;
import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.ProgressDialogUpdater;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
public class PgpHelper {
public static Date getCreationDate(PGPPublicKey key) {
return key.getCreationTime();
public static Pattern PGP_MESSAGE = Pattern.compile(
".*?(-----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) {
return key.getPublicKey().getCreationTime();
public static String getFullVersion(Context context) {
return "OpenPGP Keychain v" + getVersion(context);
}
@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;
}
public static long getDecryptionKeyId(Context context, InputStream inputStream)
throws PgpGeneralException, NoAsymmetricEncryptionException, IOException {
InputStream in = PGPUtil.getDecoderStream(inputStream);
PGPObjectFactory pgpF = new PGPObjectFactory(in);
PGPEncryptedDataList enc;
Object o = pgpF.nextObject();
// the first object might be a PGP marker packet.
if (o instanceof PGPEncryptedDataList) {
enc = (PGPEncryptedDataList) o;
} else {
enc = (PGPEncryptedDataList) pgpF.nextObject();
}
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;
}
if (enc == null) {
throw new PgpGeneralException(context.getString(R.string.error_invalidData));
}
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);
// TODO: currently we always only look at the first known key
// find the secret key
PGPSecretKey secretKey = null;
Iterator<?> it = enc.getEncryptedDataObjects();
boolean gotAsymmetricEncryption = false;
while (it.hasNext()) {
Object obj = it.next();
if (obj instanceof PGPPublicKeyEncryptedData) {
gotAsymmetricEncryption = true;
PGPPublicKeyEncryptedData pbe = (PGPPublicKeyEncryptedData) obj;
secretKey = ProviderHelper.getPGPSecretKeyByKeyId(context, pbe.getKeyID());
if (secretKey != null) {
break;
}
}
}
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 (!gotAsymmetricEncryption) {
throw new NoAsymmetricEncryptionException();
}
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 Id.key.none;
}
return isSecretKeyPrivateEmpty(secretKey);
return secretKey.getKeyID();
}
public static String getSmallFingerPrint(long keyId) {
String fingerPrint = Long.toHexString(keyId & 0xffffffffL).toUpperCase(Locale.US);
while (fingerPrint.length() < 8) {
fingerPrint = "0" + fingerPrint;
public static int getStreamContent(Context context, InputStream inStream) throws IOException {
InputStream in = PGPUtil.getDecoderStream(inStream);
PGPObjectFactory pgpF = new PGPObjectFactory(in);
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();
String s2 = data.substring(len - 8);
String s1 = data.substring(0, len - 8);
return (Long.parseLong(s1, 16) << 32) | Long.parseLong(s2, 16);
/**
* Go once through stream to get length of stream. The length is later used to display progress
* when encrypting/decrypting
*
* @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();
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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

View File

@ -251,7 +251,7 @@ public class PgpToX509 {
}
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);
return selfSignedCert;

View File

@ -0,0 +1,9 @@
package org.sufficientlysecure.keychain.pgp.exception;
public class NoAsymmetricEncryptionException extends Exception {
static final long serialVersionUID = 0xf812773343L;
public NoAsymmetricEncryptionException() {
super();
}
}

View File

@ -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);
}
}

View File

@ -31,7 +31,7 @@ import org.spongycastle.openpgp.PGPSecretKeyRing;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.pgp.PgpConversionHelper;
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.KeyRings;
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.ALGORITHM, key.getAlgorithm());
values.put(Keys.KEY_SIZE, key.getBitStrength());
values.put(Keys.CAN_SIGN, PgpHelper.isSigningKey(key));
values.put(Keys.CAN_ENCRYPT, PgpHelper.isEncryptionKey(key));
values.put(Keys.CAN_SIGN, PgpKeyHelper.isSigningKey(key));
values.put(Keys.CAN_ENCRYPT, PgpKeyHelper.isEncryptionKey(key));
values.put(Keys.IS_REVOKED, key.isRevoked());
values.put(Keys.CREATION, PgpHelper.getCreationDate(key).getTime() / 1000);
Date expiryDate = PgpHelper.getExpiryDate(key);
values.put(Keys.CREATION, PgpKeyHelper.getCreationDate(key).getTime() / 1000);
Date expiryDate = PgpKeyHelper.getExpiryDate(key);
if (expiryDate != null) {
values.put(Keys.EXPIRY, expiryDate.getTime() / 1000);
}
@ -375,7 +375,7 @@ public class ProviderHelper {
boolean has_private = true;
if (key.isMasterKey()) {
if (PgpHelper.isSecretKeyPrivateEmpty(key)) {
if (PgpKeyHelper.isSecretKeyPrivateEmpty(key)) {
has_private = false;
}
}
@ -384,12 +384,12 @@ public class ProviderHelper {
values.put(Keys.IS_MASTER_KEY, key.isMasterKey());
values.put(Keys.ALGORITHM, key.getPublicKey().getAlgorithm());
values.put(Keys.KEY_SIZE, key.getPublicKey().getBitStrength());
values.put(Keys.CAN_CERTIFY, (PgpHelper.isCertificationKey(key) && has_private));
values.put(Keys.CAN_SIGN, (PgpHelper.isSigningKey(key) && has_private));
values.put(Keys.CAN_ENCRYPT, PgpHelper.isEncryptionKey(key));
values.put(Keys.CAN_CERTIFY, (PgpKeyHelper.isCertificationKey(key) && has_private));
values.put(Keys.CAN_SIGN, (PgpKeyHelper.isSigningKey(key) && has_private));
values.put(Keys.CAN_ENCRYPT, PgpKeyHelper.isEncryptionKey(key));
values.put(Keys.IS_REVOKED, key.getPublicKey().isRevoked());
values.put(Keys.CREATION, PgpHelper.getCreationDate(key).getTime() / 1000);
Date expiryDate = PgpHelper.getExpiryDate(key);
values.put(Keys.CREATION, PgpKeyHelper.getCreationDate(key).getTime() / 1000);
Date expiryDate = PgpKeyHelper.getExpiryDate(key);
if (expiryDate != null) {
values.put(Keys.EXPIRY, expiryDate.getTime() / 1000);
}
@ -617,7 +617,7 @@ public class ProviderHelper {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ArmoredOutputStream aos = new ArmoredOutputStream(bos);
aos.setHeader("Version", PgpMain.getFullVersion(context));
aos.setHeader("Version", PgpHelper.getFullVersion(context));
if (keyRing instanceof PGPSecretKeyRing) {
aos.write(((PGPSecretKeyRing) keyRing).getEncoded());

View File

@ -38,8 +38,11 @@ import org.sufficientlysecure.keychain.helper.FileHelper;
import org.sufficientlysecure.keychain.helper.OtherHelper;
import org.sufficientlysecure.keychain.helper.Preferences;
import org.sufficientlysecure.keychain.pgp.PgpConversionHelper;
import org.sufficientlysecure.keychain.pgp.PgpMain;
import org.sufficientlysecure.keychain.pgp.PgpMain.PgpGeneralException;
import org.sufficientlysecure.keychain.pgp.PgpHelper;
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.ProviderHelper;
import org.sufficientlysecure.keychain.util.HkpKeyServer;
@ -288,16 +291,15 @@ public class KeychainIntentService extends IntentService implements ProgressDial
// InputStream
InputStream in = getContentResolver().openInputStream(providerUri);
inLength = PgpMain.getLengthOfStream(in);
inLength = PgpHelper.getLengthOfStream(in);
inputData = new InputData(in, inLength);
// OutputStream
try {
while (true) {
streamFilename = PgpMain.generateRandomFilename(32);
streamFilename = PgpHelper.generateRandomFilename(32);
if (streamFilename == null) {
throw new PgpMain.PgpGeneralException(
"couldn't generate random file name");
throw new PgpGeneralException("couldn't generate random file name");
}
openFileInput(streamFilename).close();
}
@ -309,31 +311,30 @@ public class KeychainIntentService extends IntentService implements ProgressDial
break;
default:
throw new PgpMain.PgpGeneralException("No target choosen!");
throw new PgpGeneralException("No target choosen!");
}
/* Operation */
PgpOperation operation = new PgpOperation(this, this, inputData, outStream);
if (generateSignature) {
Log.d(Constants.TAG, "generating signature...");
PgpMain.generateSignature(this, this, inputData, outStream, useAsciiArmor,
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,
operation.generateSignature(useAsciiArmor, false, secretKeyId,
PassphraseCacheService.getCachedPassphrase(this, secretKeyId),
Preferences.getPreferences(this).getDefaultHashAlgorithm(), Preferences
.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 {
Log.d(Constants.TAG, "encrypt...");
PgpMain.encryptAndSign(this, this, inputData, outStream, useAsciiArmor,
compressionId, encryptionKeyIds, encryptionPassphrase, Preferences
.getPreferences(this).getDefaultEncryptionAlgorithm(),
secretKeyId,
Preferences.getPreferences(this).getDefaultHashAlgorithm(), Preferences
operation.encryptAndSign(useAsciiArmor, compressionId, encryptionKeyIds,
encryptionPassphrase, Preferences.getPreferences(this)
.getDefaultEncryptionAlgorithm(), secretKeyId, Preferences
.getPreferences(this).getDefaultHashAlgorithm(), Preferences
.getPreferences(this).getForceV3Signatures(),
PassphraseCacheService.getCachedPassphrase(this, secretKeyId));
}
@ -437,16 +438,15 @@ public class KeychainIntentService extends IntentService implements ProgressDial
// InputStream
InputStream in = getContentResolver().openInputStream(providerUri);
inLength = PgpMain.getLengthOfStream(in);
inLength = PgpHelper.getLengthOfStream(in);
inputData = new InputData(in, inLength);
// OutputStream
try {
while (true) {
streamFilename = PgpMain.generateRandomFilename(32);
streamFilename = PgpHelper.generateRandomFilename(32);
if (streamFilename == null) {
throw new PgpMain.PgpGeneralException(
"couldn't generate random file name");
throw new PgpGeneralException("couldn't generate random file name");
}
openFileInput(streamFilename).close();
}
@ -458,7 +458,7 @@ public class KeychainIntentService extends IntentService implements ProgressDial
break;
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
// verification of signatures
PgpOperation operation = new PgpOperation(this, this, inputData, outStream);
if (signedOnly) {
resultData = PgpMain.verifyText(this, this, inputData, outStream,
lookupUnknownKey);
resultData = operation.verifyText(lookupUnknownKey);
} else {
resultData = PgpMain.decryptAndVerify(this, this, inputData, outStream,
resultData = operation.decryptAndVerify(
PassphraseCacheService.getCachedPassphrase(this, secretKeyId),
assumeSymmetricEncryption);
}
@ -530,14 +530,15 @@ public class KeychainIntentService extends IntentService implements ProgressDial
ArrayList<Integer> keysUsages = data.getIntegerArrayList(SAVE_KEYRING_KEYS_USAGES);
long masterKeyId = data.getLong(SAVE_KEYRING_MASTER_KEY_ID);
PgpKeyOperation keyOperations = new PgpKeyOperation(this, this);
/* Operation */
if (!canSign) {
PgpMain.changeSecretKeyPassphrase(this,
keyOperations.changeSecretKeyPassphrase(
ProviderHelper.getPGPSecretKeyRingByKeyId(this, masterKeyId),
oldPassPhrase, newPassPhrase, this);
oldPassPhrase, newPassPhrase);
} else {
PgpMain.buildSecretKey(this, userIds, keys, keysUsages, masterKeyId,
oldPassPhrase, newPassPhrase, this);
keyOperations.buildSecretKey(userIds, keys, keysUsages, masterKeyId,
oldPassPhrase, newPassPhrase);
}
PassphraseCacheService.addCachedPassphrase(this, masterKeyId, newPassPhrase);
@ -559,7 +560,8 @@ public class KeychainIntentService extends IntentService implements ProgressDial
}
/* Operation */
PGPSecretKeyRing newKeyRing = PgpMain.createKey(this, algorithm, keysize,
PgpKeyOperation keyOperations = new PgpKeyOperation(this, this);
PGPSecretKeyRing newKeyRing = keyOperations.createKey(algorithm, keysize,
passphrase, masterKey);
/* Output */
@ -580,10 +582,12 @@ public class KeychainIntentService extends IntentService implements ProgressDial
String passphrase = data.getString(GENERATE_KEY_SYMMETRIC_PASSPHRASE);
/* 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);
PGPSecretKeyRing subKeyRing = PgpMain.createKey(this, Id.choice.algorithm.rsa,
PGPSecretKeyRing subKeyRing = keyOperations.createKey(Id.choice.algorithm.rsa,
4096, passphrase, masterKeyRing.getSecretKey());
/* Output */
@ -606,13 +610,13 @@ public class KeychainIntentService extends IntentService implements ProgressDial
/* Operation */
try {
PgpMain.deleteFileSecurely(this, this, new File(deleteFile));
PgpHelper.deleteFileSecurely(this, this, new File(deleteFile));
} catch (FileNotFoundException e) {
throw new PgpMain.PgpGeneralException(getString(R.string.error_fileNotFound,
deleteFile));
throw new PgpGeneralException(
getString(R.string.error_fileNotFound, deleteFile));
} catch (IOException e) {
throw new PgpMain.PgpGeneralException(getString(
R.string.error_fileDeleteFailed, deleteFile));
throw new PgpGeneralException(getString(R.string.error_fileDeleteFailed,
deleteFile));
}
/* Output */
@ -661,7 +665,9 @@ public class KeychainIntentService extends IntentService implements ProgressDial
}
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);
} catch (Exception e) {
@ -708,8 +714,10 @@ public class KeychainIntentService extends IntentService implements ProgressDial
}
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);
} catch (Exception e) {
@ -728,7 +736,9 @@ public class KeychainIntentService extends IntentService implements ProgressDial
PGPPublicKeyRing keyring = ProviderHelper.getPGPPublicKeyRingByRowId(this,
keyRingRowId);
if (keyring != null) {
boolean uploaded = PgpMain.uploadKeyRingToServer(server,
PgpImportExport pgpImportExport = new PgpImportExport(this, null);
boolean uploaded = pgpImportExport.uploadKeyRingToServer(server,
(PGPPublicKeyRing) keyring);
if (!uploaded) {
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,
masterKeyId);
PGPPublicKeyRing signedPubKeyRing = PgpMain.signKey(this, masterKeyId, pubKeyId,
PgpKeyOperation keyOperation = new PgpKeyOperation(this, this);
PGPPublicKeyRing signedPubKeyRing = keyOperation.signKey(masterKeyId, pubKeyId,
signaturePassPhrase);
// 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) {
throw new PgpGeneralException("Failed to store signed key in local cache");
}

View File

@ -29,7 +29,7 @@ import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.Id;
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 android.app.AlarmManager;
@ -173,7 +173,7 @@ public class PassphraseCacheService extends Service {
if (keyRing == null) {
return null;
}
PGPSecretKey masterKey = PgpHelper.getMasterKey(keyRing);
PGPSecretKey masterKey = PgpKeyHelper.getMasterKey(keyRing);
if (masterKey == null) {
return null;
}
@ -210,7 +210,7 @@ public class PassphraseCacheService extends Service {
public static boolean hasPassphrase(Context context, long secretKeyId) {
// check if the key has no passphrase
try {
PGPSecretKey secretKey = PgpHelper.getMasterKey(ProviderHelper
PGPSecretKey secretKey = PgpKeyHelper.getMasterKey(ProviderHelper
.getPGPSecretKeyRingByKeyId(context, secretKeyId));
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(
"SC").build("".toCharArray());

View File

@ -26,7 +26,7 @@ import org.spongycastle.openpgp.PGPSecretKeyRing;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.Id;
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.ui.SelectSecretKeyActivity;
import org.sufficientlysecure.keychain.util.KeyValueSpinnerAdapter;
@ -259,9 +259,9 @@ public class AppSettingsFragment extends Fragment {
PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(
getActivity(), secretKeyId);
if (keyRing != null) {
PGPSecretKey key = PgpHelper.getMasterKey(keyRing);
PGPSecretKey key = PgpKeyHelper.getMasterKey(keyRing);
if (key != null) {
String userId = PgpHelper.getMainUserIdSafe(getActivity(), key);
String userId = PgpKeyHelper.getMainUserIdSafe(getActivity(), key);
String chunks[] = userId.split(" <", 2);
uid = chunks[0];
if (chunks.length > 1) {

View File

@ -29,8 +29,7 @@ import org.spongycastle.openpgp.PGPPrivateKey;
import org.spongycastle.openpgp.PGPSecretKey;
import org.spongycastle.openssl.PEMWriter;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.pgp.PgpHelper;
import org.sufficientlysecure.keychain.pgp.PgpMain;
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
import org.sufficientlysecure.keychain.pgp.PgpToX509;
import org.sufficientlysecure.keychain.util.Log;
@ -53,13 +52,13 @@ public class ExtendedApiService extends RemoteService {
try {
long keyId = appSettings.getKeyId();
PGPSecretKey pgpSecretKey = PgpHelper.getSigningKey(this, keyId);
PGPSecretKey pgpSecretKey = PgpKeyHelper.getSigningKey(this, keyId);
PasswordCallback pgpSecKeyPasswordCallBack = new PasswordCallback("pgp passphrase?",
false);
pgpPwdCallbackHandler.handle(new Callback[] { pgpSecKeyPasswordCallBack });
PGPPrivateKey pgpPrivKey = pgpSecretKey.extractPrivateKey(
pgpSecKeyPasswordCallBack.getPassword(), PgpMain.BOUNCY_CASTLE_PROVIDER_NAME);
pgpSecKeyPasswordCallBack.getPassword(), Constants.BOUNCY_CASTLE_PROVIDER_NAME);
pgpSecKeyPasswordCallBack.clearPassword();
X509Certificate selfSignedCert = PgpToX509.createSelfSignedCert(pgpSecretKey,

View File

@ -32,7 +32,10 @@ import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.Id;
import org.sufficientlysecure.keychain.R;
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.service.KeychainIntentService;
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
@ -230,6 +233,7 @@ public class OpenPgpService extends RemoteService {
return;
}
PgpOperation operation = new PgpOperation(getContext(), null, inputData, outputStream);
if (sign) {
String passphrase = getCachedPassphrase(appSettings.getKeyId());
if (passphrase == null) {
@ -238,13 +242,11 @@ public class OpenPgpService extends RemoteService {
return;
}
PgpMain.encryptAndSign(getContext(), null, inputData, outputStream, asciiArmor,
appSettings.getCompression(), keyIds, null,
operation.encryptAndSign(asciiArmor, appSettings.getCompression(), keyIds, null,
appSettings.getEncryptionAlgorithm(), appSettings.getKeyId(),
appSettings.getHashAlgorithm(), true, passphrase);
} else {
PgpMain.encryptAndSign(getContext(), null, inputData, outputStream, asciiArmor,
appSettings.getCompression(), keyIds, null,
operation.encryptAndSign(asciiArmor, appSettings.getCompression(), keyIds, null,
appSettings.getEncryptionAlgorithm(), Id.key.none,
appSettings.getHashAlgorithm(), true, null);
}
@ -286,9 +288,9 @@ public class OpenPgpService extends RemoteService {
return;
}
PgpMain.signText(this, null, inputData, outputStream, appSettings.getKeyId(),
passphrase, appSettings.getHashAlgorithm(), Preferences.getPreferences(this)
.getForceV3Signatures());
PgpOperation operation = new PgpOperation(getContext(), null, inputData, outputStream);
operation.signText(appSettings.getKeyId(), passphrase, appSettings.getHashAlgorithm(),
Preferences.getPreferences(this).getForceV3Signatures());
outputStream.close();
@ -315,7 +317,7 @@ public class OpenPgpService extends RemoteService {
String message = new String(inputBytes);
Log.d(Constants.TAG, "in: " + message);
boolean signedOnly = false;
Matcher matcher = PgpMain.PGP_MESSAGE.matcher(message);
Matcher matcher = PgpHelper.PGP_MESSAGE.matcher(message);
if (matcher.matches()) {
Log.d(Constants.TAG, "PGP_MESSAGE matched");
message = matcher.group(1);
@ -325,7 +327,7 @@ public class OpenPgpService extends RemoteService {
// overwrite inputBytes
inputBytes = message.getBytes();
} else {
matcher = PgpMain.PGP_SIGNED_MESSAGE.matcher(message);
matcher = PgpHelper.PGP_SIGNED_MESSAGE.matcher(message);
if (matcher.matches()) {
signedOnly = true;
Log.d(Constants.TAG, "PGP_SIGNED_MESSAGE matched");
@ -368,19 +370,18 @@ public class OpenPgpService extends RemoteService {
// than 0.
inputStream2.mark(200);
}
secretKeyId = PgpMain.getDecryptionKeyId(this, inputStream2);
secretKeyId = PgpHelper.getDecryptionKeyId(this, inputStream2);
if (secretKeyId == Id.key.none) {
throw new PgpMain.PgpGeneralException(
getString(R.string.error_noSecretKeyFound));
throw new PgpGeneralException(getString(R.string.error_noSecretKeyFound));
}
assumeSymmetricEncryption = false;
} catch (PgpMain.NoAsymmetricEncryptionException e) {
} catch (NoAsymmetricEncryptionException e) {
if (inputStream2.markSupported()) {
inputStream2.reset();
}
secretKeyId = Id.key.symmetric;
if (!PgpMain.hasSymmetricEncryption(this, inputStream2)) {
throw new PgpMain.PgpGeneralException(
if (!PgpOperation.hasSymmetricEncryption(this, inputStream2)) {
throw new PgpGeneralException(
getString(R.string.error_noKnownEncryptionFound));
}
assumeSymmetricEncryption = true;
@ -404,13 +405,13 @@ public class OpenPgpService extends RemoteService {
OutputStream outputStream = new ByteArrayOutputStream();
Bundle outputBundle;
PgpOperation operation = new PgpOperation(getContext(), null, inputData, outputStream);
if (signedOnly) {
// TODO: download missing keys from keyserver?
outputBundle = PgpMain.verifyText(this, null, inputData, outputStream, false);
outputBundle = operation.verifyText(false);
} else {
// TODO: assume symmetric: callback to enter symmetric pass
outputBundle = PgpMain.decryptAndVerify(this, null, inputData, outputStream,
passphrase, assumeSymmetricEncryption);
outputBundle = operation.decryptAndVerify(passphrase, assumeSymmetricEncryption);
}
outputStream.close();

View File

@ -24,7 +24,7 @@ import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.Id;
import org.sufficientlysecure.keychain.R;
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.ui.SelectPublicKeyFragment;
import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment;
@ -316,7 +316,7 @@ public class RemoteServiceActivity extends SherlockFragmentActivity {
messenger, secretKeyId);
passphraseDialog.show(getSupportFragmentManager(), "passphraseDialog");
} catch (PgpMain.PgpGeneralException e) {
} catch (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);

View File

@ -33,7 +33,10 @@ import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
import org.sufficientlysecure.keychain.helper.ActionBarHelper;
import org.sufficientlysecure.keychain.helper.FileHelper;
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.service.KeychainIntentService;
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
@ -252,9 +255,9 @@ public class DecryptActivity extends SherlockFragmentActivity {
String data = "";
if (clipboardText != null) {
Matcher matcher = PgpMain.PGP_MESSAGE.matcher(clipboardText);
Matcher matcher = PgpHelper.PGP_MESSAGE.matcher(clipboardText);
if (!matcher.matches()) {
matcher = PgpMain.PGP_SIGNED_MESSAGE.matcher(clipboardText);
matcher = PgpHelper.PGP_SIGNED_MESSAGE.matcher(clipboardText);
}
if (matcher.matches()) {
data = matcher.group(1);
@ -357,7 +360,7 @@ public class DecryptActivity extends SherlockFragmentActivity {
*/
if (ACTION_DECRYPT.equals(action) && textData != null) {
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()) {
Log.d(Constants.TAG, "PGP_MESSAGE matched");
textData = matcher.group(1);
@ -365,7 +368,7 @@ public class DecryptActivity extends SherlockFragmentActivity {
textData = textData.replaceAll("\\xa0", " ");
mMessage.setText(textData);
} else {
matcher = PgpMain.PGP_SIGNED_MESSAGE.matcher(textData);
matcher = PgpHelper.PGP_SIGNED_MESSAGE.matcher(textData);
if (matcher.matches()) {
Log.d(Constants.TAG, "PGP_SIGNED_MESSAGE matched");
textData = matcher.group(1);
@ -478,7 +481,7 @@ public class DecryptActivity extends SherlockFragmentActivity {
if (mDecryptTarget == Id.target.message) {
String messageData = mMessage.getText().toString();
Matcher matcher = PgpMain.PGP_SIGNED_MESSAGE.matcher(messageData);
Matcher matcher = PgpHelper.PGP_SIGNED_MESSAGE.matcher(messageData);
if (matcher.matches()) {
mSignedOnly = true;
decryptStart();
@ -532,7 +535,7 @@ public class DecryptActivity extends SherlockFragmentActivity {
messenger, mSecretKeyId);
passphraseDialog.show(getSupportFragmentManager(), "passphraseDialog");
} catch (PgpMain.PgpGeneralException e) {
} catch (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);
@ -578,20 +581,18 @@ public class DecryptActivity extends SherlockFragmentActivity {
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.
}
mSecretKeyId = PgpMain.getDecryptionKeyId(this, inStream);
mSecretKeyId = PgpHelper.getDecryptionKeyId(this, inStream);
if (mSecretKeyId == Id.key.none) {
throw new PgpMain.PgpGeneralException(
getString(R.string.error_noSecretKeyFound));
throw new PgpGeneralException(getString(R.string.error_noSecretKeyFound));
}
mAssumeSymmetricEncryption = false;
} catch (PgpMain.NoAsymmetricEncryptionException e) {
} catch (NoAsymmetricEncryptionException e) {
if (inStream.markSupported()) {
inStream.reset();
}
mSecretKeyId = Id.key.symmetric;
if (!PgpMain.hasSymmetricEncryption(this, inStream)) {
throw new PgpMain.PgpGeneralException(
getString(R.string.error_noKnownEncryptionFound));
if (!PgpOperation.hasSymmetricEncryption(this, inStream)) {
throw new PgpGeneralException(getString(R.string.error_noKnownEncryptionFound));
}
mAssumeSymmetricEncryption = true;
}
@ -771,8 +772,8 @@ public class DecryptActivity extends SherlockFragmentActivity {
.getString(KeychainIntentService.RESULT_SIGNATURE_USER_ID);
mSignatureKeyId = returnData
.getLong(KeychainIntentService.RESULT_SIGNATURE_KEY_ID);
mUserIdRest
.setText("id: " + PgpHelper.getSmallFingerPrint(mSignatureKeyId));
mUserIdRest.setText("id: "
+ PgpKeyHelper.getSmallFingerPrint(mSignatureKeyId));
if (userId == null) {
userId = getResources().getString(R.string.unknownUserId);
}

View File

@ -28,12 +28,13 @@ import org.sufficientlysecure.keychain.Id;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.helper.ActionBarHelper;
import org.sufficientlysecure.keychain.pgp.PgpConversionHelper;
import org.sufficientlysecure.keychain.pgp.PgpHelper;
import org.sufficientlysecure.keychain.pgp.PgpMain;
import org.sufficientlysecure.keychain.pgp.PgpMain.PgpGeneralException;
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.service.KeychainIntentService;
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.widget.KeyEditor;
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
*
@ -299,7 +332,32 @@ public class EditKeyActivity extends SherlockFragmentActivity {
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) {
mCurrentPassPhrase = "";
}
@ -310,37 +368,28 @@ public class EditKeyActivity extends SherlockFragmentActivity {
mChangePassPhrase.setVisibility(View.GONE);
}
if (extras != null) {
if (extras.containsKey(EXTRA_MASTER_CAN_SIGN)) {
masterCanSign = extras.getBoolean(EXTRA_MASTER_CAN_SIGN);
if (masterKeyId != 0) {
PGPSecretKey masterKey = null;
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)) {
long masterKeyId = extras.getLong(EXTRA_MASTER_KEY_ID);
if (masterKeyId != 0) {
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);
}
}
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() {
try {
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
@ -480,7 +529,7 @@ public class EditKeyActivity extends SherlockFragmentActivity {
// start service with intent
startService(intent);
} catch (PgpMain.PgpGeneralException e) {
} catch (PgpGeneralException e) {
Toast.makeText(this, getString(R.string.errorMessage, e.getMessage()),
Toast.LENGTH_SHORT).show();
}
@ -497,8 +546,7 @@ public class EditKeyActivity extends SherlockFragmentActivity {
* @param userIdsView
* @return
*/
private ArrayList<String> getUserIds(SectionView userIdsView)
throws PgpMain.PgpGeneralException {
private ArrayList<String> getUserIds(SectionView userIdsView) throws PgpGeneralException {
ArrayList<String> userIds = new ArrayList<String>();
ViewGroup userIdEditors = userIdsView.getEditors();
@ -510,13 +558,12 @@ public class EditKeyActivity extends SherlockFragmentActivity {
try {
userId = editor.getValue();
} catch (UserIdEditor.NoNameException e) {
throw new PgpMain.PgpGeneralException(
this.getString(R.string.error_userIdNeedsAName));
throw new PgpGeneralException(this.getString(R.string.error_userIdNeedsAName));
} catch (UserIdEditor.NoEmailException e) {
throw new PgpMain.PgpGeneralException(
throw new PgpGeneralException(
this.getString(R.string.error_userIdNeedsAnEmailAddress));
} catch (UserIdEditor.InvalidEmailException e) {
throw new PgpMain.PgpGeneralException(e.getMessage());
throw new PgpGeneralException(e.getMessage());
}
if (userId.equals("")) {
@ -532,12 +579,11 @@ public class EditKeyActivity extends SherlockFragmentActivity {
}
if (userIds.size() == 0) {
throw new PgpMain.PgpGeneralException(getString(R.string.error_keyNeedsAUserId));
throw new PgpGeneralException(getString(R.string.error_keyNeedsAUserId));
}
if (!gotMainUserId) {
throw new PgpMain.PgpGeneralException(
getString(R.string.error_mainUserIdMustNotBeEmpty));
throw new PgpGeneralException(getString(R.string.error_mainUserIdMustNotBeEmpty));
}
return userIds;
@ -549,14 +595,13 @@ public class EditKeyActivity extends SherlockFragmentActivity {
* @param keysView
* @return
*/
private ArrayList<PGPSecretKey> getKeys(SectionView keysView)
throws PgpMain.PgpGeneralException {
private ArrayList<PGPSecretKey> getKeys(SectionView keysView) throws PgpGeneralException {
ArrayList<PGPSecretKey> keys = new ArrayList<PGPSecretKey>();
ViewGroup keyEditors = keysView.getEditors();
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) {
@ -573,14 +618,13 @@ public class EditKeyActivity extends SherlockFragmentActivity {
* @param keysView
* @return
*/
private ArrayList<Integer> getKeysUsages(SectionView keysView)
throws PgpMain.PgpGeneralException {
private ArrayList<Integer> getKeysUsages(SectionView keysView) throws PgpGeneralException {
ArrayList<Integer> getKeysUsages = new ArrayList<Integer>();
ViewGroup keyEditors = keysView.getEditors();
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) {

View File

@ -31,8 +31,8 @@ import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
import org.sufficientlysecure.keychain.helper.ActionBarHelper;
import org.sufficientlysecure.keychain.helper.FileHelper;
import org.sufficientlysecure.keychain.helper.Preferences;
import org.sufficientlysecure.keychain.pgp.PgpHelper;
import org.sufficientlysecure.keychain.pgp.PgpMain;
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.service.KeychainIntentService;
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
@ -302,9 +302,9 @@ public class EncryptActivity extends SherlockFragmentActivity {
preselectedSignatureKeyId);
PGPSecretKey masterKey = null;
if (keyRing != null) {
masterKey = PgpHelper.getMasterKey(keyRing);
masterKey = PgpKeyHelper.getMasterKey(keyRing);
if (masterKey != null) {
Vector<PGPSecretKey> signKeys = PgpHelper.getUsableSigningKeys(keyRing);
Vector<PGPSecretKey> signKeys = PgpKeyHelper.getUsableSigningKeys(keyRing);
if (signKeys.size() > 0) {
mSecretKeyId = masterKey.getKeyID();
}
@ -321,11 +321,11 @@ public class EncryptActivity extends SherlockFragmentActivity {
if (keyRing == null) {
continue;
}
masterKey = PgpHelper.getMasterKey(keyRing);
masterKey = PgpKeyHelper.getMasterKey(keyRing);
if (masterKey == null) {
continue;
}
Vector<PGPPublicKey> encryptKeys = PgpHelper.getUsableEncryptKeys(keyRing);
Vector<PGPPublicKey> encryptKeys = PgpKeyHelper.getUsableEncryptKeys(keyRing);
if (encryptKeys.size() == 0) {
continue;
}
@ -570,7 +570,7 @@ public class EncryptActivity extends SherlockFragmentActivity {
EncryptActivity.this, messenger, mSecretKeyId);
passphraseDialog.show(getSupportFragmentManager(), "passphraseDialog");
} catch (PgpMain.PgpGeneralException e) {
} catch (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);
@ -914,9 +914,9 @@ public class EncryptActivity extends SherlockFragmentActivity {
PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(this,
mSecretKeyId);
if (keyRing != null) {
PGPSecretKey key = PgpHelper.getMasterKey(keyRing);
PGPSecretKey key = PgpKeyHelper.getMasterKey(keyRing);
if (key != null) {
String userId = PgpHelper.getMainUserIdSafe(this, key);
String userId = PgpKeyHelper.getMainUserIdSafe(this, key);
String chunks[] = userId.split(" <", 2);
uid = chunks[0];
if (chunks.length > 1) {

View File

@ -19,7 +19,7 @@ package org.sufficientlysecure.keychain.ui;
import org.spongycastle.openpgp.PGPPublicKeyRing;
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.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds;
@ -97,7 +97,7 @@ public class KeyListPublicFragment extends KeyListFragment implements
PGPPublicKeyRing updateKeyRing = ProviderHelper.getPGPPublicKeyRingByRowId(
mKeyListActivity, keyRingRowId);
if (updateKeyRing != null) {
updateKeyId = PgpHelper.getMasterKey(updateKeyRing).getKeyID();
updateKeyId = PgpKeyHelper.getMasterKey(updateKeyRing).getKeyID();
}
if (updateKeyId == 0) {
// this shouldn't happen
@ -126,7 +126,7 @@ public class KeyListPublicFragment extends KeyListFragment implements
PGPPublicKeyRing signKeyRing = ProviderHelper.getPGPPublicKeyRingByRowId(
mKeyListActivity, keyRingRowId);
if (signKeyRing != null) {
keyId = PgpHelper.getMasterKey(signKeyRing).getKeyID();
keyId = PgpKeyHelper.getMasterKey(signKeyRing).getKeyID();
}
if (keyId == 0) {
// this shouldn't happen

View File

@ -19,20 +19,13 @@ package org.sufficientlysecure.keychain.ui;
import org.sufficientlysecure.keychain.Constants;
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 com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Messenger;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;
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() {
PgpMain.setEditPassPhrase("");
Intent intent = new Intent(this, EditKeyActivity.class);
intent.setAction(EditKeyActivity.ACTION_CREATE_KEY);
intent.putExtra(EditKeyActivity.EXTRA_GENERATE_DEFAULT_KEYS, true);
@ -127,13 +79,12 @@ public class KeyListSecretActivity extends KeyListActivity {
}
private void createKeyExpert() {
PgpMain.setEditPassPhrase("");
Intent intent = new Intent(this, EditKeyActivity.class);
intent.setAction(EditKeyActivity.ACTION_CREATE_KEY);
startActivityForResult(intent, 0);
}
private void editKey(long masterKeyId, boolean masterCanSign) {
void editKey(long masterKeyId, boolean masterCanSign) {
Intent intent = new Intent(this, EditKeyActivity.class);
intent.setAction(EditKeyActivity.ACTION_EDIT_KEY);
intent.putExtra(EditKeyActivity.EXTRA_MASTER_KEY_ID, masterKeyId);

View File

@ -91,7 +91,7 @@ public class KeyListSecretFragment extends KeyListFragment implements
switch (item.getItemId()) {
case Id.menu.edit:
mKeyListSecretActivity.checkPassPhraseAndEdit(masterKeyId, masterCanSign);
mKeyListSecretActivity.editKey(masterKeyId, masterCanSign);
return true;

View File

@ -23,7 +23,7 @@ import java.util.List;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.Id;
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.KeychainIntentServiceHandler;
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)) {
long keyId = intent.getLongExtra(EXTRA_KEY_ID, 0);
if (keyId != 0) {
String query = "0x" + PgpHelper.keyToHex(keyId);
String query = "0x" + PgpKeyHelper.keyToHex(keyId);
mQuery.setText(query);
search(query);
}
@ -308,7 +308,7 @@ public class KeyServerQueryActivity extends SherlockFragmentActivity {
mainUserId.setText(userId);
}
keyId.setText(PgpHelper.getSmallFingerPrint(keyInfo.keyId));
keyId.setText(PgpKeyHelper.getSmallFingerPrint(keyInfo.keyId));
if (mainUserIdRest.getText().length() == 0) {
mainUserIdRest.setVisibility(View.GONE);

View File

@ -22,18 +22,15 @@ import org.spongycastle.openpgp.PGPPublicKeyRing;
import org.spongycastle.openpgp.PGPSignature;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.Id;
import org.sufficientlysecure.keychain.R;
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.service.KeychainIntentService;
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
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 com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import android.app.ProgressDialog;
import android.content.Intent;
@ -51,6 +48,9 @@ import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.Spinner;
import android.widget.Toast;
import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.SherlockFragmentActivity;
/**
* gpg --sign-key
*
@ -144,7 +144,7 @@ public class SignKeyActivity extends SherlockFragmentActivity {
messenger, secretKeyId);
passphraseDialog.show(getSupportFragmentManager(), "passphraseDialog");
} catch (PgpMain.PgpGeneralException e) {
} catch (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);

View File

@ -21,7 +21,7 @@ import org.spongycastle.openpgp.PGPPublicKeyRing;
import org.spongycastle.openpgp.PGPSecretKeyRing;
import org.sufficientlysecure.keychain.Constants;
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.util.Log;
import org.sufficientlysecure.keychain.R;
@ -79,11 +79,11 @@ public class DeleteKeyDialogFragment extends DialogFragment {
if (keyType == Id.type.public_key) {
PGPPublicKeyRing keyRing = ProviderHelper.getPGPPublicKeyRingByRowId(activity,
deleteKeyRingRowId);
userId = PgpHelper.getMainUserIdSafe(activity, PgpHelper.getMasterKey(keyRing));
userId = PgpKeyHelper.getMainUserIdSafe(activity, PgpKeyHelper.getMasterKey(keyRing));
} else {
PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByRowId(activity,
deleteKeyRingRowId);
userId = PgpHelper.getMainUserIdSafe(activity, PgpHelper.getMasterKey(keyRing));
userId = PgpKeyHelper.getMainUserIdSafe(activity, PgpKeyHelper.getMasterKey(keyRing));
}
AlertDialog.Builder builder = new AlertDialog.Builder(activity);

View File

@ -19,7 +19,7 @@ package org.sufficientlysecure.keychain.ui.dialog;
import org.sufficientlysecure.keychain.Constants;
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.util.Log;
import org.sufficientlysecure.keychain.R;
@ -79,7 +79,7 @@ public class LookupUnknownKeyDialogFragment extends DialogFragment {
alert.setIcon(android.R.drawable.ic_dialog_alert);
alert.setTitle(R.string.title_unknownSignatureKey);
alert.setMessage(getString(R.string.lookupUnknownKey,
PgpHelper.getSmallFingerPrint(unknownKeyId)));
PgpKeyHelper.getSmallFingerPrint(unknownKeyId)));
alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {

View File

@ -24,13 +24,12 @@ import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor;
import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.Id;
import org.sufficientlysecure.keychain.pgp.PgpHelper;
import org.sufficientlysecure.keychain.pgp.PgpMain;
import org.sufficientlysecure.keychain.pgp.PgpMain.PgpGeneralException;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.R;
import android.app.Activity;
import android.app.AlertDialog;
@ -80,7 +79,7 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor
// check if secret key has a passphrase
if (!(secretKeyId == Id.key.symmetric || secretKeyId == Id.key.none)) {
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);
} else {
// TODO: by master key id???
secretKey = PgpHelper.getMasterKey(ProviderHelper.getPGPSecretKeyRingByKeyId(activity,
secretKey = PgpKeyHelper.getMasterKey(ProviderHelper.getPGPSecretKeyRingByKeyId(activity,
secretKeyId));
// secretKey = PGPHelper.getMasterKey(PGPMain.getSecretKeyRing(secretKeyId));
@ -135,7 +134,7 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor
canKB = false;
return alert.create();
}
String userId = PgpHelper.getMainUserIdSafe(activity, secretKey);
String userId = PgpKeyHelper.getMainUserIdSafe(activity, secretKey);
Log.d(Constants.TAG, "User id: '" + 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
try {
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder()
.setProvider(PgpMain.BOUNCY_CASTLE_PROVIDER_NAME).build(
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(
passPhrase.toCharArray());
PGPPrivateKey testKey = clickSecretKey
.extractPrivateKey(keyDecryptor);
@ -176,7 +175,7 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor
sendMessageToHandler(MESSAGE_CANCEL);
return;
} else {
clickSecretKey = PgpHelper.getKeyNum(ProviderHelper
clickSecretKey = PgpKeyHelper.getKeyNum(ProviderHelper
.getPGPSecretKeyRingByKeyId(activity, secretKeyId),
curKeyIndex);
curKeyIndex++; // does post-increment work like C?

View File

@ -32,7 +32,7 @@ import org.spongycastle.openpgp.PGPObjectFactory;
import org.spongycastle.openpgp.PGPSecretKeyRing;
import org.spongycastle.openpgp.PGPUtil;
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.Log;
import org.sufficientlysecure.keychain.util.PositionAwareInputStream;
@ -142,13 +142,13 @@ public class ImportKeysListLoader extends AsyncTaskLoader<List<Map<String, Strin
}
private void addToData(PGPKeyRing keyring) {
String userId = PgpHelper.getMainUserId(keyring.getPublicKey());
String userId = PgpKeyHelper.getMainUserId(keyring.getPublicKey());
if (keyring instanceof PGPSecretKeyRing) {
userId = mContext.getString(R.string.secretKeyring) + " " + userId;
}
String fingerprint = PgpHelper.convertFingerprintToHex(keyring.getPublicKey()
String fingerprint = PgpKeyHelper.convertFingerprintToHex(keyring.getPublicKey()
.getFingerprint());
Map<String, String> attrs = new HashMap<String, String>();

View File

@ -19,7 +19,7 @@ package org.sufficientlysecure.keychain.ui.widget;
import org.spongycastle.openpgp.PGPPublicKey;
import org.spongycastle.openpgp.PGPSecretKey;
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.R;
@ -151,9 +151,9 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener {
mDeleteButton.setVisibility(View.INVISIBLE);
}
mAlgorithm.setText(PgpHelper.getAlgorithmInfo(key));
String keyId1Str = PgpHelper.getSmallFingerPrint(key.getKeyID());
String keyId2Str = PgpHelper.getSmallFingerPrint(key.getKeyID() >> 32);
mAlgorithm.setText(PgpKeyHelper.getAlgorithmInfo(key));
String keyId1Str = PgpKeyHelper.getSmallFingerPrint(key.getKeyID());
String keyId2Str = PgpKeyHelper.getSmallFingerPrint(key.getKeyID() >> 32);
mKeyId.setText(keyId1Str + " " + keyId2Str);
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
int selectId = 0;
if (PgpHelper.isEncryptionKey(key)) {
if (PgpHelper.isSigningKey(key)) {
if (PgpKeyHelper.isEncryptionKey(key)) {
if (PgpKeyHelper.isSigningKey(key)) {
selectId = Id.choice.usage.sign_and_encrypt;
} else {
selectId = Id.choice.usage.encrypt_only;
@ -203,14 +203,14 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener {
}
GregorianCalendar cal = new GregorianCalendar();
cal.setTime(PgpHelper.getCreationDate(key));
cal.setTime(PgpKeyHelper.getCreationDate(key));
mCreationDate.setText(DateFormat.getDateInstance().format(cal.getTime()));
cal = new GregorianCalendar();
Date date = PgpHelper.getExpiryDate(key);
Date date = PgpKeyHelper.getExpiryDate(key);
if (date == null) {
setExpiryDate(null);
} else {
cal.setTime(PgpHelper.getExpiryDate(key));
cal.setTime(PgpKeyHelper.getExpiryDate(key));
setExpiryDate(cal);
}

View File

@ -19,7 +19,7 @@ package org.sufficientlysecure.keychain.ui.widget;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.Id;
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.UserIds;
import org.sufficientlysecure.keychain.util.Log;
@ -117,7 +117,7 @@ public class KeyListAdapter extends CursorTreeAdapter {
keyLayout.setVisibility(View.GONE);
userIdLayout.setVisibility(View.VISIBLE);
String fingerprint = PgpHelper.getFingerPrint(context,
String fingerprint = PgpKeyHelper.getFingerPrint(context,
cursor.getLong(cursor.getColumnIndex(Keys.KEY_ID)));
fingerprint = fingerprint.replace(" ", "\n");
@ -132,9 +132,9 @@ public class KeyListAdapter extends CursorTreeAdapter {
keyLayout.setVisibility(View.VISIBLE);
userIdLayout.setVisibility(View.GONE);
String keyIdStr = PgpHelper.getSmallFingerPrint(cursor.getLong(cursor
String keyIdStr = PgpKeyHelper.getSmallFingerPrint(cursor.getLong(cursor
.getColumnIndex(Keys.KEY_ID)));
String algorithmStr = PgpHelper.getAlgorithmInfo(
String algorithmStr = PgpKeyHelper.getAlgorithmInfo(
cursor.getInt(cursor.getColumnIndex(Keys.ALGORITHM)),
cursor.getInt(cursor.getColumnIndex(Keys.KEY_SIZE)));

View File

@ -19,7 +19,7 @@ package org.sufficientlysecure.keychain.ui.widget;
import org.sufficientlysecure.keychain.Id;
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.UserIds;
import org.sufficientlysecure.keychain.R;
@ -87,7 +87,7 @@ public class SelectKeyCursorAdapter extends CursorAdapter {
}
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) {
mainUserIdRest.setVisibility(View.GONE);

View File

@ -44,7 +44,7 @@ import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.sufficientlysecure.keychain.pgp.PgpHelper;
import org.sufficientlysecure.keychain.pgp.PgpMain;
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
import android.text.Html;
@ -179,8 +179,8 @@ public class HkpKeyServer extends KeyServer {
KeyInfo info = new KeyInfo();
info.size = Integer.parseInt(matcher.group(1));
info.algorithm = matcher.group(2);
info.keyId = PgpHelper.keyFromHex(matcher.group(3));
info.fingerPrint = PgpHelper.getSmallFingerPrint(info.keyId);
info.keyId = PgpKeyHelper.keyFromHex(matcher.group(3));
info.fingerPrint = PgpKeyHelper.getSmallFingerPrint(info.keyId);
String chunks[] = matcher.group(4).split("-");
info.date = new GregorianCalendar(Integer.parseInt(chunks[0]),
Integer.parseInt(chunks[1]), Integer.parseInt(chunks[2])).getTime();
@ -211,7 +211,7 @@ public class HkpKeyServer extends KeyServer {
HttpClient client = new DefaultHttpClient();
try {
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);
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
@ -221,7 +221,7 @@ public class HkpKeyServer extends KeyServer {
HttpEntity entity = response.getEntity();
InputStream is = entity.getContent();
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()) {
return matcher.group(1);
}