aboutsummaryrefslogtreecommitdiff
path: root/android/olm-sdk/src
diff options
context:
space:
mode:
authorHubert Chathi <hubert@uhoreg.ca>2019-03-13 22:43:56 -0400
committerHubert Chathi <hubert@uhoreg.ca>2019-03-20 10:32:53 -0400
commit2f2a19f2e7f3522cdb80031f980f8b4c1356b2f1 (patch)
treec2245b9c121f68b19f601263147ba2b1446af243 /android/olm-sdk/src
parent0348f06a5692f168f2d0d8b77aac81ebb31e2df6 (diff)
add Android bindings for PK signing
Diffstat (limited to 'android/olm-sdk/src')
-rw-r--r--android/olm-sdk/src/androidTest/java/org/matrix/olm/OlmPkTest.java63
-rw-r--r--android/olm-sdk/src/main/java/org/matrix/olm/OlmException.java7
-rw-r--r--android/olm-sdk/src/main/jni/olm_jni.h3
-rw-r--r--android/olm-sdk/src/main/jni/olm_jni_helper.cpp7
-rw-r--r--android/olm-sdk/src/main/jni/olm_jni_helper.h3
-rw-r--r--android/olm-sdk/src/main/jni/olm_pk.cpp278
-rw-r--r--android/olm-sdk/src/main/jni/olm_pk.h10
7 files changed, 364 insertions, 7 deletions
diff --git a/android/olm-sdk/src/androidTest/java/org/matrix/olm/OlmPkTest.java b/android/olm-sdk/src/androidTest/java/org/matrix/olm/OlmPkTest.java
index 29f6946..d1e4a2e 100644
--- a/android/olm-sdk/src/androidTest/java/org/matrix/olm/OlmPkTest.java
+++ b/android/olm-sdk/src/androidTest/java/org/matrix/olm/OlmPkTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 New Vector Ltd
+ * Copyright 2018,2019 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -39,6 +39,7 @@ public class OlmPkTest {
private static OlmPkEncryption mOlmPkEncryption;
private static OlmPkDecryption mOlmPkDecryption;
+ private static OlmPkSigning mOlmPkSigning;
@Test
public void test01EncryptAndDecrypt() {
@@ -137,4 +138,64 @@ public class OlmPkTest {
mOlmPkDecryption.releaseDecryption();
assertTrue(mOlmPkDecryption.isReleased());
}
+
+ @Test
+ public void test03Signing() {
+ try {
+ mOlmPkSigning = new OlmPkSigning();
+ } catch (OlmException e) {
+ e.printStackTrace();
+ assertTrue("OlmPkSigning failed " + e.getMessage(), false);
+ }
+
+ assertNotNull(mOlmPkSigning);
+
+ byte[] seed = null;
+ try {
+ seed = OlmPkSigning.generateSeed();
+ } catch (OlmException e) {
+ e.printStackTrace();
+ assertTrue("generateSeed failed " + e.getMessage(), false);
+ }
+
+ assertTrue(seed.length == OlmPkSigning.seedLength());
+
+ String pubkey = null;
+ try {
+ pubkey = mOlmPkSigning.initWithSeed(seed);
+ } catch (OlmException e) {
+ e.printStackTrace();
+ assertTrue("initWithSeed failed " + e.getMessage(), false);
+ }
+
+ String message = "We hold these truths to be self-evident, that all men are created equal, that they are endowed by their Creator with certain unalienable Rights, that among these are Life, Liberty and the pursuit of Happiness.";
+
+ String signature = null;
+ try {
+ signature = mOlmPkSigning.sign(message);
+ } catch (OlmException e) {
+ e.printStackTrace();
+ assertTrue("sign failed " + e.getMessage(), false);
+ }
+
+ OlmUtility olmUtility = null;
+ try {
+ olmUtility = new OlmUtility();
+ } catch (OlmException e) {
+ e.printStackTrace();
+ assertTrue("olmUtility failed " + e.getMessage(), false);
+ }
+
+ try {
+ olmUtility.verifyEd25519Signature(signature, pubkey, message);
+ } catch (OlmException e) {
+ e.printStackTrace();
+ assertTrue("Signature verification failed " + e.getMessage(), false);
+ }
+
+ mOlmPkSigning.releaseSigning();
+ assertTrue(mOlmPkSigning.isReleased());
+
+ olmUtility.releaseUtility();
+ }
}
diff --git a/android/olm-sdk/src/main/java/org/matrix/olm/OlmException.java b/android/olm-sdk/src/main/java/org/matrix/olm/OlmException.java
index 5b534d5..532f318 100644
--- a/android/olm-sdk/src/main/java/org/matrix/olm/OlmException.java
+++ b/android/olm-sdk/src/main/java/org/matrix/olm/OlmException.java
@@ -1,6 +1,6 @@
/*
* Copyright 2017 OpenMarket Ltd
- * Copyright 2017 Vector Creations Ltd
+ * Copyright 2017-2019 Vector Creations Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -71,6 +71,11 @@ public class OlmException extends IOException {
public static final int EXCEPTION_CODE_PK_DECRYPTION_SET_PRIVATE_KEY = 703;
public static final int EXCEPTION_CODE_PK_DECRYPTION_PRIVATE_KEY = 704;
+ public static final int EXCEPTION_CODE_PK_SIGNING_CREATION = 800;
+ public static final int EXCEPTION_CODE_PK_SIGNING_GENERATE_SEED = 801;
+ public static final int EXCEPTION_CODE_PK_SIGNING_INIT_WITH_SEED = 802;
+ public static final int EXCEPTION_CODE_PK_SIGNING_SIGN = 803;
+
// exception human readable messages
public static final String EXCEPTION_MSG_INVALID_PARAMS_DESERIALIZATION = "invalid de-serialized parameters";
diff --git a/android/olm-sdk/src/main/jni/olm_jni.h b/android/olm-sdk/src/main/jni/olm_jni.h
index bc2bdae..0a50c5f 100644
--- a/android/olm-sdk/src/main/jni/olm_jni.h
+++ b/android/olm-sdk/src/main/jni/olm_jni.h
@@ -1,6 +1,6 @@
/*
* Copyright 2016 OpenMarket Ltd
- * Copyright 2016 Vector Creations Ltd
+ * Copyright 2016,2018,2019 Vector Creations Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -72,6 +72,7 @@ struct OlmOutboundGroupSession* getOutboundGroupSessionInstanceId(JNIEnv* aJniEn
struct OlmUtility* getUtilityInstanceId(JNIEnv* aJniEnv, jobject aJavaObject);
struct OlmPkDecryption* getPkDecryptionInstanceId(JNIEnv* aJniEnv, jobject aJavaObject);
struct OlmPkEncryption* getPkEncryptionInstanceId(JNIEnv* aJniEnv, jobject aJavaObject);
+struct OlmPkSigning* getPkSigningInstanceId(JNIEnv* aJniEnv, jobject aJavaObject);
#ifdef __cplusplus
}
diff --git a/android/olm-sdk/src/main/jni/olm_jni_helper.cpp b/android/olm-sdk/src/main/jni/olm_jni_helper.cpp
index 1997334..f13c5e1 100644
--- a/android/olm-sdk/src/main/jni/olm_jni_helper.cpp
+++ b/android/olm-sdk/src/main/jni/olm_jni_helper.cpp
@@ -1,6 +1,6 @@
/*
* Copyright 2016 OpenMarket Ltd
- * Copyright 2016 Vector Creations Ltd
+ * Copyright 2016,2018,2019 Vector Creations Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -222,3 +222,8 @@ struct OlmPkEncryption* getPkEncryptionInstanceId(JNIEnv* aJniEnv, jobject aJava
{
return (struct OlmPkEncryption*)getInstanceId(aJniEnv, aJavaObject, CLASS_OLM_PK_ENCRYPTION);
}
+
+struct OlmPkSigning* getPkSigningInstanceId(JNIEnv* aJniEnv, jobject aJavaObject)
+{
+ return (struct OlmPkSigning*)getInstanceId(aJniEnv, aJavaObject, CLASS_OLM_PK_SIGNING);
+}
diff --git a/android/olm-sdk/src/main/jni/olm_jni_helper.h b/android/olm-sdk/src/main/jni/olm_jni_helper.h
index 9a23532..e9c03c8 100644
--- a/android/olm-sdk/src/main/jni/olm_jni_helper.h
+++ b/android/olm-sdk/src/main/jni/olm_jni_helper.h
@@ -1,6 +1,6 @@
/*
* Copyright 2016 OpenMarket Ltd
- * Copyright 2016 Vector Creations Ltd
+ * Copyright 2016,2018,2019 Vector Creations Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,4 +27,5 @@ namespace AndroidOlmSdk
static const char *CLASS_OLM_UTILITY = "org/matrix/olm/OlmUtility";
static const char *CLASS_OLM_PK_ENCRYPTION = "org/matrix/olm/OlmPkEncryption";
static const char *CLASS_OLM_PK_DECRYPTION = "org/matrix/olm/OlmPkDecryption";
+ static const char *CLASS_OLM_PK_SIGNING = "org/matrix/olm/OlmPkSigning";
}
diff --git a/android/olm-sdk/src/main/jni/olm_pk.cpp b/android/olm-sdk/src/main/jni/olm_pk.cpp
index cb1422a..c528342 100644
--- a/android/olm-sdk/src/main/jni/olm_pk.cpp
+++ b/android/olm-sdk/src/main/jni/olm_pk.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 New Vector Ltd
+ * Copyright 2018,2019 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -714,3 +714,279 @@ JNIEXPORT jbyteArray OLM_PK_DECRYPTION_FUNC_DEF(decryptJni)(
return decryptedMsgRet;
}
+
+OlmPkSigning * initializePkSigningMemory()
+{
+ size_t signingSize = olm_pk_signing_size();
+ OlmPkSigning *signingPtr = (OlmPkSigning *)malloc(signingSize);
+
+ if (signingPtr)
+ {
+ // init encryption object
+ signingPtr = olm_pk_signing(signingPtr);
+ LOGD(
+ "## initializePkSigningMemory(): success - OLM signing size=%lu",
+ static_cast<long unsigned int>(signingSize)
+ );
+ }
+ else
+ {
+ LOGE("## initializePkSigningMemory(): failure - OOM");
+ }
+
+ return signingPtr;
+}
+
+JNIEXPORT jlong OLM_PK_SIGNING_FUNC_DEF(createNewPkSigningJni)(JNIEnv *env, jobject thiz)
+{
+ const char* errorMessage = NULL;
+ OlmPkSigning *signingPtr = initializePkSigningMemory();
+
+ // init signing memory allocation
+ if (!signingPtr)
+ {
+ LOGE("## createNewPkSigningJni(): failure - init signing OOM");
+ errorMessage = "init signing OOM";
+ }
+ else
+ {
+ LOGD("## createNewPkSigningJni(): success - OLM signing created");
+ LOGD(
+ "## createNewPkSigningJni(): signingPtr=%p (jlong)(intptr_t)signingPtr=%lld",
+ signingPtr, (jlong)(intptr_t)signingPtr
+ );
+ }
+
+ if (errorMessage)
+ {
+ // release the allocated data
+ if (signingPtr)
+ {
+ olm_clear_pk_signing(signingPtr);
+ free(signingPtr);
+ }
+ env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage);
+ }
+
+ return (jlong)(intptr_t)signingPtr;
+}
+
+JNIEXPORT void OLM_PK_SIGNING_FUNC_DEF(releasePkSigningJni)(JNIEnv *env, jobject thiz)
+{
+ LOGD("## releasePkSigningJni(): IN");
+
+ OlmPkSigning* signingPtr = getPkSigningInstanceId(env, thiz);
+
+ if (!signingPtr)
+ {
+ LOGE(" ## releasePkSigningJni(): failure - invalid Signing ptr=NULL");
+ }
+ else
+ {
+ LOGD(" ## releasePkSigningJni(): signingPtr=%p", signingPtr);
+ olm_clear_pk_signing(signingPtr);
+
+ LOGD(" ## releasePkSigningJni(): IN");
+ // even if free(NULL) does not crash, logs are performed for debug
+ // purpose
+ free(signingPtr);
+ LOGD(" ## releasePkSigningJni(): OUT");
+ }
+}
+
+JNIEXPORT jbyteArray OLM_PK_SIGNING_FUNC_DEF(generateSeedJni)(JNIEnv *env, jobject thiz)
+{
+ size_t randomLength = olm_pk_signing_seed_length();
+ uint8_t *randomBuffPtr = NULL;
+ jbyteArray randomRet = 0;
+ const char* errorMessage = NULL;
+
+ if (!setRandomInBuffer(env, &randomBuffPtr, randomLength))
+ {
+ errorMessage = "random buffer init";
+ LOGE("## pkSigningGenerateSeedJni(): failure - %s", errorMessage);
+ }
+ else if (!(randomRet = env->NewByteArray(randomLength)))
+ {
+ errorMessage = "randomRet JNI allocation OOM";
+ LOGE(" ## pkSigningGenerateSeedJni(): falure - %s", errorMessage);
+ }
+ else
+ {
+ env->SetByteArrayRegion(
+ randomRet, 0, randomLength, (jbyte*)randomBuffPtr
+ );
+ }
+
+ if (randomBuffPtr)
+ {
+ memset(randomBuffPtr, 0, randomLength);
+ free(randomBuffPtr);
+ }
+
+ if (errorMessage)
+ {
+ env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage);
+ }
+
+ return randomRet;
+}
+
+JNIEXPORT jint OLM_PK_SIGNING_FUNC_DEF(seedLength)(JNIEnv *env, jobject thiz)
+{
+ return (jint) olm_pk_signing_seed_length();
+}
+
+JNIEXPORT jbyteArray OLM_PK_SIGNING_FUNC_DEF(setKeyFromSeedJni)(JNIEnv *env, jobject thiz, jbyteArray seed)
+{
+ const char* errorMessage = NULL;
+ OlmPkSigning *signingPtr = getPkSigningInstanceId(env, thiz);
+
+ jbyteArray publicKeyRet = 0;
+ jbyte *seedPtr = NULL;
+ jboolean seedWasCopied = JNI_FALSE;
+
+ if (!signingPtr)
+ {
+ errorMessage = "invalid Siging ptr=NULL";
+ LOGE(" ## setPkSigningKeyFromSeedJni(): failure - %s", errorMessage);
+ }
+ else if (!seed)
+ {
+ errorMessage = "invalid seed";
+ LOGE(" ## setPkSigningKeyFromSeedJni: failure - %s", errorMessage);
+ }
+ else if (!(seedPtr = env->GetByteArrayElements(seed, &seedWasCopied)))
+ {
+ errorMessage = "seed JNI allocation OOM";
+ LOGE(" ## setPkSigningKeyFromSeedJni(): failure - %s", errorMessage);
+ }
+ else
+ {
+ size_t publicKeyLength = olm_pk_signing_public_key_length();
+ uint8_t *publicKeyPtr = NULL;
+ size_t seedLength = (size_t)env->GetArrayLength(seed);
+ if (!(publicKeyPtr = (uint8_t*)malloc(publicKeyLength)))
+ {
+ errorMessage = "public key JNI allocation OOM";
+ LOGE(" ## setPkSigningKeyFromSeedJni(): falure - %s", errorMessage);
+ }
+ else
+ {
+ size_t returnValue = olm_pk_signing_key_from_seed(
+ signingPtr,
+ publicKeyPtr, publicKeyLength,
+ seedPtr, seedLength
+ );
+ if (returnValue == olm_error())
+ {
+ errorMessage = olm_pk_signing_last_error(signingPtr);
+ LOGE(" ## setPkSigningKeyFromSeedJni: failure - olm_pk_signing_key_from_seed Msg=%s", errorMessage);
+ }
+ else
+ {
+ if (!(publicKeyRet = env->NewByteArray(publicKeyLength))) {
+ errorMessage = "publicKeyRet JNI allocation OOM";
+ LOGE(" ## setPkSigningKeyFromSeedJni(): falure - %s", errorMessage);
+ } else {
+ env->SetByteArrayRegion(
+ publicKeyRet, 0, publicKeyLength, (jbyte*)publicKeyPtr
+ );
+ }
+ }
+ }
+ }
+
+ if (seedPtr)
+ {
+ if (seedWasCopied)
+ {
+ memset(seedPtr, 0, (size_t)env->GetArrayLength(seed));
+ }
+ env->ReleaseByteArrayElements(seed, seedPtr, JNI_ABORT);
+ }
+
+ if (errorMessage)
+ {
+ env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage);
+ }
+
+ return publicKeyRet;
+}
+
+JNIEXPORT jbyteArray OLM_PK_SIGNING_FUNC_DEF(pkSignJni)(JNIEnv *env, jobject thiz, jbyteArray aMessage)
+{
+ const char* errorMessage = NULL;
+ OlmPkSigning *signingPtr = getPkSigningInstanceId(env, thiz);
+
+ jbyteArray signatureRet = 0;
+ jbyte *messagePtr = NULL;
+ jboolean messageWasCopied = JNI_FALSE;
+
+ if (!signingPtr)
+ {
+ errorMessage = "invalid Siging ptr=NULL";
+ LOGE(" ## setPkSignJni(): failure - %s", errorMessage);
+ }
+ else if (!aMessage)
+ {
+ errorMessage = "message seed";
+ LOGE(" ## setPkSignJni: failure - %s", errorMessage);
+ }
+ else if (!(messagePtr = env->GetByteArrayElements(aMessage, &messageWasCopied)))
+ {
+ errorMessage = "message JNI allocation OOM";
+ LOGE(" ## setPkSignJni(): failure - %s", errorMessage);
+ }
+ else
+ {
+ size_t signatureLength = olm_pk_signature_length();
+ uint8_t *signaturePtr = NULL;
+ size_t messageLength = (size_t)env->GetArrayLength(aMessage);
+ if (!(signaturePtr = (uint8_t*)malloc(signatureLength)))
+ {
+ errorMessage = "signature JNI allocation OOM";
+ LOGE(" ## setPkSignJni(): falure - %s", errorMessage);
+ }
+ else
+ {
+ size_t returnValue = olm_pk_sign(
+ signingPtr,
+ (uint8_t *)messagePtr, messageLength,
+ signaturePtr, signatureLength
+ );
+ if (returnValue == olm_error())
+ {
+ errorMessage = olm_pk_signing_last_error(signingPtr);
+ LOGE(" ## setPkSignJni: failure - olm_pk_sign Msg=%s", errorMessage);
+ }
+ else
+ {
+ if (!(signatureRet = env->NewByteArray(signatureLength))) {
+ errorMessage = "signatureRet JNI allocation OOM";
+ LOGE(" ## setPkSignJni(): falure - %s", errorMessage);
+ } else {
+ env->SetByteArrayRegion(
+ signatureRet, 0, signatureLength, (jbyte*)signaturePtr
+ );
+ }
+ }
+ }
+ }
+
+ if (messagePtr)
+ {
+ if (messageWasCopied)
+ {
+ memset(messagePtr, 0, (size_t)env->GetArrayLength(aMessage));
+ }
+ env->ReleaseByteArrayElements(aMessage, messagePtr, JNI_ABORT);
+ }
+
+ if (errorMessage)
+ {
+ env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage);
+ }
+
+ return signatureRet;
+}
diff --git a/android/olm-sdk/src/main/jni/olm_pk.h b/android/olm-sdk/src/main/jni/olm_pk.h
index 2219699..7a577bb 100644
--- a/android/olm-sdk/src/main/jni/olm_pk.h
+++ b/android/olm-sdk/src/main/jni/olm_pk.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 New Vector Ltd
+ * Copyright 2018,2019 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,6 +22,7 @@
#define OLM_PK_ENCRYPTION_FUNC_DEF(func_name) FUNC_DEF(OlmPkEncryption,func_name)
#define OLM_PK_DECRYPTION_FUNC_DEF(func_name) FUNC_DEF(OlmPkDecryption,func_name)
+#define OLM_PK_SIGNING_FUNC_DEF(func_name) FUNC_DEF(OlmPkSigning,func_name)
#ifdef __cplusplus
extern "C" {
@@ -41,6 +42,13 @@ JNIEXPORT jbyteArray OLM_PK_DECRYPTION_FUNC_DEF(generateKeyJni)(JNIEnv *env, job
JNIEXPORT jbyteArray OLM_PK_DECRYPTION_FUNC_DEF(privateKeyJni)(JNIEnv *env, jobject thiz);
JNIEXPORT jbyteArray OLM_PK_DECRYPTION_FUNC_DEF(decryptJni)(JNIEnv *env, jobject thiz, jobject aEncryptedMsg);
+JNIEXPORT jlong OLM_PK_SIGNING_FUNC_DEF(createNewPkSigningJni)(JNIEnv *env, jobject thiz);
+JNIEXPORT void OLM_PK_SIGNING_FUNC_DEF(releasePkSigningJni)(JNIEnv *env, jobject thiz);
+JNIEXPORT jint OLM_PK_SIGNING_FUNC_DEF(seedLength)(JNIEnv *env, jobject thiz);
+JNIEXPORT jbyteArray OLM_PK_SIGNING_FUNC_DEF(generateSeedJni)(JNIEnv *env, jobject thiz);
+JNIEXPORT jbyteArray OLM_PK_SIGNING_FUNC_DEF(setKeyFromSeedJni)(JNIEnv *env, jobject thiz, jbyteArray seed);
+JNIEXPORT jbyteArray OLM_PK_SIGNING_FUNC_DEF(pkSignJni)(JNIEnv *env, jobject thiz, jbyteArray aMessage);
+
#ifdef __cplusplus
}
#endif