/** * Checks if key has a passphrase * * @param secretKeyId * @return true if it has a passphrase */ private static boolean hasPassphrase(Context context, long secretKeyId) { // check if the key has no passphrase try { PGPSecretKey secretKey = PGPHelper.getMasterKey(ProviderHelper.getPGPSecretKeyRingByKeyId(context, secretKeyId)); // PGPSecretKey secretKey = // PGPHelper.getMasterKey(PGPMain.getSecretKeyRing(secretKeyId)); Log.d(Constants.TAG, "Check if key has no passphrase..."); PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider("SC").build("".toCharArray()); PGPPrivateKey testKey = secretKey.extractPrivateKey(keyDecryptor); if (testKey != null) { Log.d(Constants.TAG, "Key has no passphrase! Caches empty passphrase!"); // cache empty passphrase PassphraseCacheService.addCachedPassphrase(context, secretKey.getKeyID(), ""); return false; } } catch (PGPException e) { // silently catch } return true; }
@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; }
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(), true); }
/** * Replace the passed the public key on the passed in secret key. * * @param secretKey secret key to change * @param publicKey new public key. * @return a new secret key. * @throws IllegalArgumentException if keyIDs do not match. */ public static PGPSecretKey replacePublicKey(PGPSecretKey secretKey, PGPPublicKey publicKey) { if (publicKey.getKeyID() != secretKey.getKeyID()) { throw new IllegalArgumentException("keyIDs do not match"); } return new PGPSecretKey(secretKey.secret, publicKey); }
@SuppressWarnings("unchecked") public static String getMainUserId(PGPSecretKey key) { for (String userId : new IterableIterator<String>(key.getUserIDs())) { return userId; } return null; }
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; }
/** * If an Intent gives a signatureMasterKeyId and/or encryptionMasterKeyIds, preselect those! * * @param preselectedSignatureKeyId * @param preselectedEncryptionKeyIds */ private void preselectKeys( long preselectedSignatureKeyId, long[] preselectedEncryptionKeyIds, ProviderHelper providerHelper) { if (preselectedSignatureKeyId != 0) { // TODO: don't use bouncy castle objects! try { PGPSecretKeyRing keyRing = providerHelper.getPGPSecretKeyRingWithKeyId(preselectedSignatureKeyId); PGPSecretKey masterKey = keyRing.getSecretKey(); if (masterKey != null) { PGPSecretKey signKey = PgpKeyHelper.getFirstSigningSubkey(keyRing); if (signKey != null) { setSignatureKeyId(masterKey.getKeyID()); } } } catch (ProviderHelper.NotFoundException e) { Log.e(Constants.TAG, "key not found!", e); } } if (preselectedEncryptionKeyIds != null) { Vector<Long> goodIds = new Vector<Long>(); for (int i = 0; i < preselectedEncryptionKeyIds.length; ++i) { // TODO One query per selected key?! wtf try { long id = providerHelper.getMasterKeyId( KeyRings.buildUnifiedKeyRingsFindBySubkeyUri( Long.toString(preselectedEncryptionKeyIds[i]))); goodIds.add(id); } catch (ProviderHelper.NotFoundException e) { Log.e(Constants.TAG, "key not found!", e); } } if (goodIds.size() > 0) { long[] keyIds = new long[goodIds.size()]; for (int i = 0; i < goodIds.size(); ++i) { keyIds[i] = goodIds.get(i); } setEncryptionKeyIds(keyIds); } } }
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(); } if (enc == null) { throw new PgpGeneralException(context.getString(R.string.error_invalid_data)); } // 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 (!gotAsymmetricEncryption) { throw new NoAsymmetricEncryptionException(); } if (secretKey == null) { return Id.key.none; } return secretKey.getKeyID(); }
public static boolean isSigningKey(PGPSecretKey key) { return isSigningKey(key.getPublicKey()); }
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.edit_key); mActionBar = getSupportActionBar(); mActionBar.setDisplayShowTitleEnabled(true); // set actionbar without home button if called from another app if (getCallingPackage() != null && getCallingPackage().equals(Constants.PACKAGE_NAME)) { mActionBar.setDisplayHomeAsUpEnabled(true); mActionBar.setHomeButtonEnabled(true); } else { mActionBar.setDisplayHomeAsUpEnabled(false); mActionBar.setHomeButtonEnabled(false); } // find views mChangePassPhrase = (Button) findViewById(R.id.edit_key_btn_change_pass_phrase); mNoPassphrase = (CheckBox) findViewById(R.id.edit_key_no_passphrase); mUserIds = new Vector<String>(); mKeys = new Vector<PGPSecretKey>(); mKeysUsages = new Vector<Integer>(); // Catch Intents opened from other apps mIntent = getIntent(); // Handle intents Bundle extras = mIntent.getExtras(); if (ACTION_CREATE_KEY.equals(mIntent.getAction())) { mActionBar.setTitle(R.string.title_createKey); mCurrentPassPhrase = ""; if (extras != null) { // if userId is given, prefill the fields if (extras.containsKey(EXTRA_USER_IDS)) { Log.d(Constants.TAG, "UserIds are given!"); mUserIds.add(extras.getString(EXTRA_USER_IDS)); } // if no passphrase is given if (extras.containsKey(EXTRA_NO_PASSPHRASE)) { boolean noPassphrase = extras.getBoolean(EXTRA_NO_PASSPHRASE); if (noPassphrase) { // check "no passphrase" checkbox and remove button mNoPassphrase.setChecked(true); mChangePassPhrase.setVisibility(View.GONE); } } // generate key if (extras.containsKey(EXTRA_GENERATE_DEFAULT_KEYS)) { boolean generateDefaultKeys = extras.getBoolean(EXTRA_GENERATE_DEFAULT_KEYS); if (generateDefaultKeys) { // build layout in handler after generating keys not directly in onCreate mBuildLayout = false; // Send all information needed to service generate keys in other thread Intent intent = new Intent(this, ApgService.class); intent.putExtra(ApgService.EXTRA_ACTION, ApgService.ACTION_GENERATE_DEFAULT_RSA_KEYS); // fill values for this action Bundle data = new Bundle(); data.putString(ApgService.SYMMETRIC_PASSPHRASE, mCurrentPassPhrase); intent.putExtra(ApgService.EXTRA_DATA, data); // show progress dialog mGeneratingDialog = ProgressDialogFragment.newInstance( R.string.progress_generating, ProgressDialog.STYLE_SPINNER); // Message is received after generating is done in ApgService ApgHandler saveHandler = new ApgHandler(this, mGeneratingDialog) { public void handleMessage(Message message) { // handle messages by standard ApgHandler first super.handleMessage(message); if (message.arg1 == ApgHandler.MESSAGE_OKAY) { // get new key from data bundle returned from service Bundle data = message.getData(); PGPSecretKeyRing masterKeyRing = PGPConversionHelper.BytesToPGPSecretKeyRing( data.getByteArray(ApgService.RESULT_NEW_KEY)); PGPSecretKeyRing subKeyRing = PGPConversionHelper.BytesToPGPSecretKeyRing( data.getByteArray(ApgService.RESULT_NEW_KEY2)); // add master key Iterator<PGPSecretKey> masterIt = masterKeyRing.getSecretKeys(); mKeys.add(masterIt.next()); mKeysUsages.add(Id.choice.usage.sign_only); // add sub key Iterator<PGPSecretKey> subIt = subKeyRing.getSecretKeys(); subIt.next(); // masterkey mKeys.add(subIt.next()); mKeysUsages.add(Id.choice.usage.encrypt_only); buildLayout(); } }; }; // Create a new Messenger for the communication back Messenger messenger = new Messenger(saveHandler); intent.putExtra(ApgService.EXTRA_MESSENGER, messenger); mGeneratingDialog.show(getSupportFragmentManager(), "dialog"); // start service with intent startService(intent); } } } } else if (ACTION_EDIT_KEY.equals(mIntent.getAction())) { mActionBar.setTitle(R.string.title_editKey); mCurrentPassPhrase = PGPMain.getEditPassPhrase(); if (mCurrentPassPhrase == null) { mCurrentPassPhrase = ""; } if (mCurrentPassPhrase.equals("")) { // check "no passphrase" checkbox and remove button mNoPassphrase.setChecked(true); mChangePassPhrase.setVisibility(View.GONE); } if (extras != null) { if (extras.containsKey(EXTRA_KEY_ID)) { long keyId = mIntent.getExtras().getLong(EXTRA_KEY_ID); if (keyId != 0) { PGPSecretKey masterKey = null; mKeyRing = PGPMain.getSecretKeyRing(keyId); 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 } } if (masterKey != null) { for (String userId : new IterableIterator<String>(masterKey.getUserIDs())) { mUserIds.add(userId); } } } } } } mChangePassPhrase.setOnClickListener( new OnClickListener() { public void onClick(View v) { showDialog(Id.dialog.new_pass_phrase); } }); // disable passphrase when no passphrase checkobox is checked! mNoPassphrase.setOnCheckedChangeListener( new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if (isChecked) { // remove passphrase mNewPassPhrase = null; mChangePassPhrase.setVisibility(View.GONE); } else { mChangePassPhrase.setVisibility(View.VISIBLE); } } }); if (mBuildLayout) { buildLayout(); } }
public static boolean isSecretKeyPrivateEmpty(PGPSecretKey secretKey) { return secretKey.isPrivateKeyEmpty(); }
public static Date getCreationDate(PGPSecretKey key) { return key.getPublicKey().getCreationTime(); }
public static Date getExpiryDate(PGPSecretKey key) { return getExpiryDate(key.getPublicKey()); }
public static String getAlgorithmInfo(PGPSecretKey key) { return getAlgorithmInfo(key.getPublicKey()); }
public static boolean isCertificationKey(PGPSecretKey key) { return isCertificationKey(key.getPublicKey()); }
/** * Return a copy of the passed in secret key, encrypted using a new password and the passed in * algorithm. * * @param key the PGPSecretKey to be copied. * @param oldKeyDecryptor the current decryptor based on the current password for key. * @param newKeyEncryptor a new encryptor based on a new password for encrypting the secret key * material. */ public static PGPSecretKey copyWithNewPassword( PGPSecretKey key, PBESecretKeyDecryptor oldKeyDecryptor, PBESecretKeyEncryptor newKeyEncryptor) throws PGPException { if (key.isPrivateKeyEmpty()) { throw new PGPException("no private key in this SecretKey - public key present only."); } byte[] rawKeyData = key.extractKeyData(oldKeyDecryptor); int s2kUsage = key.secret.getS2KUsage(); byte[] iv = null; S2K s2k = null; byte[] keyData; int newEncAlgorithm = SymmetricKeyAlgorithmTags.NULL; if (newKeyEncryptor == null || newKeyEncryptor.getAlgorithm() == SymmetricKeyAlgorithmTags.NULL) { s2kUsage = SecretKeyPacket.USAGE_NONE; if (key.secret.getS2KUsage() == SecretKeyPacket.USAGE_SHA1) // SHA-1 hash, need to rewrite checksum { keyData = new byte[rawKeyData.length - 18]; System.arraycopy(rawKeyData, 0, keyData, 0, keyData.length - 2); byte[] check = checksum(null, keyData, keyData.length - 2); keyData[keyData.length - 2] = check[0]; keyData[keyData.length - 1] = check[1]; } else { keyData = rawKeyData; } } else { if (key.secret.getPublicKeyPacket().getVersion() < 4) { // Version 2 or 3 - RSA Keys only byte[] encKey = newKeyEncryptor.getKey(); keyData = new byte[rawKeyData.length]; if (newKeyEncryptor.getS2K() != null) { throw new PGPException("MD5 Digest Calculator required for version 3 key encryptor."); } // // process 4 numbers // int pos = 0; for (int i = 0; i != 4; i++) { int encLen = (((rawKeyData[pos] << 8) | (rawKeyData[pos + 1] & 0xff)) + 7) / 8; keyData[pos] = rawKeyData[pos]; keyData[pos + 1] = rawKeyData[pos + 1]; byte[] tmp; if (i == 0) { tmp = newKeyEncryptor.encryptKeyData(encKey, rawKeyData, pos + 2, encLen); iv = newKeyEncryptor.getCipherIV(); } else { byte[] tmpIv = new byte[iv.length]; System.arraycopy(keyData, pos - iv.length, tmpIv, 0, tmpIv.length); tmp = newKeyEncryptor.encryptKeyData(encKey, tmpIv, rawKeyData, pos + 2, encLen); } System.arraycopy(tmp, 0, keyData, pos + 2, tmp.length); pos += 2 + encLen; } // // copy in checksum. // keyData[pos] = rawKeyData[pos]; keyData[pos + 1] = rawKeyData[pos + 1]; s2k = newKeyEncryptor.getS2K(); newEncAlgorithm = newKeyEncryptor.getAlgorithm(); } else { keyData = newKeyEncryptor.encryptKeyData(rawKeyData, 0, rawKeyData.length); iv = newKeyEncryptor.getCipherIV(); s2k = newKeyEncryptor.getS2K(); newEncAlgorithm = newKeyEncryptor.getAlgorithm(); } } SecretKeyPacket secret; if (key.secret instanceof SecretSubkeyPacket) { secret = new SecretSubkeyPacket( key.secret.getPublicKeyPacket(), newEncAlgorithm, s2kUsage, s2k, iv, keyData); } else { secret = new SecretKeyPacket( key.secret.getPublicKeyPacket(), newEncAlgorithm, s2kUsage, s2k, iv, keyData); } return new PGPSecretKey(secret, key.pub); }
public static boolean isEncryptionKey(PGPSecretKey key) { return isEncryptionKey(key.getPublicKey()); }