Merge branch 'master' of github.com:open-keychain/open-keychain

This commit is contained in:
Dominik Schürmann 2014-06-22 16:03:13 +02:00
commit 4db0194e6a
7 changed files with 95 additions and 133 deletions

View File

@ -46,6 +46,7 @@ public class ImportKeysListEntry implements Serializable, Parcelable {
private String mExtraData;
private String mQuery;
private String mOrigin;
private Integer mHashCode = null;
private boolean mSelected;
@ -98,6 +99,13 @@ public class ImportKeysListEntry implements Serializable, Parcelable {
}
};
public int hashCode() {
if (mHashCode != null) {
return mHashCode;
}
return super.hashCode();
}
public String getKeyIdHex() {
return mKeyIdHex;
}
@ -240,6 +248,8 @@ public class ImportKeysListEntry implements Serializable, Parcelable {
mSecretKey = ring.isSecret();
UncachedPublicKey key = ring.getPublicKey();
mHashCode = key.hashCode();
mPrimaryUserId = key.getPrimaryUserId();
mUserIds = key.getUnorderedUserIds();

View File

@ -27,7 +27,9 @@ public class ParcelableKeyRing implements Parcelable {
public static final Creator<ParcelableKeyRing> CREATOR = new Creator<ParcelableKeyRing>() {
public ParcelableKeyRing createFromParcel(final Parcel source) {
return new ParcelableKeyRing(source.createByteArray());
byte[] bytes = source.createByteArray();
String expectedFingerprint = source.readString();
return new ParcelableKeyRing(bytes, expectedFingerprint);
}
public ParcelableKeyRing[] newArray(final int size) {

View File

@ -481,58 +481,4 @@ public class PgpKeyOperation {
}
/**
* Certify the given pubkeyid with the given masterkeyid.
*
* @param certificationKey Certifying key
* @param publicKey public key to certify
* @param userIds User IDs to certify, must not be null or empty
* @param passphrase Passphrase of the secret key
* @return A keyring with added certifications
*/
public PGPPublicKey certifyKey(PGPSecretKey certificationKey, PGPPublicKey publicKey,
List<String> userIds, String passphrase)
throws PgpGeneralMsgIdException, NoSuchAlgorithmException, NoSuchProviderException,
PGPException, SignatureException {
// create a signatureGenerator from the supplied masterKeyId and passphrase
PGPSignatureGenerator signatureGenerator;
{
if (certificationKey == null) {
throw new PgpGeneralMsgIdException(R.string.error_no_signature_key);
}
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(
Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(passphrase.toCharArray());
PGPPrivateKey signaturePrivateKey = certificationKey.extractPrivateKey(keyDecryptor);
if (signaturePrivateKey == null) {
throw new PgpGeneralMsgIdException(R.string.error_could_not_extract_private_key);
}
// TODO: SHA256 fixed?
JcaPGPContentSignerBuilder contentSignerBuilder = new JcaPGPContentSignerBuilder(
certificationKey.getPublicKey().getAlgorithm(), PGPUtil.SHA256)
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
signatureGenerator = new PGPSignatureGenerator(contentSignerBuilder);
signatureGenerator.init(PGPSignature.DEFAULT_CERTIFICATION, signaturePrivateKey);
}
{ // supply signatureGenerator with a SubpacketVector
PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator();
PGPSignatureSubpacketVector packetVector = spGen.generate();
signatureGenerator.setHashedSubpackets(packetVector);
}
// fetch public key ring, add the certification and return it
for (String userId : new IterableIterator<String>(userIds.iterator())) {
PGPSignature sig = signatureGenerator.generateCertification(userId, publicKey);
publicKey = PGPPublicKey.addCertification(publicKey, userId, sig);
}
return publicKey;
}
}

View File

@ -498,13 +498,12 @@ public class ProviderHelper {
}
}
mIndent -= 1;
} catch (IOException e) {
log(LogLevel.ERROR, LogType.MSG_IP_FAIL_IO_EXC);
Log.e(Constants.TAG, "IOException during import", e);
mIndent -= 1;
return SaveKeyringResult.RESULT_ERROR;
} finally {
mIndent -= 1;
}
try {
@ -523,19 +522,16 @@ public class ProviderHelper {
mContentResolver.applyBatch(KeychainContract.CONTENT_AUTHORITY, operations);
log(LogLevel.OK, LogType.MSG_IP_SUCCESS);
mIndent -= 1;
progress.setProgress(LogType.MSG_IP_SUCCESS.getMsgId(), 90, 100);
return result;
} catch (RemoteException e) {
log(LogLevel.ERROR, LogType.MSG_IP_FAIL_REMOTE_EX);
Log.e(Constants.TAG, "RemoteException during import", e);
mIndent -= 1;
return SaveKeyringResult.RESULT_ERROR;
} catch (OperationApplicationException e) {
log(LogLevel.ERROR, LogType.MSG_IP_FAIL_OP_EXC);
Log.e(Constants.TAG, "OperationApplicationException during import", e);
mIndent -= 1;
return SaveKeyringResult.RESULT_ERROR;
}
@ -581,76 +577,81 @@ public class ProviderHelper {
log(LogLevel.START, LogType.MSG_IS,
new String[]{ PgpKeyHelper.convertKeyIdToHex(masterKeyId) });
mIndent += 1;
// Canonicalize this key, to assert a number of assumptions made about it.
keyRing = keyRing.canonicalize(mLog, mIndent);
if (keyRing == null) {
return SaveKeyringResult.RESULT_ERROR;
}
// IF this is successful, it's a secret key
int result = SaveKeyringResult.SAVED_SECRET;
// save secret keyring
try {
ContentValues values = new ContentValues();
values.put(KeyRingData.MASTER_KEY_ID, masterKeyId);
values.put(KeyRingData.KEY_RING_DATA, keyRing.getEncoded());
// insert new version of this keyRing
Uri uri = KeyRingData.buildSecretKeyRingUri(Long.toString(masterKeyId));
if (mContentResolver.insert(uri, values) == null) {
log(LogLevel.ERROR, LogType.MSG_IS_DB_EXCEPTION);
// Canonicalize this key, to assert a number of assumptions made about it.
keyRing = keyRing.canonicalize(mLog, mIndent);
if (keyRing == null) {
return SaveKeyringResult.RESULT_ERROR;
}
} catch (IOException e) {
Log.e(Constants.TAG, "Failed to encode key!", e);
log(LogLevel.ERROR, LogType.MSG_IS_FAIL_IO_EXC);
return SaveKeyringResult.RESULT_ERROR;
}
{
Uri uri = Keys.buildKeysUri(Long.toString(masterKeyId));
// IF this is successful, it's a secret key
int result = SaveKeyringResult.SAVED_SECRET;
// first, mark all keys as not available
ContentValues values = new ContentValues();
values.put(Keys.HAS_SECRET, 0);
mContentResolver.update(uri, values, null, null);
// save secret keyring
try {
ContentValues values = new ContentValues();
values.put(KeyRingData.MASTER_KEY_ID, masterKeyId);
values.put(KeyRingData.KEY_RING_DATA, keyRing.getEncoded());
// insert new version of this keyRing
Uri uri = KeyRingData.buildSecretKeyRingUri(Long.toString(masterKeyId));
if (mContentResolver.insert(uri, values) == null) {
log(LogLevel.ERROR, LogType.MSG_IS_DB_EXCEPTION);
return SaveKeyringResult.RESULT_ERROR;
}
} catch (IOException e) {
Log.e(Constants.TAG, "Failed to encode key!", e);
log(LogLevel.ERROR, LogType.MSG_IS_FAIL_IO_EXC);
return SaveKeyringResult.RESULT_ERROR;
}
values.put(Keys.HAS_SECRET, 1);
// then, mark exactly the keys we have available
log(LogLevel.INFO, LogType.MSG_IS_IMPORTING_SUBKEYS);
mIndent += 1;
Set<Long> available = keyRing.getAvailableSubkeys();
for (UncachedPublicKey sub :
new IterableIterator<UncachedPublicKey>(keyRing.getPublicKeys())) {
long id = sub.getKeyId();
if(available.contains(id)) {
int upd = mContentResolver.update(uri, values, Keys.KEY_ID + " = ?",
new String[] { Long.toString(id) });
if (upd == 1) {
log(LogLevel.DEBUG, LogType.MSG_IS_SUBKEY_OK, new String[]{
PgpKeyHelper.convertKeyIdToHex(id)
});
{
Uri uri = Keys.buildKeysUri(Long.toString(masterKeyId));
// first, mark all keys as not available
ContentValues values = new ContentValues();
values.put(Keys.HAS_SECRET, 0);
mContentResolver.update(uri, values, null, null);
values.put(Keys.HAS_SECRET, 1);
// then, mark exactly the keys we have available
log(LogLevel.INFO, LogType.MSG_IS_IMPORTING_SUBKEYS);
mIndent += 1;
Set<Long> available = keyRing.getAvailableSubkeys();
for (UncachedPublicKey sub :
new IterableIterator<UncachedPublicKey>(keyRing.getPublicKeys())) {
long id = sub.getKeyId();
if (available.contains(id)) {
int upd = mContentResolver.update(uri, values, Keys.KEY_ID + " = ?",
new String[]{Long.toString(id)});
if (upd == 1) {
log(LogLevel.DEBUG, LogType.MSG_IS_SUBKEY_OK, new String[]{
PgpKeyHelper.convertKeyIdToHex(id)
});
} else {
log(LogLevel.WARN, LogType.MSG_IS_SUBKEY_NONEXISTENT, new String[]{
PgpKeyHelper.convertKeyIdToHex(id)
});
}
} else {
log(LogLevel.WARN, LogType.MSG_IS_SUBKEY_NONEXISTENT, new String[]{
log(LogLevel.INFO, LogType.MSG_IS_SUBKEY_STRIPPED, new String[]{
PgpKeyHelper.convertKeyIdToHex(id)
});
}
} else {
log(LogLevel.INFO, LogType.MSG_IS_SUBKEY_STRIPPED, new String[]{
PgpKeyHelper.convertKeyIdToHex(id)
});
}
mIndent -= 1;
// this implicitly leaves all keys which were not in the secret key ring
// with has_secret = 0
}
log(LogLevel.OK, LogType.MSG_IS_SUCCESS);
return result;
} finally {
mIndent -= 1;
// this implicitly leaves all keys which were not in the secret key ring
// with has_secret = 0
}
log(LogLevel.OK, LogType.MSG_IS_SUCCESS);
return result;
}
@ -738,12 +739,13 @@ public class ProviderHelper {
}
}
mIndent -= 1;
return new SaveKeyringResult(result, mLog);
} catch (IOException e) {
log(LogLevel.ERROR, LogType.MSG_IP_FAIL_IO_EXC);
return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog);
} finally {
mIndent -= 1;
}
}
@ -833,6 +835,8 @@ public class ProviderHelper {
} catch (IOException e) {
log(LogLevel.ERROR, LogType.MSG_IS_FAIL_IO_EXC, null);
return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog);
} finally {
mIndent -= 1;
}
}

View File

@ -4,7 +4,7 @@ import android.os.Parcel;
import android.os.Parcelable;
import java.io.Serializable;
import java.util.HashMap;
import java.util.ArrayList;
/** This class is a a transferable representation for a collection of changes
* to be done on a keyring.
@ -29,14 +29,14 @@ public class SaveKeyringParcel implements Parcelable {
public String newPassphrase;
public String[] addUserIds;
public SubkeyAdd[] addSubKeys;
public ArrayList<String> addUserIds;
public ArrayList<SubkeyAdd> addSubKeys;
public SubkeyChange[] changeSubKeys;
public ArrayList<SubkeyChange> changeSubKeys;
public String changePrimaryUserId;
public String[] revokeUserIds;
public long[] revokeSubKeys;
public ArrayList<String> revokeUserIds;
public ArrayList<Long> revokeSubKeys;
public SaveKeyringParcel(long masterKeyId, byte[] fingerprint) {
mMasterKeyId = masterKeyId;
@ -73,14 +73,14 @@ public class SaveKeyringParcel implements Parcelable {
mMasterKeyId = source.readLong();
mFingerprint = source.createByteArray();
addUserIds = source.createStringArray();
addSubKeys = (SubkeyAdd[]) source.readSerializable();
addUserIds = source.createStringArrayList();
addSubKeys = (ArrayList<SubkeyAdd>) source.readSerializable();
changeSubKeys = (SubkeyChange[]) source.readSerializable();
changeSubKeys = (ArrayList<SubkeyChange>) source.readSerializable();
changePrimaryUserId = source.readString();
revokeUserIds = source.createStringArray();
revokeSubKeys = source.createLongArray();
revokeUserIds = source.createStringArrayList();
revokeSubKeys = (ArrayList<Long>) source.readSerializable();
}
@Override
@ -88,14 +88,14 @@ public class SaveKeyringParcel implements Parcelable {
destination.writeLong(mMasterKeyId);
destination.writeByteArray(mFingerprint);
destination.writeStringArray(addUserIds);
destination.writeStringList(addUserIds);
destination.writeSerializable(addSubKeys);
destination.writeSerializable(changeSubKeys);
destination.writeString(changePrimaryUserId);
destination.writeStringArray(revokeUserIds);
destination.writeLongArray(revokeSubKeys);
destination.writeStringList(revokeUserIds);
destination.writeSerializable(revokeSubKeys);
}
public static final Creator<SaveKeyringParcel> CREATOR = new Creator<SaveKeyringParcel>() {

View File

@ -79,7 +79,7 @@ public class ImportKeysListFragment extends ListFragment implements
public ArrayList<ParcelableKeyRing> getSelectedData() {
ArrayList<ParcelableKeyRing> result = new ArrayList<ParcelableKeyRing>();
for (ImportKeysListEntry entry : getSelectedEntries()) {
result.add(mCachedKeyData.get(entry.getKeyId()));
result.add(mCachedKeyData.get(entry.hashCode()));
}
return result;
}

View File

@ -138,7 +138,7 @@ public class ImportKeysListLoader
for(UncachedKeyRing key : rings) {
ImportKeysListEntry item = new ImportKeysListEntry(getContext(), key);
mData.add(item);
mParcelableRings.put(key.getMasterKeyId(), new ParcelableKeyRing(key.getEncoded()));
mParcelableRings.put(item.hashCode(), new ParcelableKeyRing(key.getEncoded()));
isEmpty = false;
}
}