Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package com.fsck.k9.autocrypt

import androidx.annotation.VisibleForTesting
import com.fsck.k9.mail.Part
import com.fsck.k9.mail.internet.MimeUtility
import net.thunderbird.core.logging.legacy.Log
import okio.ByteString.Companion.decodeBase64

internal class AutocryptGossipHeaderParser private constructor() {

fun getAllAutocryptGossipHeaders(part: Part): List<AutocryptGossipHeader> {
return parseAllAutocryptGossipHeaders(
part.getHeader(AutocryptGossipHeader.AUTOCRYPT_GOSSIP_HEADER),
)
}

@VisibleForTesting
fun parseAutocryptGossipHeader(headerValue: String): AutocryptGossipHeader? {
val parameters = MimeUtility.getAllHeaderParameters(headerValue).toMutableMap()

val type = parameters.remove(AutocryptHeader.AUTOCRYPT_PARAM_TYPE)
val base64KeyData = parameters.remove(AutocryptHeader.AUTOCRYPT_PARAM_KEY_DATA)
val addr = parameters.remove(AutocryptHeader.AUTOCRYPT_PARAM_ADDR)

return when {
type != null && type != AutocryptHeader.AUTOCRYPT_TYPE_1 -> {
Log.e("autocrypt: unsupported type parameter %s", type)
null
}

base64KeyData == null -> {
Log.e("autocrypt: missing key parameter")
null
}

base64KeyData.decodeBase64() == null -> {
Log.e("autocrypt: error parsing base64 data")
null
}

addr == null -> {
Log.e("autocrypt: no to header!")
null
}

hasCriticalParameters(parameters) -> {
null
}

else -> {
val byteString = base64KeyData.decodeBase64()!! // safe after null-check
AutocryptGossipHeader(addr, byteString.toByteArray())
}
}
}

private fun hasCriticalParameters(parameters: Map<String, String>): Boolean {
return parameters.keys.any { !it.startsWith("_") }
}

private fun parseAllAutocryptGossipHeaders(headers: Array<String>): List<AutocryptGossipHeader> {
return headers.mapNotNull { header ->
parseAutocryptGossipHeader(header) ?: run {
Log.e("Encountered malformed autocrypt-gossip header - skipping!")
null
}
}
}

companion object {
val instance: AutocryptGossipHeaderParser by lazy { AutocryptGossipHeaderParser() }
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package com.fsck.k9.autocrypt

import androidx.annotation.VisibleForTesting
import com.fsck.k9.mail.Message
import com.fsck.k9.mail.internet.MimeUtility
import net.thunderbird.core.logging.legacy.Log
import okio.ByteString.Companion.decodeBase64

internal class AutocryptHeaderParser private constructor() {

fun getValidAutocryptHeader(currentMessage: Message): AutocryptHeader? {
val headers = currentMessage.getHeader(AutocryptHeader.AUTOCRYPT_HEADER).orEmpty().asList()
return parseAllAutocryptHeaders(headers).singleOrNull()
}

@VisibleForTesting
fun parseAutocryptHeader(headerValue: String): AutocryptHeader? {
val parameters = MimeUtility.getAllHeaderParameters(headerValue).toMutableMap()

val type = parameters.remove(AutocryptHeader.AUTOCRYPT_PARAM_TYPE)
val base64KeyData = parameters.remove(AutocryptHeader.AUTOCRYPT_PARAM_KEY_DATA)
val to = parameters.remove(AutocryptHeader.AUTOCRYPT_PARAM_ADDR)
val preferEncrypt = parameters.remove(AutocryptHeader.AUTOCRYPT_PARAM_PREFER_ENCRYPT)

val decodedKeyData = base64KeyData?.decodeBase64()

return when {
type != null && type != AutocryptHeader.AUTOCRYPT_TYPE_1 -> {
Log.e(TAG, "Unsupported type parameter: $type")
null
}

base64KeyData == null -> {
Log.e(TAG, "Missing key parameter")
null
}

decodedKeyData == null -> {
Log.e(TAG, "Error parsing base64 data")
null
}

to == null -> {
Log.e(TAG, "No 'to' header found")
null
}

hasCriticalParameters(parameters) -> null

else -> AutocryptHeader(
parameters = parameters,
addr = to,
keyData = decodedKeyData.toByteArray(),
isPreferEncryptMutual = AutocryptHeader.AUTOCRYPT_PREFER_ENCRYPT_MUTUAL.equals(
preferEncrypt,
ignoreCase = true,
),
)
}
}

private fun hasCriticalParameters(parameters: Map<String, String>): Boolean {
return parameters.keys.any { !it.startsWith("_") }
}

private fun parseAllAutocryptHeaders(headers: Collection<String>): List<AutocryptHeader> {
return headers.mapNotNull(::parseAutocryptHeader)
}

companion object {
private const val TAG = "AutocryptHeaderParser"

val instance: AutocryptHeaderParser by lazy { AutocryptHeaderParser() }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ public class AutocryptOperations {


public static AutocryptOperations getInstance() {
AutocryptHeaderParser autocryptHeaderParser = AutocryptHeaderParser.getInstance();
AutocryptGossipHeaderParser autocryptGossipHeaderParser = AutocryptGossipHeaderParser.getInstance();
AutocryptHeaderParser autocryptHeaderParser = AutocryptHeaderParser.Companion.getInstance();
AutocryptGossipHeaderParser autocryptGossipHeaderParser = AutocryptGossipHeaderParser.Companion.getInstance();
return new AutocryptOperations(autocryptHeaderParser, autocryptGossipHeaderParser);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import org.junit.Test

class AutocryptGossipHeaderParserTest {

private val autocryptGossipHeaderParser = AutocryptGossipHeaderParser.getInstance()
private val autocryptGossipHeaderParser = AutocryptGossipHeaderParser.Companion.instance

@Before
fun setUp() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@


public class AutocryptHeaderParserTest extends RobolectricTest {
AutocryptHeaderParser autocryptHeaderParser = AutocryptHeaderParser.getInstance();
AutocryptHeaderParser autocryptHeaderParser = AutocryptHeaderParser.Companion.getInstance();

@Before
public void setUp() throws Exception {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@


public class AutocryptOperationsHelper {
private static AutocryptHeaderParser INSTANCE = AutocryptHeaderParser.getInstance();
private static AutocryptHeaderParser INSTANCE = AutocryptHeaderParser.Companion.getInstance();

public static void assertMessageHasAutocryptHeader(
MimeMessage message, String addr, boolean isPreferEncryptMutual, byte[] keyData) {
Expand Down
Loading