|
|
@ -2026,12 +2026,17 @@ public class MessageHelper {
|
|
|
|
String dns = kv.get("s") + "._domainkey." + signer;
|
|
|
|
String dns = kv.get("s") + "._domainkey." + signer;
|
|
|
|
Log.i("DKIM lookup " + dns);
|
|
|
|
Log.i("DKIM lookup " + dns);
|
|
|
|
DnsHelper.DnsRecord[] records = DnsHelper.lookup(context, dns, "txt");
|
|
|
|
DnsHelper.DnsRecord[] records = DnsHelper.lookup(context, dns, "txt");
|
|
|
|
if (records.length > 0) {
|
|
|
|
if (records.length == 0)
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
Log.i("DKIM got " + records[0].name);
|
|
|
|
Log.i("DKIM got " + records[0].name);
|
|
|
|
Map<String, String> dk = getKeyValues(records[0].name);
|
|
|
|
Map<String, String> dk = getKeyValues(records[0].name);
|
|
|
|
|
|
|
|
|
|
|
|
Log.i("DKIM canonicalization=" + kv.get("c"));
|
|
|
|
String canonic = kv.get("c");
|
|
|
|
String[] c = kv.get("c").split("/");
|
|
|
|
Log.i("DKIM canonicalization=" + canonic);
|
|
|
|
|
|
|
|
if (canonic == null)
|
|
|
|
|
|
|
|
canonic = "simple/simple";
|
|
|
|
|
|
|
|
String[] c = canonic.split("/");
|
|
|
|
|
|
|
|
|
|
|
|
StringBuilder head = new StringBuilder();
|
|
|
|
StringBuilder head = new StringBuilder();
|
|
|
|
|
|
|
|
|
|
|
@ -2040,6 +2045,7 @@ public class MessageHelper {
|
|
|
|
|
|
|
|
|
|
|
|
boolean from = false;
|
|
|
|
boolean from = false;
|
|
|
|
List<String> _h = new ArrayList<>();
|
|
|
|
List<String> _h = new ArrayList<>();
|
|
|
|
|
|
|
|
if (hs != null)
|
|
|
|
for (String key : hs.split(":")) {
|
|
|
|
for (String key : hs.split(":")) {
|
|
|
|
_h.add(key.trim());
|
|
|
|
_h.add(key.trim());
|
|
|
|
from = (from || "from".equalsIgnoreCase(key.trim()));
|
|
|
|
from = (from || "from".equalsIgnoreCase(key.trim()));
|
|
|
@ -2057,7 +2063,9 @@ public class MessageHelper {
|
|
|
|
idx = (idx == null ? 1 : idx + 1);
|
|
|
|
idx = (idx == null ? 1 : idx + 1);
|
|
|
|
index.put(_n, idx);
|
|
|
|
index.put(_n, idx);
|
|
|
|
|
|
|
|
|
|
|
|
String[] h = ("DKIM-Signature".equals(n) ? new String[]{header} : amessage.getHeader(n));
|
|
|
|
String[] h = ("DKIM-Signature".equals(n)
|
|
|
|
|
|
|
|
? new String[]{header}
|
|
|
|
|
|
|
|
: amessage.getHeader(n));
|
|
|
|
if (h == null || idx > h.length) {
|
|
|
|
if (h == null || idx > h.length) {
|
|
|
|
// https://datatracker.ietf.org/doc/html/rfc6376/#section-5.4
|
|
|
|
// https://datatracker.ietf.org/doc/html/rfc6376/#section-5.4
|
|
|
|
Log.i("DKIM missing header=" + n + "[" + idx + "/" + (h == null ? null : h.length) + "]");
|
|
|
|
Log.i("DKIM missing header=" + n + "[" + idx + "/" + (h == null ? null : h.length) + "]");
|
|
|
@ -2128,7 +2136,11 @@ public class MessageHelper {
|
|
|
|
byte[] bh = MessageDigest.getInstance(halgo).digest(body.getBytes()); // TODO: charset
|
|
|
|
byte[] bh = MessageDigest.getInstance(halgo).digest(body.getBytes()); // TODO: charset
|
|
|
|
Log.i("DKIM bh=" + Base64.encodeToString(bh, Base64.NO_WRAP) + "/" + kv.get("bh"));
|
|
|
|
Log.i("DKIM bh=" + Base64.encodeToString(bh, Base64.NO_WRAP) + "/" + kv.get("bh"));
|
|
|
|
|
|
|
|
|
|
|
|
String p = dk.get("p").replaceAll("\\s+", "");
|
|
|
|
String pubkey = dk.get("p");
|
|
|
|
|
|
|
|
if (pubkey == null)
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
String p = pubkey.replaceAll("\\s+", "");
|
|
|
|
Log.i("DKIM pubkey=" + p);
|
|
|
|
Log.i("DKIM pubkey=" + p);
|
|
|
|
|
|
|
|
|
|
|
|
X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(Base64.decode(p, Base64.DEFAULT));
|
|
|
|
X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(Base64.decode(p, Base64.DEFAULT));
|
|
|
@ -2136,11 +2148,13 @@ public class MessageHelper {
|
|
|
|
PublicKey pubKey = keyFactory.generatePublic(pubKeySpec);
|
|
|
|
PublicKey pubKey = keyFactory.generatePublic(pubKeySpec);
|
|
|
|
Signature sig = Signature.getInstance(salgo); // a=
|
|
|
|
Signature sig = Signature.getInstance(salgo); // a=
|
|
|
|
|
|
|
|
|
|
|
|
String s = kv.get("b").replaceAll("\\s+", "");
|
|
|
|
String hash = kv.get("b");
|
|
|
|
|
|
|
|
if (hash == null)
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
String s = hash.replaceAll("\\s+", "");
|
|
|
|
Log.i("DKIM signature=" + s);
|
|
|
|
Log.i("DKIM signature=" + s);
|
|
|
|
|
|
|
|
|
|
|
|
byte[] signature = Base64.decode(s, Base64.DEFAULT);
|
|
|
|
byte[] signature = Base64.decode(s, Base64.DEFAULT);
|
|
|
|
// TODO: check signature length
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sig.initVerify(pubKey);
|
|
|
|
sig.initVerify(pubKey);
|
|
|
|
sig.update(head.toString().getBytes());
|
|
|
|
sig.update(head.toString().getBytes());
|
|
|
@ -2153,7 +2167,6 @@ public class MessageHelper {
|
|
|
|
if (verified &&
|
|
|
|
if (verified &&
|
|
|
|
!signers.contains(signer))
|
|
|
|
!signers.contains(signer))
|
|
|
|
signers.add(signer);
|
|
|
|
signers.add(signer);
|
|
|
|
}
|
|
|
|
|
|
|
|
} catch (Throwable ex) {
|
|
|
|
} catch (Throwable ex) {
|
|
|
|
Log.e("DKIM", ex);
|
|
|
|
Log.e("DKIM", ex);
|
|
|
|
}
|
|
|
|
}
|
|
|
|