@Test public void testCertifyAttribute() throws Exception { KeyWritableRepository keyWritableRepository = KeyWritableRepository.create(RuntimeEnvironment.application); CertifyOperation op = new CertifyOperation(RuntimeEnvironment.application, keyWritableRepository, null, null); { CanonicalizedPublicKeyRing ring = keyWritableRepository.getCanonicalizedPublicKeyRing(mStaticRing2.getMasterKeyId()); Assert.assertNull("public key must not be marked verified prior to certification", ring.getVerified()); } CertifyActionsParcel.Builder actions = CertifyActionsParcel.builder(mStaticRing1.getMasterKeyId()); actions.addAction(CertifyAction.createForUserAttributes(mStaticRing2.getMasterKeyId(), mStaticRing2.getPublicKey().getUnorderedUserAttributes())); CertifyResult result = op.execute(actions.build(), CryptoInputParcel.createCryptoInputParcel(new Date(), mKeyPhrase1)); Assert.assertTrue("certification must succeed", result.success()); { CanonicalizedPublicKeyRing ring = keyWritableRepository.getCanonicalizedPublicKeyRing(mStaticRing2.getMasterKeyId()); Assert.assertEquals("new key must be verified now", VerificationStatus.VERIFIED_SECRET, ring.getVerified()); } }
@NonNull @Override public CertifyResult execute(CertifyActionsParcel parcel, CryptoInputParcel cryptoInput) { OperationLog log = new OperationLog(); log.add(LogType.MSG_CRT, 0); CanonicalizedSecretKey certificationKey; long masterKeyId = parcel.getMasterKeyId(); try { log.add(LogType.MSG_CRT_MASTER_FETCH, 1); Passphrase passphrase; switch (mKeyRepository.getSecretKeyType(masterKeyId)) { case PASSPHRASE: passphrase = cryptoInput.getPassphrase(); if (passphrase == null) { try { passphrase = getCachedPassphrase(masterKeyId, masterKeyId); } catch (PassphraseCacheInterface.NoSecretKeyException ignored) { } } if (passphrase == null) { return new CertifyResult(log, RequiredInputParcel.createRequiredSignPassphrase(masterKeyId, masterKeyId, null), cryptoInput ); } break; case PASSPHRASE_EMPTY: passphrase = new Passphrase(""); break; case DIVERT_TO_CARD: passphrase = null; break; default: log.add(LogType.MSG_CRT_ERROR_UNLOCK, 2); return new CertifyResult(CertifyResult.RESULT_ERROR, log); } CanonicalizedSecretKeyRing secretKeyRing = mKeyRepository.getCanonicalizedSecretKeyRing(parcel.getMasterKeyId()); certificationKey = secretKeyRing.getSecretKey(); log.add(LogType.MSG_CRT_UNLOCK, 1); boolean unlockSuccessful = certificationKey.unlock(passphrase); if (!unlockSuccessful) { log.add(LogType.MSG_CRT_ERROR_UNLOCK, 2); return new CertifyResult(CertifyResult.RESULT_ERROR, log); } } catch (PgpGeneralException e) { log.add(LogType.MSG_CRT_ERROR_UNLOCK, 2); return new CertifyResult(CertifyResult.RESULT_ERROR, log); } catch (NotFoundException e) { log.add(LogType.MSG_CRT_ERROR_MASTER_NOT_FOUND, 2); return new CertifyResult(CertifyResult.RESULT_ERROR, log); } ArrayList<UncachedKeyRing> certifiedKeys = new ArrayList<>(); log.add(LogType.MSG_CRT_CERTIFYING, 1); int certifyOk = 0, certifyError = 0, uploadOk = 0, uploadError = 0; SecurityTokenSignOperationsBuilder allRequiredInput = new SecurityTokenSignOperationsBuilder( cryptoInput.getSignatureTime(), masterKeyId, masterKeyId); for (CertifyAction action : parcel.getCertifyActions()) { if (checkCancelled()) { log.add(LogType.MSG_OPERATION_CANCELLED, 0); return new CertifyResult(CertifyResult.RESULT_CANCELLED, log); } try { if (action.getMasterKeyId() == parcel.getMasterKeyId()) { log.add(LogType.MSG_CRT_ERROR_SELF, 2); certifyError += 1; continue; } CanonicalizedPublicKeyRing publicRing = mKeyRepository.getCanonicalizedPublicKeyRing(action.getMasterKeyId()); PgpCertifyOperation op = new PgpCertifyOperation(); PgpCertifyResult result = op.certify(certificationKey, publicRing, log, 2, action, cryptoInput.getCryptoData(), cryptoInput.getSignatureTime()); if (!result.success()) { certifyError += 1; continue; } if (result.nfcInputRequired()) { RequiredInputParcel requiredInput = result.getRequiredInput(); allRequiredInput.addAll(requiredInput); continue; } certifiedKeys.add(result.getCertifiedRing()); } catch (NotFoundException e) { certifyError += 1; log.add(LogType.MSG_CRT_WARN_NOT_FOUND, 3); } } if (!allRequiredInput.isEmpty()) { log.add(LogType.MSG_CRT_NFC_RETURN, 1); return new CertifyResult(log, allRequiredInput.build(), cryptoInput); } log.add(LogType.MSG_CRT_SAVING, 1); if (checkCancelled()) { log.add(LogType.MSG_OPERATION_CANCELLED, 0); return new CertifyResult(CertifyResult.RESULT_CANCELLED, log); } UploadOperation uploadOperation = null; if (parcel.getParcelableKeyServer() != null) { uploadOperation = new UploadOperation(mContext, mKeyRepository, mProgressable, mCancelled); } for (UncachedKeyRing certifiedKey : certifiedKeys) { if (checkCancelled()) { log.add(LogType.MSG_OPERATION_CANCELLED, 0); return new CertifyResult(CertifyResult.RESULT_CANCELLED, log, certifyOk, certifyError, uploadOk, uploadError); } log.add(LogType.MSG_CRT_SAVE, 2, KeyFormattingUtils.convertKeyIdToHex(certifiedKey.getMasterKeyId())); mKeyRepository.clearLog(); SaveKeyringResult result = mKeyWritableRepository.savePublicKeyRing(certifiedKey); if (uploadOperation != null) { UploadKeyringParcel uploadInput = UploadKeyringParcel.createWithKeyId( parcel.getParcelableKeyServer(), certifiedKey.getMasterKeyId()); UploadResult uploadResult = uploadOperation.execute(uploadInput, cryptoInput); log.add(uploadResult, 2); if (uploadResult.success()) { keyMetadataDao.renewKeyLastUpdatedTime(certifiedKey.getMasterKeyId(), true); uploadOk += 1; } else { uploadError += 1; } } if (result.success()) { certifyOk += 1; } else { log.add(LogType.MSG_CRT_WARN_SAVE_FAILED, 3); } log.add(result, 2); } if (certifyOk == 0) { log.add(LogType.MSG_CRT_ERROR_NOTHING, 0); return new CertifyResult(CertifyResult.RESULT_ERROR, log, certifyOk, certifyError, uploadOk, uploadError); } log.add(LogType.MSG_CRT_SUCCESS, 0); if (uploadError != 0) { return new CertifyResult(CertifyResult.RESULT_WARNINGS, log, certifyOk, certifyError, uploadOk, uploadError); } else { return new CertifyResult(CertifyResult.RESULT_OK, log, certifyOk, certifyError, uploadOk, uploadError); } }
CertifyOperation extends BaseReadWriteOperation<CertifyActionsParcel> { @NonNull @Override public CertifyResult execute(CertifyActionsParcel parcel, CryptoInputParcel cryptoInput) { OperationLog log = new OperationLog(); log.add(LogType.MSG_CRT, 0); CanonicalizedSecretKey certificationKey; long masterKeyId = parcel.getMasterKeyId(); try { log.add(LogType.MSG_CRT_MASTER_FETCH, 1); Passphrase passphrase; switch (mKeyRepository.getSecretKeyType(masterKeyId)) { case PASSPHRASE: passphrase = cryptoInput.getPassphrase(); if (passphrase == null) { try { passphrase = getCachedPassphrase(masterKeyId, masterKeyId); } catch (PassphraseCacheInterface.NoSecretKeyException ignored) { } } if (passphrase == null) { return new CertifyResult(log, RequiredInputParcel.createRequiredSignPassphrase(masterKeyId, masterKeyId, null), cryptoInput ); } break; case PASSPHRASE_EMPTY: passphrase = new Passphrase(""); break; case DIVERT_TO_CARD: passphrase = null; break; default: log.add(LogType.MSG_CRT_ERROR_UNLOCK, 2); return new CertifyResult(CertifyResult.RESULT_ERROR, log); } CanonicalizedSecretKeyRing secretKeyRing = mKeyRepository.getCanonicalizedSecretKeyRing(parcel.getMasterKeyId()); certificationKey = secretKeyRing.getSecretKey(); log.add(LogType.MSG_CRT_UNLOCK, 1); boolean unlockSuccessful = certificationKey.unlock(passphrase); if (!unlockSuccessful) { log.add(LogType.MSG_CRT_ERROR_UNLOCK, 2); return new CertifyResult(CertifyResult.RESULT_ERROR, log); } } catch (PgpGeneralException e) { log.add(LogType.MSG_CRT_ERROR_UNLOCK, 2); return new CertifyResult(CertifyResult.RESULT_ERROR, log); } catch (NotFoundException e) { log.add(LogType.MSG_CRT_ERROR_MASTER_NOT_FOUND, 2); return new CertifyResult(CertifyResult.RESULT_ERROR, log); } ArrayList<UncachedKeyRing> certifiedKeys = new ArrayList<>(); log.add(LogType.MSG_CRT_CERTIFYING, 1); int certifyOk = 0, certifyError = 0, uploadOk = 0, uploadError = 0; SecurityTokenSignOperationsBuilder allRequiredInput = new SecurityTokenSignOperationsBuilder( cryptoInput.getSignatureTime(), masterKeyId, masterKeyId); for (CertifyAction action : parcel.getCertifyActions()) { if (checkCancelled()) { log.add(LogType.MSG_OPERATION_CANCELLED, 0); return new CertifyResult(CertifyResult.RESULT_CANCELLED, log); } try { if (action.getMasterKeyId() == parcel.getMasterKeyId()) { log.add(LogType.MSG_CRT_ERROR_SELF, 2); certifyError += 1; continue; } CanonicalizedPublicKeyRing publicRing = mKeyRepository.getCanonicalizedPublicKeyRing(action.getMasterKeyId()); PgpCertifyOperation op = new PgpCertifyOperation(); PgpCertifyResult result = op.certify(certificationKey, publicRing, log, 2, action, cryptoInput.getCryptoData(), cryptoInput.getSignatureTime()); if (!result.success()) { certifyError += 1; continue; } if (result.nfcInputRequired()) { RequiredInputParcel requiredInput = result.getRequiredInput(); allRequiredInput.addAll(requiredInput); continue; } certifiedKeys.add(result.getCertifiedRing()); } catch (NotFoundException e) { certifyError += 1; log.add(LogType.MSG_CRT_WARN_NOT_FOUND, 3); } } if (!allRequiredInput.isEmpty()) { log.add(LogType.MSG_CRT_NFC_RETURN, 1); return new CertifyResult(log, allRequiredInput.build(), cryptoInput); } log.add(LogType.MSG_CRT_SAVING, 1); if (checkCancelled()) { log.add(LogType.MSG_OPERATION_CANCELLED, 0); return new CertifyResult(CertifyResult.RESULT_CANCELLED, log); } UploadOperation uploadOperation = null; if (parcel.getParcelableKeyServer() != null) { uploadOperation = new UploadOperation(mContext, mKeyRepository, mProgressable, mCancelled); } for (UncachedKeyRing certifiedKey : certifiedKeys) { if (checkCancelled()) { log.add(LogType.MSG_OPERATION_CANCELLED, 0); return new CertifyResult(CertifyResult.RESULT_CANCELLED, log, certifyOk, certifyError, uploadOk, uploadError); } log.add(LogType.MSG_CRT_SAVE, 2, KeyFormattingUtils.convertKeyIdToHex(certifiedKey.getMasterKeyId())); mKeyRepository.clearLog(); SaveKeyringResult result = mKeyWritableRepository.savePublicKeyRing(certifiedKey); if (uploadOperation != null) { UploadKeyringParcel uploadInput = UploadKeyringParcel.createWithKeyId( parcel.getParcelableKeyServer(), certifiedKey.getMasterKeyId()); UploadResult uploadResult = uploadOperation.execute(uploadInput, cryptoInput); log.add(uploadResult, 2); if (uploadResult.success()) { keyMetadataDao.renewKeyLastUpdatedTime(certifiedKey.getMasterKeyId(), true); uploadOk += 1; } else { uploadError += 1; } } if (result.success()) { certifyOk += 1; } else { log.add(LogType.MSG_CRT_WARN_SAVE_FAILED, 3); } log.add(result, 2); } if (certifyOk == 0) { log.add(LogType.MSG_CRT_ERROR_NOTHING, 0); return new CertifyResult(CertifyResult.RESULT_ERROR, log, certifyOk, certifyError, uploadOk, uploadError); } log.add(LogType.MSG_CRT_SUCCESS, 0); if (uploadError != 0) { return new CertifyResult(CertifyResult.RESULT_WARNINGS, log, certifyOk, certifyError, uploadOk, uploadError); } else { return new CertifyResult(CertifyResult.RESULT_OK, log, certifyOk, certifyError, uploadOk, uploadError); } } }
CertifyOperation extends BaseReadWriteOperation<CertifyActionsParcel> { @NonNull @Override public CertifyResult execute(CertifyActionsParcel parcel, CryptoInputParcel cryptoInput) { OperationLog log = new OperationLog(); log.add(LogType.MSG_CRT, 0); CanonicalizedSecretKey certificationKey; long masterKeyId = parcel.getMasterKeyId(); try { log.add(LogType.MSG_CRT_MASTER_FETCH, 1); Passphrase passphrase; switch (mKeyRepository.getSecretKeyType(masterKeyId)) { case PASSPHRASE: passphrase = cryptoInput.getPassphrase(); if (passphrase == null) { try { passphrase = getCachedPassphrase(masterKeyId, masterKeyId); } catch (PassphraseCacheInterface.NoSecretKeyException ignored) { } } if (passphrase == null) { return new CertifyResult(log, RequiredInputParcel.createRequiredSignPassphrase(masterKeyId, masterKeyId, null), cryptoInput ); } break; case PASSPHRASE_EMPTY: passphrase = new Passphrase(""); break; case DIVERT_TO_CARD: passphrase = null; break; default: log.add(LogType.MSG_CRT_ERROR_UNLOCK, 2); return new CertifyResult(CertifyResult.RESULT_ERROR, log); } CanonicalizedSecretKeyRing secretKeyRing = mKeyRepository.getCanonicalizedSecretKeyRing(parcel.getMasterKeyId()); certificationKey = secretKeyRing.getSecretKey(); log.add(LogType.MSG_CRT_UNLOCK, 1); boolean unlockSuccessful = certificationKey.unlock(passphrase); if (!unlockSuccessful) { log.add(LogType.MSG_CRT_ERROR_UNLOCK, 2); return new CertifyResult(CertifyResult.RESULT_ERROR, log); } } catch (PgpGeneralException e) { log.add(LogType.MSG_CRT_ERROR_UNLOCK, 2); return new CertifyResult(CertifyResult.RESULT_ERROR, log); } catch (NotFoundException e) { log.add(LogType.MSG_CRT_ERROR_MASTER_NOT_FOUND, 2); return new CertifyResult(CertifyResult.RESULT_ERROR, log); } ArrayList<UncachedKeyRing> certifiedKeys = new ArrayList<>(); log.add(LogType.MSG_CRT_CERTIFYING, 1); int certifyOk = 0, certifyError = 0, uploadOk = 0, uploadError = 0; SecurityTokenSignOperationsBuilder allRequiredInput = new SecurityTokenSignOperationsBuilder( cryptoInput.getSignatureTime(), masterKeyId, masterKeyId); for (CertifyAction action : parcel.getCertifyActions()) { if (checkCancelled()) { log.add(LogType.MSG_OPERATION_CANCELLED, 0); return new CertifyResult(CertifyResult.RESULT_CANCELLED, log); } try { if (action.getMasterKeyId() == parcel.getMasterKeyId()) { log.add(LogType.MSG_CRT_ERROR_SELF, 2); certifyError += 1; continue; } CanonicalizedPublicKeyRing publicRing = mKeyRepository.getCanonicalizedPublicKeyRing(action.getMasterKeyId()); PgpCertifyOperation op = new PgpCertifyOperation(); PgpCertifyResult result = op.certify(certificationKey, publicRing, log, 2, action, cryptoInput.getCryptoData(), cryptoInput.getSignatureTime()); if (!result.success()) { certifyError += 1; continue; } if (result.nfcInputRequired()) { RequiredInputParcel requiredInput = result.getRequiredInput(); allRequiredInput.addAll(requiredInput); continue; } certifiedKeys.add(result.getCertifiedRing()); } catch (NotFoundException e) { certifyError += 1; log.add(LogType.MSG_CRT_WARN_NOT_FOUND, 3); } } if (!allRequiredInput.isEmpty()) { log.add(LogType.MSG_CRT_NFC_RETURN, 1); return new CertifyResult(log, allRequiredInput.build(), cryptoInput); } log.add(LogType.MSG_CRT_SAVING, 1); if (checkCancelled()) { log.add(LogType.MSG_OPERATION_CANCELLED, 0); return new CertifyResult(CertifyResult.RESULT_CANCELLED, log); } UploadOperation uploadOperation = null; if (parcel.getParcelableKeyServer() != null) { uploadOperation = new UploadOperation(mContext, mKeyRepository, mProgressable, mCancelled); } for (UncachedKeyRing certifiedKey : certifiedKeys) { if (checkCancelled()) { log.add(LogType.MSG_OPERATION_CANCELLED, 0); return new CertifyResult(CertifyResult.RESULT_CANCELLED, log, certifyOk, certifyError, uploadOk, uploadError); } log.add(LogType.MSG_CRT_SAVE, 2, KeyFormattingUtils.convertKeyIdToHex(certifiedKey.getMasterKeyId())); mKeyRepository.clearLog(); SaveKeyringResult result = mKeyWritableRepository.savePublicKeyRing(certifiedKey); if (uploadOperation != null) { UploadKeyringParcel uploadInput = UploadKeyringParcel.createWithKeyId( parcel.getParcelableKeyServer(), certifiedKey.getMasterKeyId()); UploadResult uploadResult = uploadOperation.execute(uploadInput, cryptoInput); log.add(uploadResult, 2); if (uploadResult.success()) { keyMetadataDao.renewKeyLastUpdatedTime(certifiedKey.getMasterKeyId(), true); uploadOk += 1; } else { uploadError += 1; } } if (result.success()) { certifyOk += 1; } else { log.add(LogType.MSG_CRT_WARN_SAVE_FAILED, 3); } log.add(result, 2); } if (certifyOk == 0) { log.add(LogType.MSG_CRT_ERROR_NOTHING, 0); return new CertifyResult(CertifyResult.RESULT_ERROR, log, certifyOk, certifyError, uploadOk, uploadError); } log.add(LogType.MSG_CRT_SUCCESS, 0); if (uploadError != 0) { return new CertifyResult(CertifyResult.RESULT_WARNINGS, log, certifyOk, certifyError, uploadOk, uploadError); } else { return new CertifyResult(CertifyResult.RESULT_OK, log, certifyOk, certifyError, uploadOk, uploadError); } } CertifyOperation(Context context, KeyWritableRepository keyWritableRepository, Progressable progressable,
            AtomicBoolean cancelled); }
CertifyOperation extends BaseReadWriteOperation<CertifyActionsParcel> { @NonNull @Override public CertifyResult execute(CertifyActionsParcel parcel, CryptoInputParcel cryptoInput) { OperationLog log = new OperationLog(); log.add(LogType.MSG_CRT, 0); CanonicalizedSecretKey certificationKey; long masterKeyId = parcel.getMasterKeyId(); try { log.add(LogType.MSG_CRT_MASTER_FETCH, 1); Passphrase passphrase; switch (mKeyRepository.getSecretKeyType(masterKeyId)) { case PASSPHRASE: passphrase = cryptoInput.getPassphrase(); if (passphrase == null) { try { passphrase = getCachedPassphrase(masterKeyId, masterKeyId); } catch (PassphraseCacheInterface.NoSecretKeyException ignored) { } } if (passphrase == null) { return new CertifyResult(log, RequiredInputParcel.createRequiredSignPassphrase(masterKeyId, masterKeyId, null), cryptoInput ); } break; case PASSPHRASE_EMPTY: passphrase = new Passphrase(""); break; case DIVERT_TO_CARD: passphrase = null; break; default: log.add(LogType.MSG_CRT_ERROR_UNLOCK, 2); return new CertifyResult(CertifyResult.RESULT_ERROR, log); } CanonicalizedSecretKeyRing secretKeyRing = mKeyRepository.getCanonicalizedSecretKeyRing(parcel.getMasterKeyId()); certificationKey = secretKeyRing.getSecretKey(); log.add(LogType.MSG_CRT_UNLOCK, 1); boolean unlockSuccessful = certificationKey.unlock(passphrase); if (!unlockSuccessful) { log.add(LogType.MSG_CRT_ERROR_UNLOCK, 2); return new CertifyResult(CertifyResult.RESULT_ERROR, log); } } catch (PgpGeneralException e) { log.add(LogType.MSG_CRT_ERROR_UNLOCK, 2); return new CertifyResult(CertifyResult.RESULT_ERROR, log); } catch (NotFoundException e) { log.add(LogType.MSG_CRT_ERROR_MASTER_NOT_FOUND, 2); return new CertifyResult(CertifyResult.RESULT_ERROR, log); } ArrayList<UncachedKeyRing> certifiedKeys = new ArrayList<>(); log.add(LogType.MSG_CRT_CERTIFYING, 1); int certifyOk = 0, certifyError = 0, uploadOk = 0, uploadError = 0; SecurityTokenSignOperationsBuilder allRequiredInput = new SecurityTokenSignOperationsBuilder( cryptoInput.getSignatureTime(), masterKeyId, masterKeyId); for (CertifyAction action : parcel.getCertifyActions()) { if (checkCancelled()) { log.add(LogType.MSG_OPERATION_CANCELLED, 0); return new CertifyResult(CertifyResult.RESULT_CANCELLED, log); } try { if (action.getMasterKeyId() == parcel.getMasterKeyId()) { log.add(LogType.MSG_CRT_ERROR_SELF, 2); certifyError += 1; continue; } CanonicalizedPublicKeyRing publicRing = mKeyRepository.getCanonicalizedPublicKeyRing(action.getMasterKeyId()); PgpCertifyOperation op = new PgpCertifyOperation(); PgpCertifyResult result = op.certify(certificationKey, publicRing, log, 2, action, cryptoInput.getCryptoData(), cryptoInput.getSignatureTime()); if (!result.success()) { certifyError += 1; continue; } if (result.nfcInputRequired()) { RequiredInputParcel requiredInput = result.getRequiredInput(); allRequiredInput.addAll(requiredInput); continue; } certifiedKeys.add(result.getCertifiedRing()); } catch (NotFoundException e) { certifyError += 1; log.add(LogType.MSG_CRT_WARN_NOT_FOUND, 3); } } if (!allRequiredInput.isEmpty()) { log.add(LogType.MSG_CRT_NFC_RETURN, 1); return new CertifyResult(log, allRequiredInput.build(), cryptoInput); } log.add(LogType.MSG_CRT_SAVING, 1); if (checkCancelled()) { log.add(LogType.MSG_OPERATION_CANCELLED, 0); return new CertifyResult(CertifyResult.RESULT_CANCELLED, log); } UploadOperation uploadOperation = null; if (parcel.getParcelableKeyServer() != null) { uploadOperation = new UploadOperation(mContext, mKeyRepository, mProgressable, mCancelled); } for (UncachedKeyRing certifiedKey : certifiedKeys) { if (checkCancelled()) { log.add(LogType.MSG_OPERATION_CANCELLED, 0); return new CertifyResult(CertifyResult.RESULT_CANCELLED, log, certifyOk, certifyError, uploadOk, uploadError); } log.add(LogType.MSG_CRT_SAVE, 2, KeyFormattingUtils.convertKeyIdToHex(certifiedKey.getMasterKeyId())); mKeyRepository.clearLog(); SaveKeyringResult result = mKeyWritableRepository.savePublicKeyRing(certifiedKey); if (uploadOperation != null) { UploadKeyringParcel uploadInput = UploadKeyringParcel.createWithKeyId( parcel.getParcelableKeyServer(), certifiedKey.getMasterKeyId()); UploadResult uploadResult = uploadOperation.execute(uploadInput, cryptoInput); log.add(uploadResult, 2); if (uploadResult.success()) { keyMetadataDao.renewKeyLastUpdatedTime(certifiedKey.getMasterKeyId(), true); uploadOk += 1; } else { uploadError += 1; } } if (result.success()) { certifyOk += 1; } else { log.add(LogType.MSG_CRT_WARN_SAVE_FAILED, 3); } log.add(result, 2); } if (certifyOk == 0) { log.add(LogType.MSG_CRT_ERROR_NOTHING, 0); return new CertifyResult(CertifyResult.RESULT_ERROR, log, certifyOk, certifyError, uploadOk, uploadError); } log.add(LogType.MSG_CRT_SUCCESS, 0); if (uploadError != 0) { return new CertifyResult(CertifyResult.RESULT_WARNINGS, log, certifyOk, certifyError, uploadOk, uploadError); } else { return new CertifyResult(CertifyResult.RESULT_OK, log, certifyOk, certifyError, uploadOk, uploadError); } } CertifyOperation(Context context, KeyWritableRepository keyWritableRepository, Progressable progressable,
            AtomicBoolean cancelled); @NonNull @Override CertifyResult execute(CertifyActionsParcel parcel, CryptoInputParcel cryptoInput); }
CertifyOperation extends BaseReadWriteOperation<CertifyActionsParcel> { @NonNull @Override public CertifyResult execute(CertifyActionsParcel parcel, CryptoInputParcel cryptoInput) { OperationLog log = new OperationLog(); log.add(LogType.MSG_CRT, 0); CanonicalizedSecretKey certificationKey; long masterKeyId = parcel.getMasterKeyId(); try { log.add(LogType.MSG_CRT_MASTER_FETCH, 1); Passphrase passphrase; switch (mKeyRepository.getSecretKeyType(masterKeyId)) { case PASSPHRASE: passphrase = cryptoInput.getPassphrase(); if (passphrase == null) { try { passphrase = getCachedPassphrase(masterKeyId, masterKeyId); } catch (PassphraseCacheInterface.NoSecretKeyException ignored) { } } if (passphrase == null) { return new CertifyResult(log, RequiredInputParcel.createRequiredSignPassphrase(masterKeyId, masterKeyId, null), cryptoInput ); } break; case PASSPHRASE_EMPTY: passphrase = new Passphrase(""); break; case DIVERT_TO_CARD: passphrase = null; break; default: log.add(LogType.MSG_CRT_ERROR_UNLOCK, 2); return new CertifyResult(CertifyResult.RESULT_ERROR, log); } CanonicalizedSecretKeyRing secretKeyRing = mKeyRepository.getCanonicalizedSecretKeyRing(parcel.getMasterKeyId()); certificationKey = secretKeyRing.getSecretKey(); log.add(LogType.MSG_CRT_UNLOCK, 1); boolean unlockSuccessful = certificationKey.unlock(passphrase); if (!unlockSuccessful) { log.add(LogType.MSG_CRT_ERROR_UNLOCK, 2); return new CertifyResult(CertifyResult.RESULT_ERROR, log); } } catch (PgpGeneralException e) { log.add(LogType.MSG_CRT_ERROR_UNLOCK, 2); return new CertifyResult(CertifyResult.RESULT_ERROR, log); } catch (NotFoundException e) { log.add(LogType.MSG_CRT_ERROR_MASTER_NOT_FOUND, 2); return new CertifyResult(CertifyResult.RESULT_ERROR, log); } ArrayList<UncachedKeyRing> certifiedKeys = new ArrayList<>(); log.add(LogType.MSG_CRT_CERTIFYING, 1); int certifyOk = 0, certifyError = 0, uploadOk = 0, uploadError = 0; SecurityTokenSignOperationsBuilder allRequiredInput = new SecurityTokenSignOperationsBuilder( cryptoInput.getSignatureTime(), masterKeyId, masterKeyId); for (CertifyAction action : parcel.getCertifyActions()) { if (checkCancelled()) { log.add(LogType.MSG_OPERATION_CANCELLED, 0); return new CertifyResult(CertifyResult.RESULT_CANCELLED, log); } try { if (action.getMasterKeyId() == parcel.getMasterKeyId()) { log.add(LogType.MSG_CRT_ERROR_SELF, 2); certifyError += 1; continue; } CanonicalizedPublicKeyRing publicRing = mKeyRepository.getCanonicalizedPublicKeyRing(action.getMasterKeyId()); PgpCertifyOperation op = new PgpCertifyOperation(); PgpCertifyResult result = op.certify(certificationKey, publicRing, log, 2, action, cryptoInput.getCryptoData(), cryptoInput.getSignatureTime()); if (!result.success()) { certifyError += 1; continue; } if (result.nfcInputRequired()) { RequiredInputParcel requiredInput = result.getRequiredInput(); allRequiredInput.addAll(requiredInput); continue; } certifiedKeys.add(result.getCertifiedRing()); } catch (NotFoundException e) { certifyError += 1; log.add(LogType.MSG_CRT_WARN_NOT_FOUND, 3); } } if (!allRequiredInput.isEmpty()) { log.add(LogType.MSG_CRT_NFC_RETURN, 1); return new CertifyResult(log, allRequiredInput.build(), cryptoInput); } log.add(LogType.MSG_CRT_SAVING, 1); if (checkCancelled()) { log.add(LogType.MSG_OPERATION_CANCELLED, 0); return new CertifyResult(CertifyResult.RESULT_CANCELLED, log); } UploadOperation uploadOperation = null; if (parcel.getParcelableKeyServer() != null) { uploadOperation = new UploadOperation(mContext, mKeyRepository, mProgressable, mCancelled); } for (UncachedKeyRing certifiedKey : certifiedKeys) { if (checkCancelled()) { log.add(LogType.MSG_OPERATION_CANCELLED, 0); return new CertifyResult(CertifyResult.RESULT_CANCELLED, log, certifyOk, certifyError, uploadOk, uploadError); } log.add(LogType.MSG_CRT_SAVE, 2, KeyFormattingUtils.convertKeyIdToHex(certifiedKey.getMasterKeyId())); mKeyRepository.clearLog(); SaveKeyringResult result = mKeyWritableRepository.savePublicKeyRing(certifiedKey); if (uploadOperation != null) { UploadKeyringParcel uploadInput = UploadKeyringParcel.createWithKeyId( parcel.getParcelableKeyServer(), certifiedKey.getMasterKeyId()); UploadResult uploadResult = uploadOperation.execute(uploadInput, cryptoInput); log.add(uploadResult, 2); if (uploadResult.success()) { keyMetadataDao.renewKeyLastUpdatedTime(certifiedKey.getMasterKeyId(), true); uploadOk += 1; } else { uploadError += 1; } } if (result.success()) { certifyOk += 1; } else { log.add(LogType.MSG_CRT_WARN_SAVE_FAILED, 3); } log.add(result, 2); } if (certifyOk == 0) { log.add(LogType.MSG_CRT_ERROR_NOTHING, 0); return new CertifyResult(CertifyResult.RESULT_ERROR, log, certifyOk, certifyError, uploadOk, uploadError); } log.add(LogType.MSG_CRT_SUCCESS, 0); if (uploadError != 0) { return new CertifyResult(CertifyResult.RESULT_WARNINGS, log, certifyOk, certifyError, uploadOk, uploadError); } else { return new CertifyResult(CertifyResult.RESULT_OK, log, certifyOk, certifyError, uploadOk, uploadError); } } CertifyOperation(Context context, KeyWritableRepository keyWritableRepository, Progressable progressable,
            AtomicBoolean cancelled); @NonNull @Override CertifyResult execute(CertifyActionsParcel parcel, CryptoInputParcel cryptoInput);  }