Program: 8311
Project: 8311
Buggy source:
/** 
 * This method introduces a list of modifications specified by a SaveKeyringParcel to a WrappedSecretKeyRing. This method relies on WrappedSecretKeyRing's canonicalization property! Note that PGPPublicKeyRings can not be directly modified. Instead, the corresponding PGPSecretKeyRing must be modified and consequently consolidated with its public counterpart. This is a natural workflow since pgp keyrings are immutable data structures: Old semantics are changed by adding new certificates, which implicitly override older certificates. Note that this method does not care about any "special" type of master key. If unlocking with a passphrase fails, the operation will fail with an unlocking error. More specific handling of errors should be done in UI code! If the passphrase is null, only a restricted subset of operations will be available, namely stripping of subkeys and changing the protection mode of dummy keys.
 */
public PgpEditKeyResult modifySecretKeyRing(CanonicalizedSecretKeyRing wsKR,CryptoInputParcel cryptoInput,SaveKeyringParcel saveParcel){
  OperationLog log=new OperationLog();
  int indent=0;
  log.add(LogType.MSG_MF,indent,KeyFormattingUtils.convertKeyIdToHex(wsKR.getMasterKeyId()));
  indent+=1;
  progress(R.string.progress_building_key,0);
  if (saveParcel.mMasterKeyId == null || saveParcel.mMasterKeyId != wsKR.getMasterKeyId()) {
    log.add(LogType.MSG_MF_ERROR_KEYID,indent);
    return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR,log,null);
  }
  PGPSecretKeyRing sKR=wsKR.getRing();
  PGPSecretKey masterSecretKey=sKR.getSecretKey();
  if (saveParcel.mFingerprint == null || !Arrays.equals(saveParcel.mFingerprint,masterSecretKey.getPublicKey().getFingerprint())) {
    log.add(LogType.MSG_MF_ERROR_FINGERPRINT,indent);
    return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR,log,null);
  }
  if (saveParcel.isEmpty()) {
    log.add(LogType.MSG_MF_ERROR_NOOP,indent);
    return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR,log,null);
  }
  if (isDummy(masterSecretKey) || saveParcel.isRestrictedOnly()) {
    log.add(LogType.MSG_MF_RESTRICTED_MODE,indent);
    return internalRestricted(sKR,saveParcel,log);
  }
  if (!isDivertToCard(masterSecretKey) && !cryptoInput.hasPassphrase()) {
    log.add(LogType.MSG_MF_REQUIRE_PASSPHRASE,indent);
    return new PgpEditKeyResult(log,RequiredInputParcel.createRequiredSignPassphrase(masterSecretKey.getKeyID(),masterSecretKey.getKeyID(),cryptoInput.getSignatureTime()));
  }
  PGPPublicKey masterPublicKey=masterSecretKey.getPublicKey();
  int masterKeyFlags=readKeyFlags(masterPublicKey) | KeyFlags.CERTIFY_OTHER;
  Date expiryTime=wsKR.getPublicKey().getExpiryTime();
  long masterKeyExpiry=expiryTime != null ? expiryTime.getTime() / 1000 : 0L;
  return internal(sKR,masterSecretKey,masterKeyFlags,masterKeyExpiry,cryptoInput,saveParcel,log);
}

Fixed version (ground truth):
/** 
 * This method introduces a list of modifications specified by a SaveKeyringParcel to a WrappedSecretKeyRing. This method relies on WrappedSecretKeyRing's canonicalization property! Note that PGPPublicKeyRings can not be directly modified. Instead, the corresponding PGPSecretKeyRing must be modified and consequently consolidated with its public counterpart. This is a natural workflow since pgp keyrings are immutable data structures: Old semantics are changed by adding new certificates, which implicitly override older certificates. Note that this method does not care about any "special" type of master key. If unlocking with a passphrase fails, the operation will fail with an unlocking error. More specific handling of errors should be done in UI code! If the passphrase is null, only a restricted subset of operations will be available, namely stripping of subkeys and changing the protection mode of dummy keys.
 */
public PgpEditKeyResult modifySecretKeyRing(CanonicalizedSecretKeyRing wsKR,CryptoInputParcel cryptoInput,SaveKeyringParcel saveParcel){
  OperationLog log=new OperationLog();
  int indent=0;
  log.add(LogType.MSG_MF,indent,KeyFormattingUtils.convertKeyIdToHex(wsKR.getMasterKeyId()));
  indent+=1;
  progress(R.string.progress_building_key,0);
  if (saveParcel.mMasterKeyId == null || saveParcel.mMasterKeyId != wsKR.getMasterKeyId()) {
    log.add(LogType.MSG_MF_ERROR_KEYID,indent);
    return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR,log,null);
  }
  PGPSecretKeyRing sKR=wsKR.getRing();
  PGPSecretKey masterSecretKey=sKR.getSecretKey();
  if (saveParcel.mFingerprint == null || !Arrays.equals(saveParcel.mFingerprint,masterSecretKey.getPublicKey().getFingerprint())) {
    log.add(LogType.MSG_MF_ERROR_FINGERPRINT,indent);
    return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR,log,null);
  }
  if (saveParcel.isEmpty()) {
    log.add(LogType.MSG_MF_ERROR_NOOP,indent);
    return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR,log,null);
  }
  if (isDummy(masterSecretKey) || saveParcel.isRestrictedOnly()) {
    log.add(LogType.MSG_MF_RESTRICTED_MODE,indent);
    return internalRestricted(sKR,saveParcel,log);
  }
  if (!isDivertToCard(masterSecretKey) && !cryptoInput.hasPassphrase()) {
    log.add(LogType.MSG_MF_REQUIRE_PASSPHRASE,indent);
    return new PgpEditKeyResult(log,RequiredInputParcel.createRequiredSignPassphrase(masterSecretKey.getKeyID(),masterSecretKey.getKeyID(),cryptoInput.getSignatureTime()));
  }
  PGPPublicKey masterPublicKey=masterSecretKey.getPublicKey();
  int masterKeyFlags=readKeyFlags(masterPublicKey) | KeyFlags.CERTIFY_OTHER;
  Date expiryTime=wsKR.getPublicKey().getExpiryTime();
  long masterKeyExpiry=expiryTime != null ? expiryTime.getTime() / 1000 : 0L;
  return internal(sKR,masterSecretKey,masterKeyFlags,masterKeyExpiry,cryptoInput,saveParcel,log,indent);
}