diff --git a/src/foundation/pEp/jniadapter/AbstractEngine.java b/src/foundation/pEp/jniadapter/AbstractEngine.java index f882fce..f492ccb 100644 --- a/src/foundation/pEp/jniadapter/AbstractEngine.java +++ b/src/foundation/pEp/jniadapter/AbstractEngine.java @@ -194,5 +194,52 @@ abstract class AbstractEngine extends UniquelyIdentifiable implements AutoClosea } return 0; } -} + public Message incomingMessageFromPGPText(String pgpText, Message.EncFormat encFormat) { + Message msg = new Message(); + msg.setDir(Message.Direction.Incoming); + msg.setEncFormat(encFormat); + + // Opts + ArrayList> opts = new ArrayList<>(); + Pair xpEp = new Pair<>(); + xpEp.first = "X-pEp-Version"; + xpEp.second = this.getProtocolVersion();; + opts.add(xpEp); + msg.setOptFields(opts); + + if(encFormat == Message.EncFormat.PEP) { + // For EncFormat.PEP + // The pgpText goes into the attachment index 1 + msg.setShortmsg("p≡p"); + msg.setLongmsg("this message was encrypted with p≡p https://pEp-project.org"); + + // Attachments + Blob att0 = new Blob(); + att0.mime_type = "application/pgp-encrypted"; + att0.filename = null; + att0.data = "Version: 1".getBytes(); + + Blob att1 = new Blob(); + att1.mime_type = "application/octet-stream"; + att1.filename = "file://msg.asc"; + att1.data = pgpText.getBytes(); + + Vector attachments = new Vector<>(); + attachments.add(att0); + attachments.add(att1); + msg.setAttachments(attachments); + } + else if (encFormat == Message.EncFormat.PEPEncInlineEA) { + // For EncFormat.PEPEncInlineEA + // The pgpText goes into the longMessage + msg.setShortmsg(""); + msg.setLongmsg(pgpText); + } + else { + throw new pEpCannotEncode("Message.Encformat not supported: " + encFormat.toString()); + } + + return msg; + } +} \ No newline at end of file diff --git a/src/pEp.yml2 b/src/pEp.yml2 index 0a96c3f..dd1b14d 100644 --- a/src/pEp.yml2 +++ b/src/pEp.yml2 @@ -285,11 +285,12 @@ namespace pEp { } enum EncFormat { - none > 0 - inline > 1 - SMIME > 2 - PGPMIME > 3 - PEP > 4 + none > 0 + inline > 1 + SMIME > 2 + PGPMIME > 3 + PEP > 4 + PEP_enc_inline_EA > 6 } direction dir; diff --git a/test/java/foundation/pEp/jniadapter/test/Makefile b/test/java/foundation/pEp/jniadapter/test/Makefile index d1eb828..8fad575 100644 --- a/test/java/foundation/pEp/jniadapter/test/Makefile +++ b/test/java/foundation/pEp/jniadapter/test/Makefile @@ -10,6 +10,7 @@ run: compile $(MAKE) -C jni91 run $(MAKE) -C jni92 run $(MAKE) -C jni94 run + $(MAKE) -C jni98 run compile: $(MAKE) -C template compile @@ -19,6 +20,7 @@ compile: $(MAKE) -C jni91 compile $(MAKE) -C jni92 compile $(MAKE) -C jni94 compile + $(MAKE) -C jni98 compile clean: $(MAKE) -C template clean @@ -28,6 +30,7 @@ clean: $(MAKE) -C jni91 clean $(MAKE) -C jni92 clean $(MAKE) -C jni94 clean + $(MAKE) -C jni98 clean clean-pep-home: $(MAKE) -C basic clean-pep-home diff --git a/test/java/foundation/pEp/jniadapter/test/jni98/Makefile b/test/java/foundation/pEp/jniadapter/test/jni98/Makefile new file mode 100644 index 0000000..6f1e518 --- /dev/null +++ b/test/java/foundation/pEp/jniadapter/test/jni98/Makefile @@ -0,0 +1,34 @@ +include ../../../../../../../Makefile.conf +include ../Makefile.conf + +TEST_UNIT_NAME=jni98 + +JAVA_CLASSES = \ + TestMain.class \ + ../utils/AdapterTestUtils.class + +JAVA_CLASSES += $(JAVA_CLASSES_FRAMEWORK) + +.PHONY: compile run test clean + +all: compile + $(MAKE) run + +run: compile + cd $(JAVA_CWD);pwd;HOME=$(JAVA_PEP_HOME_DIR) $(JAVA) $(JAVA_PKG_BASENAME).$(TEST_UNIT_NAME).TestMain + +compile: $(JAVA_CLASSES) + +%.class: %.java + cd $(JAVA_CWD);javac -cp $(CLASSPATH) $(JAVA_PKG_BASEPATH)/$(TEST_UNIT_NAME)/$< + +clean: + rm -f $(JAVA_CLASSES) + rm -f *.class + rm -f *.log + rm -Rf .gnupg + rm -Rf .lldb + +clean-pep-home: + rm -rf $(PEP_HOME_DIR)/* + rm -rf $(PEP_HOME_DIR)/.pEp \ No newline at end of file diff --git a/test/java/foundation/pEp/jniadapter/test/jni98/TestMain.java b/test/java/foundation/pEp/jniadapter/test/jni98/TestMain.java new file mode 100644 index 0000000..8883a33 --- /dev/null +++ b/test/java/foundation/pEp/jniadapter/test/jni98/TestMain.java @@ -0,0 +1,84 @@ +package foundation.pEp.jniadapter.test.jni98; + +import foundation.pEp.jniadapter.Engine; +import foundation.pEp.jniadapter.Message; +import foundation.pEp.jniadapter.test.framework.TestUnit; +import foundation.pEp.jniadapter.test.utils.AdapterBaseTestContext; + +import static foundation.pEp.jniadapter.test.framework.TestLogger.log; +import static foundation.pEp.jniadapter.test.framework.TestLogger.logH2; +import static foundation.pEp.jniadapter.test.utils.AdapterTestUtils.msgToString; + +/* +JNI-98 - "Factory function for generating incoming message from PGP text" + +Problem: +There must be a static function in class Engine, which is generating an encrypted +version of a Message, which is structured like messages coming out from encrypt_message() +when being used with Message.EncFormat.PEP. Additionally, it should work with inline format, too. +The signature is expected to be: + +public static Message incomingMessageFromPGPText(String pgpText, Message.EncFormat encFormat) + +Please see https://pep.foundation/jira/browse/JNI-98 for further discussion +*/ + + +class TestMain { + public static void main(String[] args) throws Exception { + new TestUnit("JNI-98 - Message.EncFormat.PEP", new AdapterBaseTestContext(), env -> { + // Make msg1 by encrypting msgToBob + logH2("Create target Message"); + Message msg1 = env.engine.encrypt_message(env.msgToBob, null, Message.EncFormat.PEP); + log("\n" + msgToString(msg1, false)); + + // Lets get the pgpText of the msg1, and the EncFormat + String pgpText = Engine.toUTF16(msg1.getAttachments().elementAt(1).data); + Message.EncFormat ef = msg1.getEncFormat(); + //TODO: setting encformat to 4 (PEP) but getting back 3 (PGPMIME) + + // Create msg2 by using incomingMessageFromPGPText with the pgpText and EncFormat from msg1 + logH2("incomingMessageFromPGPText()"); + Message msg2 = env.engine.incomingMessageFromPGPText(pgpText, Message.EncFormat.PEP); + log("\n" + msgToString(msg2, false)); + + logH2("Verify msg2"); + Engine.decrypt_message_Return result = null; + result = env.engine.decrypt_message(msg2, env.vStr, 0); + log("\n" + msgToString(result.dst, false)); + }).run(); + + new TestUnit("JNI-98 - Message.EncFormat.PEP_enc_inline_EA", new AdapterBaseTestContext(), env -> { + // Make msg1 by encrypting msgToBob + logH2("Create target Message"); + Message msg1 = env.engine.encrypt_message(env.msgToBob, null, Message.EncFormat.PEPEncInlineEA); + log("\n" + msgToString(msg1, false)); + + // Lets get the pgpText of the msg1, and the EncFormat + String pgpText = msg1.getLongmsg(); + Message.EncFormat ef = msg1.getEncFormat(); + + // Create msg2 by using incomingMessageFromPGPText with the pgpText and EncFormat from msg1 + logH2("incomingMessageFromPGPText()"); + Message msg2 = env.engine.incomingMessageFromPGPText(pgpText, ef); + log("\n" + msgToString(msg2, false)); + + // Cant be just simply decrypted again + // And thats correct according to fdik + //[21:29] < heck> | Assertion failed: (value && size && mime_type && code && !code[0] && code_size), function decode_internal, file internal_format.c, line 113. + //[21:31] < fdik> | ja + //[21:31] < fdik> | auch das ist korrekt + //[21:31] < fdik> | wenn Du EA verwendest, dann geht es nicht, dass man die Nachricht so wie sie ist wieder decrypted + //[21:31] < fdik> | sondern das geht nur, wenn man sie zerlegt + //[21:32] < fdik> | dafür ist das Verfahren da + //[21:34] < fdik> | ich hab einen Test dafür geschrieben + //[21:34] < fdik> | pEpEngine/test/src/ElevatedAttachmentsTest.cc + //[21:34] < fdik> | in default + //[21:35] < fdik> | Doku hier https://dev.pep.foundation/Engine/ElevatedAttachments + //[21:35] < fdik> | siehe hier: + //[21:35] < fdik> | https://dev.pep.foundation/Engine/ElevatedAttachments#support-in-message-api + }).run(); + } +} + + diff --git a/test/java/foundation/pEp/jniadapter/test/utils/AdapterTestUtils.java b/test/java/foundation/pEp/jniadapter/test/utils/AdapterTestUtils.java index 2445599..371e41f 100644 --- a/test/java/foundation/pEp/jniadapter/test/utils/AdapterTestUtils.java +++ b/test/java/foundation/pEp/jniadapter/test/utils/AdapterTestUtils.java @@ -23,133 +23,162 @@ public class AdapterTestUtils { return ret; } - public static String msgToString(Message msg) { + + public static String msgToString(Message msg, boolean full) { String ret = ""; - ret += "getAttachments: "; + ArrayList> kvs = new ArrayList<>(); + String key = ""; + String value = ""; + + key = "getAttachments"; try { - ret += blobListToString(msg.getAttachments()) + "\n"; - } catch(Throwable e) { - ret += e.toString() + "\n"; + value = blobListToString(msg.getAttachments(), full) + "\n"; + } catch (Throwable e) { + value = e.toString(); } + kvs.add(new Pair<>(key, value)); - ret += "Id: "; + key = "Id"; try { - ret += msg.getId() + "\n"; - } catch(Throwable e) { - ret += e.toString() + "\n"; + value = msg.getId(); + } catch (Throwable e) { + value = e.toString(); } + kvs.add(new Pair<>(key, value)); - ret += "getDir: "; + key = "getDir"; try { - ret += msg.getDir().toString() + "\n"; - } catch(Throwable e) { - ret += e.toString() + "\n"; + value = msg.getDir().toString(); + } catch (Throwable e) { + value = e.toString(); } + kvs.add(new Pair<>(key, value)); - ret += "getShortmsg: "; + key = "getShortmsg"; try { - ret += msg.getShortmsg() + "\n"; - } catch(Throwable e) { - ret += e.toString() + "\n"; + value = msg.getShortmsg(); + } catch (Throwable e) { + value = e.toString(); } + kvs.add(new Pair<>(key, value)); - ret += "getLongmsg: "; + key = "getLongmsg"; try { - ret += msg.getLongmsg() + "\n"; - } catch(Throwable e) { - ret += e.toString() + "\n"; + value = msg.getLongmsg(); + } catch (Throwable e) { + value = e.toString(); } + kvs.add(new Pair<>(key, value)); - ret += "getLongmsgFormatted: "; + key = "getLongmsgFormatted"; try { - ret += msg.getLongmsgFormatted() + "\n"; - } catch(Throwable e) { - ret += e.toString() + "\n"; + value = msg.getLongmsgFormatted(); + } catch (Throwable e) { + value = e.toString(); } + kvs.add(new Pair<>(key, value)); - ret += "getFrom: "; + key = "getFrom"; try { - ret += identityToString(msg.getFrom(), false) + "\n"; - } catch(Throwable e) { - ret += e.toString() + "\n"; + value = identityToString(msg.getFrom(), full); + } catch (Throwable e) { + value = e.toString(); } + kvs.add(new Pair<>(key, value)); - ret += "getTo: "; + key = "getTo"; try { - ret += identityListToString(msg.getTo(), false) + "\n"; - } catch(Throwable e) { - ret += e.toString() + "\n"; + value = identityListToString(msg.getTo(), full); + } catch (Throwable e) { + value = e.toString(); } + kvs.add(new Pair<>(key, value)); - ret += "getRecvBy: "; + key = "getRecvBy"; try { - ret += identityToString(msg.getRecvBy(), false) + "\n"; - } catch(Throwable e) { - ret += e.toString() + "\n"; + value = identityToString(msg.getRecvBy(), full); + } catch (Throwable e) { + value = e.toString(); } + kvs.add(new Pair<>(key, value)); - ret += "getCc: "; + key = "getCc"; try { - ret += identityListToString(msg.getCc(), false)+ "\n"; - } catch(Throwable e) { - ret += e.toString() + "\n"; + value = identityListToString(msg.getCc(), full) + "\n"; + } catch (Throwable e) { + value = e.toString(); } + kvs.add(new Pair<>(key, value)); - ret += "getBcc: "; + key = "getBcc"; try { - ret += identityListToString(msg.getBcc(), false) + "\n"; - } catch(Throwable e) { - ret += e.toString() + "\n"; + value = identityListToString(msg.getBcc(), full); + } catch (Throwable e) { + value = e.toString(); } + kvs.add(new Pair<>(key, value)); - ret += "getReplyTo: "; + key = "getReplyTo"; try { - ret += identityListToString(msg.getReplyTo(), false) + "\n"; - } catch(Throwable e) { - ret += e.toString() + "\n"; + value = identityListToString(msg.getReplyTo(), full); + } catch (Throwable e) { + value = e.toString(); } + kvs.add(new Pair<>(key, value)); - ret += "getInReplyTo: "; + key = "getInReplyTo"; try { - ret += stringVectorToString(msg.getInReplyTo()) + "\n"; - } catch(Throwable e) { - ret += e.toString() + "\n"; + value = stringVectorToString(msg.getInReplyTo()); + } catch (Throwable e) { + value = e.toString(); } + kvs.add(new Pair<>(key, value)); - ret += "getReferences: "; + key = "getReferences"; try { - ret += stringVectorToString(msg.getReferences()) + "\n"; - } catch(Throwable e) { - ret += e.toString() + "\n"; + value = stringVectorToString(msg.getReferences()); + } catch (Throwable e) { + value = e.toString(); } + kvs.add(new Pair<>(key, value)); - ret += "getKeywords: "; + key = "getKeywords"; try { - ret += stringVectorToString(msg.getKeywords()) + "\n"; - } catch(Throwable e) { - ret += e.toString() + "\n"; + value = stringVectorToString(msg.getKeywords()); + } catch (Throwable e) { + value = e.toString(); } + kvs.add(new Pair<>(key, value)); - ret += "getComments: "; + key = "getComments"; try { - ret += msg.getComments() + "\n"; - } catch(Throwable e) { - ret += e.toString() + "\n"; + value = msg.getComments(); + } catch (Throwable e) { + value = e.toString(); } + kvs.add(new Pair<>(key, value)); - ret += "getOptFields: "; + key = "getOptFields"; try { - ret += stringPairListToString(msg.getOptFields()) + "\n"; - } catch(Throwable e) { - ret += e.toString() + "\n"; + value = stringPairListToString(msg.getOptFields()); + } catch (Throwable e) { + value = e.toString(); } + kvs.add(new Pair<>(key, value)); - ret += "getEncFormat: "; + key = "getEncFormat"; try { - ret += msg.getEncFormat().toString() + "\n"; - } catch(Throwable e) { - ret += e.toString() + "\n"; + value = msg.getEncFormat().toString(); + } catch (Throwable e) { + value = e.toString(); } + kvs.add(new Pair(key, value)); + + if (!full) { + kvs = clipStrings(kvs, 200); + } + + ret = stringPairListToString(kvs); ret = ret.trim(); return ret; @@ -157,7 +186,7 @@ public class AdapterTestUtils { public static String stringVectorToString(Vector vS) { String ret = ""; - for (String s : vS){ + for (String s : vS) { ret += s + "\n"; } ret = ret.trim(); @@ -166,32 +195,87 @@ public class AdapterTestUtils { public static String identityListToString(Vector vI, Boolean full) { String ret = ""; - for(Identity i : vI) { + for (Identity i : vI) { ret += identityToString(i, full) + "\n"; } ret = ret.trim(); return ret; } - public static String stringPairListToString(ArrayList> opts) { - String ret = ""; - for(Pair el : opts) { - ret += el.first + "=" + el.second + "\n"; - }; + public static String stringPairListToString(ArrayList> spl) { + String ret = "Invalid List: null object\n"; + if (spl != null) { + ret = ""; + for (Pair el : spl) { + String item = "Invalid StringPair: null object\n"; + if (el != null) { + item = ""; + String k = "Invalid String: null object"; + String v = "Invalid String: null object"; + if (el.first != null) { + k = el.first; + } + if (el.second != null) { + v = el.second; + } + + String delimBegin = "'"; + String delimEnd = "'"; + String indent = ""; + if (v.contains("\n") || (v.length() > 200)) { + delimBegin = " {\n"; + delimEnd = "\n}"; + delimEnd = String.format("%-100s", delimEnd); + indent = String.format("%4s", " "); + v = v.replace("\n", "\n" + indent); + } + + item = k + " = " + delimBegin + indent + v + delimEnd + "\n"; + } + ret += item; + } + } ret = ret.trim(); return ret; } - public static String blobListToString(Vector attachments) { + public static String blobListToString(Vector attachments, boolean full) { String ret = ""; ret += "Attachments count: " + attachments.size() + "\n"; - for( Blob a: attachments) { + for (Blob a : attachments) { ret += "-----BEGIN Attachment index: " + attachments.indexOf(a) + "-----\n"; - ret += a.toString(); + String tmp = a.toString(); + if (!full) { + tmp = clipString(tmp, 250); + } + ret += tmp + "\n"; ret += "-----END Attachment index: " + attachments.indexOf(a) + "-----\n"; } ret = ret.trim(); - return ret; + return ret; + } + + public static String clipString(String str, int len) { + String ret = str; + if (str.length() > len) { + ret = str.substring(0, len); + ret += " clipped... "; + } + return ret; + } + + public static ArrayList> clipStrings(ArrayList> spv, int len) { + for (Pair p : spv) { + if(p != null) { + if(p.first != null) { + p.first = clipString(p.first, len); + } + if(p.second != null) { + p.second = clipString(p.second, len); + } + } + } + return spv; } public static Message makeNewTestMessage(Identity from, Identity to, Message.Direction dir) {