From fb38830afac8851fcfaf62182a5495c0eb21dd82 Mon Sep 17 00:00:00 2001 From: Hussein Kasem Date: Tue, 7 Jul 2020 17:53:32 +0200 Subject: [PATCH 01/22] JNI-111 Add missing sync signal --- src/pEp.yml2 | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pEp.yml2 b/src/pEp.yml2 index ca00095..8810026 100644 --- a/src/pEp.yml2 +++ b/src/pEp.yml2 @@ -68,6 +68,7 @@ namespace pEp { sync_notify_accepted_device_accepted > 8 // sync_notify_overtaken > 9 // sync_notify_forming_group > 10 + sync_passphrase_required > 128 sync_notify_sole > 254 sync_notify_in_group > 255 }; From 921d77cad3fa24432548eb9c3285180dc1cf770c Mon Sep 17 00:00:00 2001 From: Hussein Kasem Date: Tue, 7 Jul 2020 17:59:34 +0200 Subject: [PATCH 02/22] JNI-111 Rethrow Java exceptions to the JVM during notifyHandshake. --- src/foundation_pEp_jniadapter_AbstractEngine.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/foundation_pEp_jniadapter_AbstractEngine.cc b/src/foundation_pEp_jniadapter_AbstractEngine.cc index 3db137c..93ee0b1 100644 --- a/src/foundation_pEp_jniadapter_AbstractEngine.cc +++ b/src/foundation_pEp_jniadapter_AbstractEngine.cc @@ -164,6 +164,7 @@ PEP_STATUS notifyHandshake(pEp_identity *me, pEp_identity *partner, sync_handsha PEP_STATUS status = (PEP_STATUS) JNISync::env()->CallIntMethod(objj, notifyHandShakeMethodID, me_, partner_, signal_); if (JNISync::env()->ExceptionCheck()) { + JNISync::env()->Throw(JNISync::env()->ExceptionOccurred()); JNISync::env()->ExceptionClear(); return PEP_UNKNOWN_ERROR; } From 8bb506c94c4db3d92180fa4b15f6d61ee66f61bd Mon Sep 17 00:00:00 2001 From: Hussein Kasem Date: Tue, 7 Jul 2020 18:05:43 +0200 Subject: [PATCH 03/22] JNI-111 Accept null partner during notifyHandshake --- src/foundation/pEp/jniadapter/AbstractEngine.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/foundation/pEp/jniadapter/AbstractEngine.java b/src/foundation/pEp/jniadapter/AbstractEngine.java index f492ccb..323461a 100644 --- a/src/foundation/pEp/jniadapter/AbstractEngine.java +++ b/src/foundation/pEp/jniadapter/AbstractEngine.java @@ -175,7 +175,8 @@ abstract class AbstractEngine extends UniquelyIdentifiable implements AutoClosea public int notifyHandshakeCallFromC(_Identity _myself, _Identity _partner, SyncHandshakeSignal _signal) { Identity myself = new Identity(_myself); - Identity partner = new Identity(_partner); + Identity partner = (_partner != null) ? new Identity(_partner) : null; + System.out.println("pEpSync" +"notifyHandshakeCallFromC: " + notifyHandshakeCallback); if (notifyHandshakeCallback != null) { notifyHandshakeCallback.notifyHandshake(myself, partner, _signal); From 39f3b5fb45a3da38f813db382ca3fea32fa3a67b Mon Sep 17 00:00:00 2001 From: heck Date: Wed, 8 Jul 2020 02:18:00 +0200 Subject: [PATCH 05/22] _if_ we should throw here, we need to do it differently... --- src/gen_cpp_Engine.ysl2 | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/gen_cpp_Engine.ysl2 b/src/gen_cpp_Engine.ysl2 index 669504b..abfa6ac 100644 --- a/src/gen_cpp_Engine.ysl2 +++ b/src/gen_cpp_Engine.ysl2 @@ -68,8 +68,31 @@ tstylesheet { choose { when "@cached = 'true'" { || - pEpLog("cached passphrase"); - PEP_STATUS status = passphrase_cache.api(::«@name»,session()`apply "parm", mode=call`); + pEpLog("cached passphrase mode"); + bool retryAfterCallback = false; + int maxRetries = 3; + int retryCount = 0; + PEP_STATUS status; + do { + // the actual target function + status = passphrase_cache.api(::«@name»,session()`apply "parm", mode=call`); + + if(status == PEP_PASSPHRASE_REQUIRED || PEP_WRONG_PASSPHRASE ) { + pEpLog("PassReq OR Wrong"); + // call the app + const char * _passphrase = "passphrase_alice"; + PEP_STATUS status = ::config_passphrase(session(),passphrase_cache.add(_passphrase)); + retryCount++; + if(retryCount > maxRetries) { + retryAfterCallback = false; + } else { + retryAfterCallback = true; + } + } else { + retryAfterCallback = false; + } + } while (retryAfterCallback); + || } otherwise { || From 96f1e9eb88ba1c90ac0ed288d814c517fcadf2e6 Mon Sep 17 00:00:00 2001 From: heck Date: Wed, 8 Jul 2020 02:26:28 +0200 Subject: [PATCH 06/22] Backed out changeset 0efc85ba691e that was the wrong file to commit --- src/gen_cpp_Engine.ysl2 | 27 ++------------------------- 1 file changed, 2 insertions(+), 25 deletions(-) diff --git a/src/gen_cpp_Engine.ysl2 b/src/gen_cpp_Engine.ysl2 index abfa6ac..669504b 100644 --- a/src/gen_cpp_Engine.ysl2 +++ b/src/gen_cpp_Engine.ysl2 @@ -68,31 +68,8 @@ tstylesheet { choose { when "@cached = 'true'" { || - pEpLog("cached passphrase mode"); - bool retryAfterCallback = false; - int maxRetries = 3; - int retryCount = 0; - PEP_STATUS status; - do { - // the actual target function - status = passphrase_cache.api(::«@name»,session()`apply "parm", mode=call`); - - if(status == PEP_PASSPHRASE_REQUIRED || PEP_WRONG_PASSPHRASE ) { - pEpLog("PassReq OR Wrong"); - // call the app - const char * _passphrase = "passphrase_alice"; - PEP_STATUS status = ::config_passphrase(session(),passphrase_cache.add(_passphrase)); - retryCount++; - if(retryCount > maxRetries) { - retryAfterCallback = false; - } else { - retryAfterCallback = true; - } - } else { - retryAfterCallback = false; - } - } while (retryAfterCallback); - + pEpLog("cached passphrase"); + PEP_STATUS status = passphrase_cache.api(::«@name»,session()`apply "parm", mode=call`); || } otherwise { || From 3b5366b7ed03c8eb6d1ae16e9fe5af793e83eab7 Mon Sep 17 00:00:00 2001 From: heck Date: Wed, 8 Jul 2020 02:29:45 +0200 Subject: [PATCH 07/22] _if_ we should throw here, we need to do it differently... --- src/foundation_pEp_jniadapter_AbstractEngine.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/foundation_pEp_jniadapter_AbstractEngine.cc b/src/foundation_pEp_jniadapter_AbstractEngine.cc index 93ee0b1..3db137c 100644 --- a/src/foundation_pEp_jniadapter_AbstractEngine.cc +++ b/src/foundation_pEp_jniadapter_AbstractEngine.cc @@ -164,7 +164,6 @@ PEP_STATUS notifyHandshake(pEp_identity *me, pEp_identity *partner, sync_handsha PEP_STATUS status = (PEP_STATUS) JNISync::env()->CallIntMethod(objj, notifyHandShakeMethodID, me_, partner_, signal_); if (JNISync::env()->ExceptionCheck()) { - JNISync::env()->Throw(JNISync::env()->ExceptionOccurred()); JNISync::env()->ExceptionClear(); return PEP_UNKNOWN_ERROR; } From 12fa07bc4aec21047851cab8c5f10772ba850b4a Mon Sep 17 00:00:00 2001 From: heck Date: Wed, 8 Jul 2020 02:35:17 +0200 Subject: [PATCH 08/22] Passphrase retry after application callback (callback still dummy, but works). For ALL "cached" methods :) --- src/gen_cpp_Engine.ysl2 | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/gen_cpp_Engine.ysl2 b/src/gen_cpp_Engine.ysl2 index 669504b..abfa6ac 100644 --- a/src/gen_cpp_Engine.ysl2 +++ b/src/gen_cpp_Engine.ysl2 @@ -68,8 +68,31 @@ tstylesheet { choose { when "@cached = 'true'" { || - pEpLog("cached passphrase"); - PEP_STATUS status = passphrase_cache.api(::«@name»,session()`apply "parm", mode=call`); + pEpLog("cached passphrase mode"); + bool retryAfterCallback = false; + int maxRetries = 3; + int retryCount = 0; + PEP_STATUS status; + do { + // the actual target function + status = passphrase_cache.api(::«@name»,session()`apply "parm", mode=call`); + + if(status == PEP_PASSPHRASE_REQUIRED || PEP_WRONG_PASSPHRASE ) { + pEpLog("PassReq OR Wrong"); + // call the app + const char * _passphrase = "passphrase_alice"; + PEP_STATUS status = ::config_passphrase(session(),passphrase_cache.add(_passphrase)); + retryCount++; + if(retryCount > maxRetries) { + retryAfterCallback = false; + } else { + retryAfterCallback = true; + } + } else { + retryAfterCallback = false; + } + } while (retryAfterCallback); + || } otherwise { || From 9b949e7f2876a0e110f20bbbdb3a6f75ca353e3c Mon Sep 17 00:00:00 2001 From: heck Date: Wed, 8 Jul 2020 02:44:54 +0200 Subject: [PATCH 09/22] Test case added, importKey(), setOwnKey(), NO config_passphrase(), THEN encryptMessage(). (No callback yet) --- .../pEp/jniadapter/test/jni114/Makefile | 37 ++++++++++++++ .../pEp/jniadapter/test/jni114/TestAlice.java | 48 +++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 test/java/foundation/pEp/jniadapter/test/jni114/Makefile create mode 100644 test/java/foundation/pEp/jniadapter/test/jni114/TestAlice.java diff --git a/test/java/foundation/pEp/jniadapter/test/jni114/Makefile b/test/java/foundation/pEp/jniadapter/test/jni114/Makefile new file mode 100644 index 0000000..5180dc1 --- /dev/null +++ b/test/java/foundation/pEp/jniadapter/test/jni114/Makefile @@ -0,0 +1,37 @@ +include ../../../../../../../Makefile.conf +include ../Makefile.conf + +TEST_UNIT_NAME=jni114 + +JAVA_CLASSES = \ + TestAlice.class \ + ../utils/AdapterBaseTestContext.class \ + ../utils/AdapterTestUtils.class \ + ../utils/TestCallbacks.class + +.PHONY: pitytest compile alice test clean + +all: alice compile + +pitytest: + $(MAKE) -C $(PITYTEST_DIR) + +alice: compile clean-pep-home-alice + cd $(JAVA_CWD);pwd;HOME=$(JAVA_PEP_HOME_DIR_ALICE) $(JAVA) $(JAVA_PKG_BASENAME).$(TEST_UNIT_NAME).TestAlice + +compile: $(JAVA_CLASSES) pitytest + +%.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: clean-pep-home-alice + +clean-pep-home-alice: + rm -rf $(PEP_HOME_DIR_ALICE)/.pEp diff --git a/test/java/foundation/pEp/jniadapter/test/jni114/TestAlice.java b/test/java/foundation/pEp/jniadapter/test/jni114/TestAlice.java new file mode 100644 index 0000000..7ec8242 --- /dev/null +++ b/test/java/foundation/pEp/jniadapter/test/jni114/TestAlice.java @@ -0,0 +1,48 @@ +package foundation.pEp.jniadapter.test.jni114; + +import static foundation.pEp.pitytest.TestLogger.*; +import static foundation.pEp.pitytest.utils.TestUtils.readKey; + +import foundation.pEp.jniadapter.*; +import foundation.pEp.pitytest.*; +import foundation.pEp.pitytest.utils.TestUtils; +import foundation.pEp.jniadapter.test.utils.*; + +import java.util.Vector; + + +// https://pep.foundation/jira/browse/JNI-111 + +class JNI114TestContext extends AdapterBaseTestContext { + @Override + public void init() throws Throwable { + super.init(); + alice = null; + bob = null; + } +} + +class TestAlice { + public static void main(String[] args) throws Exception { +// readKey(); + TestSuite.getDefault().setVerbose(true); + TestSuite.getDefault().setTestColor(TestUtils.TermColor.GREEN); + + AdapterBaseTestContext jni111Ctx = new JNI114TestContext(); + + new TestUnit("importKey()", jni111Ctx, ctx -> { + ctx.alice = ctx.engine.importKey(ctx.keyAliceSecPassphrase).get(0); + log(AdapterTestUtils.identityToString(ctx.alice, true)); + ctx.alice.user_id = "23"; + ctx.alice = ctx.engine.setOwnKey(ctx.alice, ctx.alice.fpr); + log(AdapterTestUtils.identityToString(ctx.alice, true)); + + Message enc = ctx.engine.encrypt_message(ctx.msgToSelf, new Vector<>(), Message.EncFormat.PEP); + log(AdapterTestUtils.msgToString(enc, false)); +// ctx.engine.startSync(); + + }); + + TestSuite.getDefault().run(); + } +} \ No newline at end of file From 7c7a8f4121efe6ff4636bb2e42849f4b7459e58b Mon Sep 17 00:00:00 2001 From: heck Date: Wed, 8 Jul 2020 03:15:15 +0200 Subject: [PATCH 10/22] Improved retry code / now passphrase from AbstractEngine level. --- ...oundation_pEp_jniadapter_AbstractEngine.cc | 6 ++++ src/gen_cpp_Engine.ysl2 | 33 +++++++++++-------- src/passphrase_callback.hh | 9 +++++ 3 files changed, 34 insertions(+), 14 deletions(-) create mode 100644 src/passphrase_callback.hh diff --git a/src/foundation_pEp_jniadapter_AbstractEngine.cc b/src/foundation_pEp_jniadapter_AbstractEngine.cc index 3db137c..bde852c 100644 --- a/src/foundation_pEp_jniadapter_AbstractEngine.cc +++ b/src/foundation_pEp_jniadapter_AbstractEngine.cc @@ -9,6 +9,7 @@ #include #include "throw_pEp_exception.hh" #include "jniutils.hh" +#include "passphrase_callback.hh" namespace pEp { using namespace pEp::JNIAdapter; @@ -91,6 +92,11 @@ void jni_init() { field_value = JNISync::env()->GetFieldID(signalClass, "value", "I"); } +char* JNIAdapter::passphraseRequiredCallback() { + pEpLog("called"); + return "passphrase_alice"; +} + PEP_STATUS messageToSend(message *msg) { std::lock_guard l(mutex_obj); diff --git a/src/gen_cpp_Engine.ysl2 b/src/gen_cpp_Engine.ysl2 index abfa6ac..7dd15d9 100644 --- a/src/gen_cpp_Engine.ysl2 +++ b/src/gen_cpp_Engine.ysl2 @@ -14,10 +14,12 @@ tstylesheet { #include #include #include + #include + #include "foundation_pEp_jniadapter_«@name».h" #include "throw_pEp_exception.hh" #include "jniutils.hh" - #include + #include "passphrase_callback.hh" using pEp::Adapter::session; using pEp::passphrase_cache; @@ -69,29 +71,32 @@ tstylesheet { when "@cached = 'true'" { || pEpLog("cached passphrase mode"); - bool retryAfterCallback = false; + bool retryAgain = false; int maxRetries = 3; int retryCount = 0; PEP_STATUS status; do { // the actual target function + pEpLog("calling passphrase_cache.api(::«@name»())"); status = passphrase_cache.api(::«@name»,session()`apply "parm", mode=call`); - - if(status == PEP_PASSPHRASE_REQUIRED || PEP_WRONG_PASSPHRASE ) { - pEpLog("PassReq OR Wrong"); - // call the app - const char * _passphrase = "passphrase_alice"; - PEP_STATUS status = ::config_passphrase(session(),passphrase_cache.add(_passphrase)); - retryCount++; - if(retryCount > maxRetries) { - retryAfterCallback = false; + pEpLog("PEP_STATUS:" << status); + if(status == PEP_PASSPHRASE_REQUIRED || status == PEP_WRONG_PASSPHRASE ) { + pEpLog("none of the cached passphrases worked"); + if(retryCount < maxRetries) { + // call the app + char* _passphrase = passphraseRequiredCallback(); + pEpLog("callback returned, config_passphrase() with new passphrase"); + PEP_STATUS status = ::config_passphrase(session(),passphrase_cache.add(_passphrase)); + retryAgain = true; + retryCount++; } else { - retryAfterCallback = true; + pEpLog("max retries reached:" << maxRetries); + retryAgain = false; } } else { - retryAfterCallback = false; + retryAgain = false; } - } while (retryAfterCallback); + } while (retryAgain); || } otherwise { diff --git a/src/passphrase_callback.hh b/src/passphrase_callback.hh new file mode 100644 index 0000000..357b2c6 --- /dev/null +++ b/src/passphrase_callback.hh @@ -0,0 +1,9 @@ + + +namespace pEp { + namespace JNIAdapter { + + char* passphraseRequiredCallback(); + + }; +}; \ No newline at end of file From 095eb8075b9314475b2d855653bbbb805e08c17c Mon Sep 17 00:00:00 2001 From: heck Date: Wed, 8 Jul 2020 04:10:01 +0200 Subject: [PATCH 11/22] JNI code done, now passphrase comes from java level throug callback --- .../pEp/jniadapter/AbstractEngine.java | 4 ++++ ...oundation_pEp_jniadapter_AbstractEngine.cc | 22 ++++++++++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/foundation/pEp/jniadapter/AbstractEngine.java b/src/foundation/pEp/jniadapter/AbstractEngine.java index 323461a..4b0fffe 100644 --- a/src/foundation/pEp/jniadapter/AbstractEngine.java +++ b/src/foundation/pEp/jniadapter/AbstractEngine.java @@ -186,6 +186,10 @@ abstract class AbstractEngine extends UniquelyIdentifiable implements AutoClosea return 0; } + public byte[] passphraseRequiredFromC() { + return toUTF8("passphrase_alice"); + } + public int messageToSendCallFromC (Message message) { System.out.println("pEpSync" + "messageToSendCallFromC: " + messageToSendCallback ); if (messageToSendCallback != null) { diff --git a/src/foundation_pEp_jniadapter_AbstractEngine.cc b/src/foundation_pEp_jniadapter_AbstractEngine.cc index bde852c..e2a26d4 100644 --- a/src/foundation_pEp_jniadapter_AbstractEngine.cc +++ b/src/foundation_pEp_jniadapter_AbstractEngine.cc @@ -26,6 +26,7 @@ jmethodID messageConstructorMethodID = nullptr; jmethodID messageToSendMethodID = nullptr; jmethodID notifyHandShakeMethodID = nullptr; jmethodID needsFastPollMethodID = nullptr; +jmethodID passphraseRequiredMethodID = nullptr; jmethodID method_values = nullptr; jobject objj = nullptr; @@ -86,6 +87,10 @@ void jni_init() { engineClass, "notifyHandshakeCallFromC", "(Lfoundation/pEp/jniadapter/_Identity;Lfoundation/pEp/jniadapter/_Identity;Lfoundation/pEp/jniadapter/SyncHandshakeSignal;)I"); + passphraseRequiredMethodID = _env->GetMethodID( + engineClass, + "passphraseRequiredFromC", + "()[B"); method_values = JNISync::env()->GetStaticMethodID(signalClass, "values", "()[Lfoundation/pEp/jniadapter/SyncHandshakeSignal;"); @@ -94,7 +99,22 @@ void jni_init() { char* JNIAdapter::passphraseRequiredCallback() { pEpLog("called"); - return "passphrase_alice"; + + assert(objj && passphraseRequiredMethodID); + + jobject ppJO = JNISync::env()->CallObjectMethod(objj, passphraseRequiredMethodID); + if (JNISync::env()->ExceptionCheck()) { + JNISync::env()->ExceptionDescribe(); + JNISync::env()->ExceptionClear(); + } + + jbyteArray ppJBA = reinterpret_cast(ppJO); + char* passphrase_ = to_string( JNISync::env(), ppJBA); + + pEpLog("fromJava: " << passphrase_); + JNISync::env()->DeleteLocalRef(ppJO); + + return passphrase_; } PEP_STATUS messageToSend(message *msg) From 64e12d777473c0f65813cc1c493f1d618694d8a4 Mon Sep 17 00:00:00 2001 From: heck Date: Wed, 8 Jul 2020 04:27:04 +0200 Subject: [PATCH 12/22] Java register callback method "Engine.setPassphraseRequired()" done and tested. --- src/foundation/pEp/jniadapter/AbstractEngine.java | 14 +++++++++++++- src/foundation/pEp/jniadapter/Sync.java | 3 +++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/foundation/pEp/jniadapter/AbstractEngine.java b/src/foundation/pEp/jniadapter/AbstractEngine.java index 4b0fffe..137fee2 100644 --- a/src/foundation/pEp/jniadapter/AbstractEngine.java +++ b/src/foundation/pEp/jniadapter/AbstractEngine.java @@ -16,6 +16,7 @@ abstract class AbstractEngine extends UniquelyIdentifiable implements AutoClosea private Sync.MessageToSendCallback messageToSendCallback; private Sync.NotifyHandshakeCallback notifyHandshakeCallback; private Sync.NeedsFastPollCallback needsFastPollCallback; + private Sync.PassphraseRequiredCallback passphraseRequiredCallback; private final static DefaultCallback defaultCallback = new DefaultCallback(); @@ -164,6 +165,10 @@ abstract class AbstractEngine extends UniquelyIdentifiable implements AutoClosea this.needsFastPollCallback = needsFastPollCallback; } + public void setPassphraseRequiredCallback(Sync.PassphraseRequiredCallback passphraseRequiredCallback) { + this.passphraseRequiredCallback = passphraseRequiredCallback; + } + public int needsFastPollCallFromC(boolean fast_poll_needed) { if (needsFastPollCallback != null) { needsFastPollCallback.needsFastPollCallFromC(fast_poll_needed); @@ -187,7 +192,14 @@ abstract class AbstractEngine extends UniquelyIdentifiable implements AutoClosea } public byte[] passphraseRequiredFromC() { - return toUTF8("passphrase_alice"); + String ret = ""; + if (passphraseRequiredCallback != null) { + ret = passphraseRequiredCallback.passphraseRequired(); + } else { + // should never happen + assert false: "passphraseRequiredFromC called without callback registered"; + } + return toUTF8(ret); } public int messageToSendCallFromC (Message message) { diff --git a/src/foundation/pEp/jniadapter/Sync.java b/src/foundation/pEp/jniadapter/Sync.java index 685ba0d..e83211e 100644 --- a/src/foundation/pEp/jniadapter/Sync.java +++ b/src/foundation/pEp/jniadapter/Sync.java @@ -19,6 +19,9 @@ public interface Sync { void notifyHandshake(Identity myself, Identity partner, SyncHandshakeSignal signal); } + interface PassphraseRequiredCallback { + String passphraseRequired(); + } public class DefaultCallback implements Sync.MessageToSendCallback, Sync.NotifyHandshakeCallback, Sync.NeedsFastPollCallback { From 70f90f61b6817e81714ceb9132070efde978813b Mon Sep 17 00:00:00 2001 From: heck Date: Wed, 8 Jul 2020 04:27:41 +0200 Subject: [PATCH 13/22] Tests updated, now using the new callback to provide the passphrase --- .../pEp/jniadapter/test/jni114/TestAlice.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/test/java/foundation/pEp/jniadapter/test/jni114/TestAlice.java b/test/java/foundation/pEp/jniadapter/test/jni114/TestAlice.java index 7ec8242..30464e0 100644 --- a/test/java/foundation/pEp/jniadapter/test/jni114/TestAlice.java +++ b/test/java/foundation/pEp/jniadapter/test/jni114/TestAlice.java @@ -19,7 +19,10 @@ class JNI114TestContext extends AdapterBaseTestContext { super.init(); alice = null; bob = null; + + } + } class TestAlice { @@ -31,15 +34,26 @@ class TestAlice { AdapterBaseTestContext jni111Ctx = new JNI114TestContext(); new TestUnit("importKey()", jni111Ctx, ctx -> { + // Register callback passphraseRequired() + ctx.engine.setPassphraseRequiredCallback(new Sync.PassphraseRequiredCallback() { + @Override + public String passphraseRequired() { + log("passphraseRequired() called"); + return "passphrase_alice"; + } + }); + + // ImportKey and setOwnKey (with passphrase, of course) ctx.alice = ctx.engine.importKey(ctx.keyAliceSecPassphrase).get(0); log(AdapterTestUtils.identityToString(ctx.alice, true)); ctx.alice.user_id = "23"; ctx.alice = ctx.engine.setOwnKey(ctx.alice, ctx.alice.fpr); log(AdapterTestUtils.identityToString(ctx.alice, true)); + // Encrypt Message enc = ctx.engine.encrypt_message(ctx.msgToSelf, new Vector<>(), Message.EncFormat.PEP); log(AdapterTestUtils.msgToString(enc, false)); -// ctx.engine.startSync(); + }); From 282cbf437dd6ff635a4aec8bb7f8ed2877df2631 Mon Sep 17 00:00:00 2001 From: heck Date: Wed, 8 Jul 2020 05:19:53 +0200 Subject: [PATCH 14/22] Tests updated, encrypt fails, then register callback, encrypt success after callback returned the correct passphrase --- .../pEp/jniadapter/test/jni114/TestAlice.java | 54 ++++++++++++------- 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/test/java/foundation/pEp/jniadapter/test/jni114/TestAlice.java b/test/java/foundation/pEp/jniadapter/test/jni114/TestAlice.java index 30464e0..cc09858 100644 --- a/test/java/foundation/pEp/jniadapter/test/jni114/TestAlice.java +++ b/test/java/foundation/pEp/jniadapter/test/jni114/TestAlice.java @@ -2,6 +2,7 @@ package foundation.pEp.jniadapter.test.jni114; import static foundation.pEp.pitytest.TestLogger.*; import static foundation.pEp.pitytest.utils.TestUtils.readKey; +import static foundation.pEp.pitytest.utils.TestUtils.sleep; import foundation.pEp.jniadapter.*; import foundation.pEp.pitytest.*; @@ -13,17 +14,6 @@ import java.util.Vector; // https://pep.foundation/jira/browse/JNI-111 -class JNI114TestContext extends AdapterBaseTestContext { - @Override - public void init() throws Throwable { - super.init(); - alice = null; - bob = null; - - - } - -} class TestAlice { public static void main(String[] args) throws Exception { @@ -31,32 +21,56 @@ class TestAlice { TestSuite.getDefault().setVerbose(true); TestSuite.getDefault().setTestColor(TestUtils.TermColor.GREEN); - AdapterBaseTestContext jni111Ctx = new JNI114TestContext(); + AdapterBaseTestContext jni114Ctx = new AdapterBaseTestContext(); + new TestUnit("ImportKey/SetOwnKey", jni114Ctx, ctx -> { + // ImportKey and setOwnKey (with passphrase, of course) + ctx.alice = ctx.engine.importKey(ctx.keyAliceSecPassphrase).get(0); + log(AdapterTestUtils.identityToString(ctx.alice, true)); + ctx.alice.user_id = "23"; + ctx.alice = ctx.engine.setOwnKey(ctx.alice, ctx.alice.fpr); + assert ctx.alice != null : "Keyimport failed"; + assert ctx.alice.me == true; + assert ctx.alice.comm_type == CommType.PEP_ct_pEp; + }); + - new TestUnit("importKey()", jni111Ctx, ctx -> { + new TestUnit("no callback / encrypt fails nonblocking", jni114Ctx, ctx -> { + ctx.alice = ctx.engine.myself(ctx.alice); + try { + Message enc = ctx.engine.encrypt_message(ctx.msgToSelf, new Vector<>(), Message.EncFormat.PEP); + } catch (pEpException e) { + assert e instanceof pEpPassphraseRequired : "wrong exception type"; + return; + } + assert false : "encrypt_message() should have failed"; + }); + + + new TestUnit("use callback for encrypt", jni114Ctx, ctx -> { // Register callback passphraseRequired() ctx.engine.setPassphraseRequiredCallback(new Sync.PassphraseRequiredCallback() { @Override public String passphraseRequired() { log("passphraseRequired() called"); + log("Please Enter Passphrase..."); + sleep(2000); return "passphrase_alice"; } }); - // ImportKey and setOwnKey (with passphrase, of course) - ctx.alice = ctx.engine.importKey(ctx.keyAliceSecPassphrase).get(0); - log(AdapterTestUtils.identityToString(ctx.alice, true)); - ctx.alice.user_id = "23"; - ctx.alice = ctx.engine.setOwnKey(ctx.alice, ctx.alice.fpr); + // myself + ctx.alice = ctx.engine.myself(ctx.alice); log(AdapterTestUtils.identityToString(ctx.alice, true)); // Encrypt + assert ctx.msgToSelf.getEncFormat() == Message.EncFormat.None : "Orig msg not plain"; Message enc = ctx.engine.encrypt_message(ctx.msgToSelf, new Vector<>(), Message.EncFormat.PEP); + assert enc.getEncFormat() == Message.EncFormat.PGPMIME : "Message not encrypted"; + assert !enc.getLongmsg().contains(ctx.msgToSelf.getLongmsg()) : "Message not encrypted"; log(AdapterTestUtils.msgToString(enc, false)); - - }); + TestSuite.getDefault().run(); } } \ No newline at end of file From 0240fafedb8db900aa01380f724819abb720f9cf Mon Sep 17 00:00:00 2001 From: heck Date: Wed, 8 Jul 2020 05:21:54 +0200 Subject: [PATCH 15/22] Avoid retry if callback not set is still ...dirty. the commit comment goes on, REMEMBER TO USE hg log -v now and then again :) // if this happens (no callback registered // we simply return "" // it will fail // this repeats MaxRetries times (currentluy hardcoded to 3) // Then the orig call will return with the PEP_STATUS (most likely PEP_PASSPHRASE_REQUIRED) --- src/foundation/pEp/jniadapter/AbstractEngine.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/foundation/pEp/jniadapter/AbstractEngine.java b/src/foundation/pEp/jniadapter/AbstractEngine.java index 137fee2..92adbd2 100644 --- a/src/foundation/pEp/jniadapter/AbstractEngine.java +++ b/src/foundation/pEp/jniadapter/AbstractEngine.java @@ -166,6 +166,8 @@ abstract class AbstractEngine extends UniquelyIdentifiable implements AutoClosea } public void setPassphraseRequiredCallback(Sync.PassphraseRequiredCallback passphraseRequiredCallback) { + System.out.println("passphraseRequiredCallback has been registered to:" + passphraseRequiredCallback.toString() + " on engine ObjID: " + getId()); + this.passphraseRequiredCallback = passphraseRequiredCallback; } @@ -194,10 +196,15 @@ abstract class AbstractEngine extends UniquelyIdentifiable implements AutoClosea public byte[] passphraseRequiredFromC() { String ret = ""; if (passphraseRequiredCallback != null) { + System.out.println("calling passphraseRequiredCallback on engine ObjID:" + getId()); ret = passphraseRequiredCallback.passphraseRequired(); } else { - // should never happen - assert false: "passphraseRequiredFromC called without callback registered"; + System.out.println("no callback registered on engine ObjID:" + getId()); + // if this happens (no callback registered + // we simply return "" + // it will fail + // this repeats MaxRetries times (currentluy hardcoded to 3) + // Then the orig call will return with the PEP_STATUS (most likely PEP_PASSPHRASE_REQUIRED) } return toUTF8(ret); } From fc06f8257ba53927bc7dce8e6d6ef32482d55672 Mon Sep 17 00:00:00 2001 From: heck Date: Wed, 8 Jul 2020 23:02:11 +0200 Subject: [PATCH 18/22] delete DeleteLocalRef() --- src/foundation_pEp_jniadapter_AbstractEngine.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/foundation_pEp_jniadapter_AbstractEngine.cc b/src/foundation_pEp_jniadapter_AbstractEngine.cc index e2a26d4..65dd6ad 100644 --- a/src/foundation_pEp_jniadapter_AbstractEngine.cc +++ b/src/foundation_pEp_jniadapter_AbstractEngine.cc @@ -112,7 +112,7 @@ char* JNIAdapter::passphraseRequiredCallback() { char* passphrase_ = to_string( JNISync::env(), ppJBA); pEpLog("fromJava: " << passphrase_); - JNISync::env()->DeleteLocalRef(ppJO); +// JNISync::env()->DeleteLocalRef(ppJO); return passphrase_; } From 7b5b55b27bb7327a3052bd8ed7cbcc85151b5732 Mon Sep 17 00:00:00 2001 From: heck Date: Wed, 8 Jul 2020 23:45:31 +0200 Subject: [PATCH 21/22] nothing for default branch... --- src/foundation_pEp_jniadapter_AbstractEngine.cc | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/foundation_pEp_jniadapter_AbstractEngine.cc b/src/foundation_pEp_jniadapter_AbstractEngine.cc index 65dd6ad..ce5edff 100644 --- a/src/foundation_pEp_jniadapter_AbstractEngine.cc +++ b/src/foundation_pEp_jniadapter_AbstractEngine.cc @@ -111,9 +111,6 @@ char* JNIAdapter::passphraseRequiredCallback() { jbyteArray ppJBA = reinterpret_cast(ppJO); char* passphrase_ = to_string( JNISync::env(), ppJBA); - pEpLog("fromJava: " << passphrase_); -// JNISync::env()->DeleteLocalRef(ppJO); - return passphrase_; }