create new keys without lots of extra certification

This commit is contained in:
Ashley Hughes 2014-02-01 17:01:03 +00:00
commit af5e01db8e
8 changed files with 89 additions and 90 deletions

View File

@ -80,9 +80,27 @@ public class PgpConversionHelper {
* @return
*/
public static PGPSecretKey BytesToPGPSecretKey(byte[] keyBytes) {
PGPSecretKey key = BytesToPGPSecretKeyList(keyBytes).get(0);
PGPObjectFactory factory = new PGPObjectFactory(keyBytes);
Object obj = null;
try {
obj = factory.nextObject();
} catch (IOException e) {
Log.e(Constants.TAG, "Error while converting to PGPSecretKey!", e);
}
PGPSecretKey secKey = null;
if(obj instanceof PGPSecretKey) {
if ((secKey = (PGPSecretKey)obj ) == null) {
Log.e(Constants.TAG, "No keys given!");
}
} else if(obj instanceof PGPSecretKeyRing) { //master keys are sent as keyrings
PGPSecretKeyRing keyRing = null;
if ((keyRing = (PGPSecretKeyRing)obj) == null) {
Log.e(Constants.TAG, "No keys given!");
}
secKey = keyRing.getSecretKey();
}
return key;
return secKey;
}
/**

View File

@ -103,15 +103,12 @@ public class PgpKeyOperation {
}
/**
* 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).
* Creates new secret key.
*
* @param algorithmChoice
* @param keySize
* @param passPhrase
* @param masterSecretKey
* @param isMasterKey
* @return
* @throws NoSuchAlgorithmException
* @throws PGPException
@ -119,9 +116,11 @@ public class PgpKeyOperation {
* @throws PgpGeneralException
* @throws InvalidAlgorithmParameterException
*/
public PGPSecretKeyRing createKey(int algorithmChoice, int keySize, String passPhrase,
PGPSecretKey masterSecretKey) throws NoSuchAlgorithmException, PGPException,
NoSuchProviderException, PgpGeneralException, InvalidAlgorithmParameterException {
// TODO: key flags?
public PGPSecretKey createKey(int algorithmChoice, int keySize, String passPhrase,
boolean isMasterKey) throws NoSuchAlgorithmException, PGPException, NoSuchProviderException,
PgpGeneralException, InvalidAlgorithmParameterException {
if (keySize < 512) {
throw new PgpGeneralException(mContext.getString(R.string.error_key_size_minimum512bit));
@ -143,7 +142,7 @@ public class PgpKeyOperation {
}
case Id.choice.algorithm.elgamal: {
if (masterSecretKey == null) {
if (isMasterKey) {
throw new PgpGeneralException(
mContext.getString(R.string.error_master_key_must_not_be_el_gamal));
}
@ -183,36 +182,11 @@ public class PgpKeyOperation {
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);
PGPSecretKey secKey = new PGPSecretKey(keyPair.getPrivateKey(), keyPair.getPublicKey(),
sha1Calc, isMasterKey, keyEncryptor);
// 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;
return secKey;
}
public void changeSecretKeyPassphrase(PGPSecretKeyRing keyRing, String oldPassPhrase,

View File

@ -561,21 +561,17 @@ public class KeychainIntentService extends IntentService implements ProgressDial
int algorithm = data.getInt(GENERATE_KEY_ALGORITHM);
String passphrase = data.getString(GENERATE_KEY_SYMMETRIC_PASSPHRASE);
int keysize = data.getInt(GENERATE_KEY_KEY_SIZE);
PGPSecretKey masterKey = null;
if (data.containsKey(GENERATE_KEY_MASTER_KEY)) {
masterKey = PgpConversionHelper.BytesToPGPSecretKey(data
.getByteArray(GENERATE_KEY_MASTER_KEY));
}
boolean masterKey = data.getBoolean(GENERATE_KEY_MASTER_KEY);
/* Operation */
PgpKeyOperation keyOperations = new PgpKeyOperation(this, this);
PGPSecretKeyRing newKeyRing = keyOperations.createKey(algorithm, keysize,
PGPSecretKey newKey = keyOperations.createKey(algorithm, keysize,
passphrase, masterKey);
/* Output */
Bundle resultData = new Bundle();
resultData.putByteArray(RESULT_NEW_KEY,
PgpConversionHelper.PGPSecretKeyRingToBytes(newKeyRing));
PgpConversionHelper.PGPSecretKeyToBytes(newKey));
OtherHelper.logDebugBundle(resultData, "resultData");
@ -592,18 +588,21 @@ public class KeychainIntentService extends IntentService implements ProgressDial
/* Operation */
PgpKeyOperation keyOperations = new PgpKeyOperation(this, this);
PGPSecretKeyRing masterKeyRing = keyOperations.createKey(Id.choice.algorithm.rsa,
4096, passphrase, null);
PGPSecretKey masterKey = keyOperations.createKey(Id.choice.algorithm.rsa,
4096, passphrase, true);
PGPSecretKeyRing subKeyRing = keyOperations.createKey(Id.choice.algorithm.rsa,
4096, passphrase, masterKeyRing.getSecretKey());
PGPSecretKey subKey = keyOperations.createKey(Id.choice.algorithm.rsa,
4096, passphrase, false);
// TODO: default to one master for cert, one sub for encrypt and one sub
// for sign
/* Output */
Bundle resultData = new Bundle();
resultData.putByteArray(RESULT_NEW_KEY,
PgpConversionHelper.PGPSecretKeyRingToBytes(masterKeyRing));
PgpConversionHelper.PGPSecretKeyToBytes(masterKey));
resultData.putByteArray(RESULT_NEW_KEY2,
PgpConversionHelper.PGPSecretKeyRingToBytes(subKeyRing));
PgpConversionHelper.PGPSecretKeyToBytes(subKey));
OtherHelper.logDebugBundle(resultData, "resultData");

View File

@ -193,25 +193,20 @@ public class EditKeyActivity extends SherlockFragmentActivity {
if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
// get new key from data bundle returned from service
Bundle data = message.getData();
PGPSecretKeyRing masterKeyRing = (PGPSecretKeyRing) PgpConversionHelper
.BytesToPGPKeyRing(data
PGPSecretKey masterKey = (PGPSecretKey) PgpConversionHelper
.BytesToPGPSecretKey(data
.getByteArray(KeychainIntentService.RESULT_NEW_KEY));
PGPSecretKeyRing subKeyRing = (PGPSecretKeyRing) PgpConversionHelper
.BytesToPGPKeyRing(data
PGPSecretKey subKey = (PGPSecretKey) PgpConversionHelper
.BytesToPGPSecretKey(data
.getByteArray(KeychainIntentService.RESULT_NEW_KEY2));
// add master key
@SuppressWarnings("unchecked")
Iterator<PGPSecretKey> masterIt = masterKeyRing.getSecretKeys();
mKeys.add(masterIt.next());
mKeysUsages.add(Id.choice.usage.sign_only);
mKeys.add(masterKey);
mKeysUsages.add(Id.choice.usage.sign_only); //TODO: get from key flags
// add sub key
@SuppressWarnings("unchecked")
Iterator<PGPSecretKey> subIt = subKeyRing.getSecretKeys();
subIt.next(); // masterkey
mKeys.add(subIt.next());
mKeysUsages.add(Id.choice.usage.encrypt_only);
mKeys.add(subKey);
mKeysUsages.add(Id.choice.usage.encrypt_only); //TODO: get from key flags
buildLayout();
}

View File

@ -290,18 +290,19 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor
// fill values for this action
Bundle data = new Bundle();
Boolean isMasterKey;
String passPhrase;
if (mEditors.getChildCount() > 0) {
PGPSecretKey masterKey = ((KeyEditor) mEditors.getChildAt(0)).getValue();
passPhrase = PassphraseCacheService
.getCachedPassphrase(mActivity, masterKey.getKeyID());
data.putByteArray(KeychainIntentService.GENERATE_KEY_MASTER_KEY,
PgpConversionHelper.PGPSecretKeyToBytes(masterKey));
isMasterKey = false;
} else {
passPhrase = "";
isMasterKey = true;
}
data.putBoolean(KeychainIntentService.GENERATE_KEY_MASTER_KEY, isMasterKey);
data.putString(KeychainIntentService.GENERATE_KEY_SYMMETRIC_PASSPHRASE, passPhrase);
data.putInt(KeychainIntentService.GENERATE_KEY_ALGORITHM, mNewKeyAlgorithmChoice.getId());
data.putInt(KeychainIntentService.GENERATE_KEY_KEY_SIZE, mNewKeySize);
@ -322,11 +323,10 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor
if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
// get new key from data bundle returned from service
Bundle data = message.getData();
PGPSecretKeyRing newKeyRing = (PGPSecretKeyRing) PgpConversionHelper
.BytesToPGPKeyRing(data
PGPSecretKey newKey = (PGPSecretKey) PgpConversionHelper
.BytesToPGPSecretKey(data
.getByteArray(KeychainIntentService.RESULT_NEW_KEY));
addGeneratedKeyToView(newKeyRing);
addGeneratedKeyToView(newKey);
}
};
};
@ -341,27 +341,12 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor
mActivity.startService(intent);
}
private void addGeneratedKeyToView(PGPSecretKeyRing newKeyRing) {
boolean isMasterKey = (mEditors.getChildCount() == 0);
// take only the key from this ring
PGPSecretKey newKey = null;
@SuppressWarnings("unchecked")
Iterator<PGPSecretKey> it = newKeyRing.getSecretKeys();
if (isMasterKey) {
newKey = it.next();
} else {
// first one is the master key
it.next();
newKey = it.next();
}
private void addGeneratedKeyToView(PGPSecretKey newKey) {
// add view with new key
KeyEditor view = (KeyEditor) mInflater.inflate(R.layout.edit_key_key_item,
mEditors, false);
view.setEditorListener(SectionView.this);
view.setValue(newKey, isMasterKey, -1);
view.setValue(newKey, newKey.isMasterKey(), -1);
mEditors.addView(view);
SectionView.this.updateEditorsVisible();
}

View File

@ -103,6 +103,15 @@ public class PGPObjectFactory
{
throw new IOException("can't create secret key object: " + e);
}
case PacketTags.SECRET_SUBKEY:
try
{
return PGPSecretKeyRing.readSubkey(in, fingerPrintCalculator);
}
catch (PGPException e)
{
throw new IOException("processing error: " + e.getMessage());
}
case PacketTags.PUBLIC_KEY:
return new PGPPublicKeyRing(in, fingerPrintCalculator);
case PacketTags.PUBLIC_SUBKEY:

View File

@ -64,7 +64,7 @@ public class PGPSecretKey
this(privKey, pubKey, checksumCalculator, false, keyEncryptor);
}
PGPSecretKey(
public PGPSecretKey(
PGPPrivateKey privKey,
PGPPublicKey pubKey,
PGPDigestCalculator checksumCalculator,

View File

@ -477,4 +477,23 @@ public class PGPSecretKeyRing
return new PGPSecretKeyRing(keys, secRing.extraPubKeys);
}
static PGPSecretKey readSubkey(BCPGInputStream in, KeyFingerPrintCalculator fingerPrintCalculator)
throws IOException, PGPException
{
SecretSubkeyPacket sub = (SecretSubkeyPacket)in.readPacket();
//
// ignore GPG comment packets if found.
//
while (in.nextPacketTag() == PacketTags.EXPERIMENTAL_2)
{
in.readPacket();
}
TrustPacket subTrust = readOptionalTrustPacket(in);
List sigList = readSignaturesAndTrust(in);
return new PGPSecretKey(sub, new PGPPublicKey(sub.getPublicKeyPacket(), subTrust, sigList, fingerPrintCalculator));
}
}