mirror of
https://github.com/moparisthebest/open-keychain
synced 2024-11-24 01:32:16 -05:00
Merge branch 'master' of github.com:open-keychain/open-keychain
This commit is contained in:
commit
4db0194e6a
@ -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();
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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>() {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user