certify: sign individual UIDs

direct signing of pubkeys is out for now. not sure how this should be
handled, but it's trivial to re-add so leaving this up for discussion
for now.
This commit is contained in:
Vincent Breitmoser 2014-03-15 18:12:44 +01:00
parent a3224687f6
commit 95be228b47
3 changed files with 31 additions and 12 deletions

View File

@ -408,7 +408,16 @@ public class PgpKeyOperation {
updateProgress(R.string.progress_done, 100, 100); updateProgress(R.string.progress_done, 100, 100);
} }
public PGPPublicKeyRing certifyKey(long masterKeyId, long pubKeyId, String passphrase) /**
* Certify the given pubkeyid with the given masterkeyid.
*
* @param masterKeyId Certifying key, must be available as secret key
* @param pubKeyId ID of 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 PGPPublicKeyRing certifyKey(long masterKeyId, long pubKeyId, List<String> userIds, String passphrase)
throws PgpGeneralException, NoSuchAlgorithmException, NoSuchProviderException, throws PgpGeneralException, NoSuchAlgorithmException, NoSuchProviderException,
PGPException, SignatureException { PGPException, SignatureException {
if (passphrase == null) { if (passphrase == null) {
@ -437,7 +446,7 @@ public class PgpKeyOperation {
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
signatureGenerator = new PGPSignatureGenerator(contentSignerBuilder); signatureGenerator = new PGPSignatureGenerator(contentSignerBuilder);
signatureGenerator.init(PGPSignature.DIRECT_KEY, signaturePrivateKey); signatureGenerator.init(PGPSignature.DEFAULT_CERTIFICATION, signaturePrivateKey);
} }
{ // supply signatureGenerator with a SubpacketVector { // supply signatureGenerator with a SubpacketVector
@ -449,8 +458,11 @@ public class PgpKeyOperation {
// fetch public key ring, add the certification and return it // fetch public key ring, add the certification and return it
PGPPublicKeyRing pubring = ProviderHelper PGPPublicKeyRing pubring = ProviderHelper
.getPGPPublicKeyRingByKeyId(mContext, pubKeyId); .getPGPPublicKeyRingByKeyId(mContext, pubKeyId);
PGPPublicKey signedKey = PGPPublicKey.addCertification(pubring.getPublicKey(pubKeyId), PGPPublicKey signedKey = pubring.getPublicKey(pubKeyId);
signatureGenerator.generate()); for(String userId : new IterableIterator<String>(userIds.iterator())) {
PGPSignature sig = signatureGenerator.generateCertification(userId, signedKey);
signedKey = PGPPublicKey.addCertification(signedKey, userId, sig);
}
pubring = PGPPublicKeyRing.insertPublicKey(pubring, signedKey); pubring = PGPPublicKeyRing.insertPublicKey(pubring, signedKey);
return pubring; return pubring;

View File

@ -805,7 +805,7 @@ public class KeychainIntentService extends IntentService
/* Input */ /* Input */
long masterKeyId = data.getLong(CERTIFY_KEY_MASTER_KEY_ID); long masterKeyId = data.getLong(CERTIFY_KEY_MASTER_KEY_ID);
long pubKeyId = data.getLong(CERTIFY_KEY_PUB_KEY_ID); long pubKeyId = data.getLong(CERTIFY_KEY_PUB_KEY_ID);
// String[] userIds = data.getStringArray(CERTIFY_KEY_PUB_KEY_ID); ArrayList<String> userIds = data.getStringArrayList(CERTIFY_KEY_UIDS);
/* Operation */ /* Operation */
String signaturePassPhrase = PassphraseCacheService.getCachedPassphrase(this, String signaturePassPhrase = PassphraseCacheService.getCachedPassphrase(this,
@ -813,7 +813,7 @@ public class KeychainIntentService extends IntentService
PgpKeyOperation keyOperation = new PgpKeyOperation(this, this); PgpKeyOperation keyOperation = new PgpKeyOperation(this, this);
PGPPublicKeyRing signedPubKeyRing = keyOperation.certifyKey(masterKeyId, pubKeyId, PGPPublicKeyRing signedPubKeyRing = keyOperation.certifyKey(masterKeyId, pubKeyId,
signaturePassPhrase); userIds, signaturePassPhrase);
// store the signed key in our local cache // store the signed key in our local cache
PgpImportExport pgpImportExport = new PgpImportExport(this, null); PgpImportExport pgpImportExport = new PgpImportExport(this, null);

View File

@ -30,14 +30,12 @@ import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader; import android.support.v4.content.Loader;
import android.support.v7.app.ActionBar; import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity; import android.support.v7.app.ActionBarActivity;
import android.text.format.DateFormat;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
import android.widget.*; import android.widget.*;
import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.CompoundButton.OnCheckedChangeListener;
import com.beardedhen.androidbootstrap.BootstrapButton; import com.beardedhen.androidbootstrap.BootstrapButton;
import org.spongycastle.openpgp.PGPPublicKeyRing; import org.spongycastle.openpgp.PGPPublicKeyRing;
import org.spongycastle.openpgp.PGPSignature;
import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.helper.OtherHelper; import org.sufficientlysecure.keychain.helper.OtherHelper;
@ -53,8 +51,7 @@ import org.sufficientlysecure.keychain.ui.adapter.ViewKeyUserIdsAdapter;
import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment; import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment;
import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Log;
import java.util.Date; import java.util.ArrayList;
import java.util.Iterator;
/** /**
* Signs the specified public key with the specified secret master key * Signs the specified public key with the specified secret master key
@ -267,6 +264,7 @@ public class CertifyKeyActivity extends ActionBarActivity implements
// if we have already signed this key, dont bother doing it again // if we have already signed this key, dont bother doing it again
boolean alreadySigned = false; boolean alreadySigned = false;
/* todo: reconsider this at a later point when certs are in the db
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
Iterator<PGPSignature> itr = pubring.getPublicKey(mPubKeyId).getSignatures(); Iterator<PGPSignature> itr = pubring.getPublicKey(mPubKeyId).getSignatures();
while (itr.hasNext()) { while (itr.hasNext()) {
@ -276,6 +274,7 @@ public class CertifyKeyActivity extends ActionBarActivity implements
break; break;
} }
} }
*/
if (!alreadySigned) { if (!alreadySigned) {
/* /*
@ -303,6 +302,15 @@ public class CertifyKeyActivity extends ActionBarActivity implements
* kicks off the actual signing process on a background thread * kicks off the actual signing process on a background thread
*/ */
private void startSigning() { private void startSigning() {
// Bail out if there is not at least one user id selected
ArrayList<String> userIds = mUserIdsAdapter.getSelectedUserIds();
if(userIds.isEmpty()) {
Toast.makeText(CertifyKeyActivity.this, "No User IDs to sign selected!",
Toast.LENGTH_SHORT).show();
return;
}
// Send all information needed to service to sign key in other thread // Send all information needed to service to sign key in other thread
Intent intent = new Intent(this, KeychainIntentService.class); Intent intent = new Intent(this, KeychainIntentService.class);
@ -313,8 +321,7 @@ public class CertifyKeyActivity extends ActionBarActivity implements
data.putLong(KeychainIntentService.CERTIFY_KEY_MASTER_KEY_ID, mMasterKeyId); data.putLong(KeychainIntentService.CERTIFY_KEY_MASTER_KEY_ID, mMasterKeyId);
data.putLong(KeychainIntentService.CERTIFY_KEY_PUB_KEY_ID, mPubKeyId); data.putLong(KeychainIntentService.CERTIFY_KEY_PUB_KEY_ID, mPubKeyId);
data.putStringArray(KeychainIntentService.CERTIFY_KEY_UIDS, data.putStringArrayList(KeychainIntentService.CERTIFY_KEY_UIDS, userIds);
(String[]) mUserIdsAdapter.getSelectedUserIds().toArray());
intent.putExtra(KeychainIntentService.EXTRA_DATA, data); intent.putExtra(KeychainIntentService.EXTRA_DATA, data);