Add TextVerificationResult for crypto.verify

This commit is contained in:
larabr 2022-01-22 13:15:04 +01:00 committed by Zorica Stojchevska
parent 7d6911b52d
commit a6354427a7
6 changed files with 61 additions and 13 deletions

View File

@ -56,7 +56,7 @@ import ch.protonmail.android.domain.entity.user.Addresses;
import ch.protonmail.android.utils.Logger;
import ch.protonmail.android.utils.VCardUtil;
import ch.protonmail.android.utils.crypto.KeyInformation;
import ch.protonmail.android.utils.crypto.TextDecryptionResult;
import ch.protonmail.android.utils.crypto.TextVerificationResult;
import ezvcard.Ezvcard;
import ezvcard.VCard;
import ezvcard.property.Key;
@ -278,9 +278,9 @@ public class SendPreferencesFactory {
for (ContactEncryptedData card : cards) {
switch (card.getEncryptionType()) {
case SIGNED:
TextDecryptionResult tdr = crypto.verify(card.getData(), card.getSignature());
signedData = tdr.getDecryptedData();
isContactSignatureVerified = tdr.isSignatureValid();
TextVerificationResult tvr = crypto.verify(card.getData(), card.getSignature());
signedData = tvr.getData();
isContactSignatureVerified = tvr.isSignatureValid();
break;
case CLEARTEXT:
clearData = card.getData();

View File

@ -24,6 +24,7 @@ import ch.protonmail.android.domain.entity.user.UserKey
import ch.protonmail.android.utils.crypto.KeyInformation
import ch.protonmail.android.utils.crypto.OpenPGP
import ch.protonmail.android.utils.crypto.TextDecryptionResult
import ch.protonmail.android.utils.crypto.TextVerificationResult
import com.proton.gopenpgp.armor.Armor
import com.squareup.inject.assisted.Assisted
import com.squareup.inject.assisted.AssistedInject
@ -53,12 +54,12 @@ class UserCrypto @AssistedInject constructor(
override fun passphraseFor(key: UserKey): EncryptedByteArray? = primaryPassphrase
fun verify(data: String, signature: String): TextDecryptionResult {
fun verify(data: String, signature: String): TextVerificationResult {
return try {
val valid = openPgp.verifyTextSignDetachedBinKey(signature, data, getVerificationKeys(), openPgp.time)
TextDecryptionResult(data, true, valid)
val verifiedTimestamp = openPgp.getVerifiedSignatureTimestamp(signature, data, getVerificationKeys(), openPgp.time)
TextVerificationResult(data, true, verifiedTimestamp)
} catch(signatureVerificationError: Exception) {
TextDecryptionResult(data, true, false)
TextVerificationResult(data, false, null)
}
}

View File

@ -134,7 +134,7 @@ data class FullContactDetails @Ignore constructor(
?.let {
runCatching { crypto.verify(it.data, it.signature) }
.fold(
onSuccess = { if (it.isSignatureValid) it.decryptedData else null },
onSuccess = { if (it.isSignatureValid) it.data else null },
onFailure = { null }
)
}

View File

@ -182,6 +182,12 @@ public class OpenPGP {
}
}
// Verify the signature and return signature creation time if verification is successful, throws otherwise
public Long getVerifiedSignatureTimestamp(String signature, String plainText, List<byte[]> publicKeys, long verifyTime) throws Exception {
KeyRing signingKeyRing = buildKeyRing(publicKeys);
return signingKeyRing.getVerifiedSignatureTimestamp(new PlainMessage(plainText), new PGPSignature(signature), verifyTime);
}
public SessionKey getSessionFromKeyPacketBinkeys(byte[] keyPackage, byte[] privateKey, byte[] passphrase) throws Exception {
KeyRing privateKeyRing = buildPrivateKeyRing(privateKey, passphrase);
try {

View File

@ -0,0 +1,41 @@
package ch.protonmail.android.utils.crypto;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.util.Objects;
public class TextVerificationResult extends AbstractDecryptionResult {
private final String data;
private final Long verifiedSignatureTimestamp;
public TextVerificationResult(@NonNull String data, boolean signatureIsValid, @Nullable Long verifiedSignatureTimestamp) {
super(true, signatureIsValid);
this.data = data;
if (signatureIsValid) {
this.verifiedSignatureTimestamp = Objects.requireNonNull(verifiedSignatureTimestamp, "verifiedSignatureTimestamp must not be null for valid signatures");
} else if (verifiedSignatureTimestamp != null) {
throw new IllegalArgumentException("verifiedSignatureTimestamp must be null for invalid signatures");
} else {
this.verifiedSignatureTimestamp = null;
}
}
/**
* @return creation time of the verified signature, or null for invalid signatures
*/
@Nullable
public Long getVerifiedSignatureTimestamp() {
return verifiedSignatureTimestamp;
}
/**
* @return signed data. Call `isVerified` to confirm signature validity.
*/
public String getData() {
return data;
}
}

View File

@ -25,7 +25,7 @@ import ch.protonmail.android.core.Constants
import ch.protonmail.android.core.UserManager
import ch.protonmail.android.crypto.UserCrypto
import me.proton.core.domain.entity.UserId
import ch.protonmail.android.utils.crypto.TextDecryptionResult
import ch.protonmail.android.utils.crypto.TextVerificationResult
import ezvcard.parameter.VCardParameters
import ezvcard.property.Address
import ezvcard.property.Birthday
@ -168,8 +168,8 @@ class FetchContactsMapperTest {
every { data } returns testCardType2
every { signature } returns type2Signature
}
every { crypto.verify(testCardType2, type2Signature) } returns TextDecryptionResult(
testCardType2, true, true
every { crypto.verify(testCardType2, type2Signature) } returns TextVerificationResult(
testCardType2, true, 0
)
val email1 = Email(
@ -234,7 +234,7 @@ class FetchContactsMapperTest {
every { signature } returns type3Signature
}
every { crypto.verify(testCardType3, type3Signature) } returns
TextDecryptionResult(testCardType3, true, true)
TextVerificationResult(testCardType3, true, 0)
val email1 = Email(
"tomek9@abc.com"