Merge pull request #83 from matrix-org/BillCarsonFr/java_sas
Java binding for SAS
This commit is contained in:
commit
c79d9282dc
9 changed files with 705 additions and 1 deletions
|
@ -0,0 +1,106 @@
|
||||||
|
/*
|
||||||
|
* Copyright 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.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.matrix.olm;
|
||||||
|
|
||||||
|
|
||||||
|
import android.support.test.runner.AndroidJUnit4;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.FixMethodOrder;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.junit.runners.MethodSorters;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4.class)
|
||||||
|
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||||
|
public class OlmSasTest {
|
||||||
|
|
||||||
|
private static OlmManager mOlmManager;
|
||||||
|
|
||||||
|
//Enable the native lib
|
||||||
|
@BeforeClass
|
||||||
|
public static void setUpClass() {
|
||||||
|
// load native librandomBytesOfLength
|
||||||
|
mOlmManager = new OlmManager();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSASCode() {
|
||||||
|
OlmSAS aliceSas = null;
|
||||||
|
OlmSAS bobSas = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
aliceSas = new OlmSAS();
|
||||||
|
bobSas = new OlmSAS();
|
||||||
|
|
||||||
|
String alicePKey = aliceSas.getPublicKey();
|
||||||
|
String bobPKey = bobSas.getPublicKey();
|
||||||
|
|
||||||
|
Log.e(OlmSasTest.class.getSimpleName(), "#### Alice pub Key is " + alicePKey);
|
||||||
|
Log.e(OlmSasTest.class.getSimpleName(), "#### Bob pub Key is " + bobPKey);
|
||||||
|
|
||||||
|
aliceSas.setTheirPublicKey(bobPKey);
|
||||||
|
bobSas.setTheirPublicKey(alicePKey);
|
||||||
|
|
||||||
|
int codeLength = 6;
|
||||||
|
byte[] alice_sas = aliceSas.generateShortCode("SAS", codeLength);
|
||||||
|
byte[] bob_sas = bobSas.generateShortCode("SAS", codeLength);
|
||||||
|
|
||||||
|
Log.e(OlmSasTest.class.getSimpleName(), "#### Alice SAS is " + new String(alice_sas, "UTF-8"));
|
||||||
|
Log.e(OlmSasTest.class.getSimpleName(), "#### Bob SAS is " + new String(bob_sas, "UTF-8"));
|
||||||
|
|
||||||
|
assertEquals(codeLength, alice_sas.length);
|
||||||
|
assertEquals(codeLength, bob_sas.length);
|
||||||
|
assertArrayEquals(alice_sas, bob_sas);
|
||||||
|
|
||||||
|
String aliceMac = aliceSas.calculateMac("Hello world!", "SAS");
|
||||||
|
String bobMac = bobSas.calculateMac("Hello world!", "SAS");
|
||||||
|
|
||||||
|
assertEquals(aliceMac, bobMac);
|
||||||
|
|
||||||
|
Log.e(OlmSasTest.class.getSimpleName(), "#### Alice Mac is " + aliceMac);
|
||||||
|
Log.e(OlmSasTest.class.getSimpleName(), "#### Bob Mac is " + bobMac);
|
||||||
|
|
||||||
|
|
||||||
|
String aliceLongKdfMac = aliceSas.calculateMacLongKdf("Hello world!", "SAS");
|
||||||
|
String bobLongKdfMac = bobSas.calculateMacLongKdf("Hello world!", "SAS");
|
||||||
|
|
||||||
|
assertEquals("Mac should be the same", aliceLongKdfMac, bobLongKdfMac);
|
||||||
|
|
||||||
|
Log.e(OlmSasTest.class.getSimpleName(), "#### Alice lkdf Mac is " + aliceLongKdfMac);
|
||||||
|
Log.e(OlmSasTest.class.getSimpleName(), "#### Bob lkdf Mac is " + bobLongKdfMac);
|
||||||
|
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
assertTrue("OlmSas init failed " + e.getMessage(), false);
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
if (aliceSas != null) {
|
||||||
|
aliceSas.releaseSas();
|
||||||
|
}
|
||||||
|
if (bobSas != null) {
|
||||||
|
bobSas.releaseSas();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -76,6 +76,11 @@ public class OlmException extends IOException {
|
||||||
public static final int EXCEPTION_CODE_PK_SIGNING_INIT_WITH_SEED = 802;
|
public static final int EXCEPTION_CODE_PK_SIGNING_INIT_WITH_SEED = 802;
|
||||||
public static final int EXCEPTION_CODE_PK_SIGNING_SIGN = 803;
|
public static final int EXCEPTION_CODE_PK_SIGNING_SIGN = 803;
|
||||||
|
|
||||||
|
public static final int EXCEPTION_CODE_SAS_CREATION = 900;
|
||||||
|
public static final int EXCEPTION_CODE_SAS_ERROR = 901;
|
||||||
|
public static final int EXCEPTION_CODE_SAS_MISSING_THEIR_PKEY = 902;
|
||||||
|
public static final int EXCEPTION_CODE_SAS_GENERATE_SHORT_CODE = 903;
|
||||||
|
|
||||||
// exception human readable messages
|
// exception human readable messages
|
||||||
public static final String EXCEPTION_MSG_INVALID_PARAMS_DESERIALIZATION = "invalid de-serialized parameters";
|
public static final String EXCEPTION_MSG_INVALID_PARAMS_DESERIALIZATION = "invalid de-serialized parameters";
|
||||||
|
|
||||||
|
|
153
android/olm-sdk/src/main/java/org/matrix/olm/OlmSAS.java
Normal file
153
android/olm-sdk/src/main/java/org/matrix/olm/OlmSAS.java
Normal file
|
@ -0,0 +1,153 @@
|
||||||
|
/*
|
||||||
|
* Copyright 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.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.matrix.olm;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
|
||||||
|
public class OlmSAS {
|
||||||
|
|
||||||
|
private static final String LOG_TAG = OlmSAS.class.getName();
|
||||||
|
/**
|
||||||
|
* Session Id returned by JNI.
|
||||||
|
* This value uniquely identifies the native SAS instance.
|
||||||
|
**/
|
||||||
|
private transient long mNativeId;
|
||||||
|
|
||||||
|
private String theirPublicKey = null;
|
||||||
|
|
||||||
|
public OlmSAS() throws OlmException {
|
||||||
|
try {
|
||||||
|
mNativeId = createNewSASJni();
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new OlmException(OlmException.EXCEPTION_CODE_SAS_CREATION, e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the Public Key encoded in Base64 with no padding
|
||||||
|
*/
|
||||||
|
public String getPublicKey() throws OlmException {
|
||||||
|
try {
|
||||||
|
byte[] buffer = getPubKeyJni();
|
||||||
|
|
||||||
|
if (null != buffer) {
|
||||||
|
return new String(buffer, "UTF-8");
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(LOG_TAG, "## sessionIdentifier(): " + e.getMessage());
|
||||||
|
throw new OlmException(OlmException.EXCEPTION_CODE_SAS_ERROR, e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the public key of other user.
|
||||||
|
*
|
||||||
|
* @param otherPkey other user public key (base64 encoded with no padding)
|
||||||
|
* @throws OlmException
|
||||||
|
*/
|
||||||
|
public void setTheirPublicKey(String otherPkey) throws OlmException {
|
||||||
|
try {
|
||||||
|
setTheirPubKey(otherPkey.getBytes("UTF-8"));
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
throw new OlmException(OlmException.EXCEPTION_CODE_SAS_ERROR, e.getMessage());
|
||||||
|
}
|
||||||
|
this.theirPublicKey = otherPkey;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate bytes to use for the short authentication string.
|
||||||
|
*
|
||||||
|
* @param info info extra information to mix in when generating the bytes, as
|
||||||
|
* per the Matrix spec.
|
||||||
|
* @param byteNumber The size of the short code to generate
|
||||||
|
* @return The generated shortcode
|
||||||
|
* @throws OlmException
|
||||||
|
*/
|
||||||
|
public byte[] generateShortCode(String info, int byteNumber) throws OlmException {
|
||||||
|
if (theirPublicKey == null || theirPublicKey.isEmpty()) {
|
||||||
|
throw new OlmException(OlmException.EXCEPTION_CODE_SAS_MISSING_THEIR_PKEY, "call setTheirPublicKey first");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return generateShortCodeJni(info.getBytes("UTF-8"), byteNumber);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(LOG_TAG, "## sessionIdentifier(): " + e.getMessage());
|
||||||
|
throw new OlmException(OlmException.EXCEPTION_CODE_SAS_GENERATE_SHORT_CODE, e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String calculateMac(String message, String info) throws OlmException {
|
||||||
|
try {
|
||||||
|
byte[] bytes = calculateMacJni(message.getBytes("UTF-8"), info.getBytes("UTF-8"));
|
||||||
|
if (bytes != null) return new String(bytes, "UTF-8");
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
throw new OlmException(OlmException.EXCEPTION_CODE_SAS_ERROR, e.getMessage());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String calculateMacLongKdf(String message, String info) throws OlmException {
|
||||||
|
try {
|
||||||
|
byte[] bytes = calculateMacLongKdfJni(message.getBytes("UTF-8"), info.getBytes("UTF-8"));
|
||||||
|
if (bytes != null) return new String(bytes, "UTF-8");
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
throw new OlmException(OlmException.EXCEPTION_CODE_SAS_ERROR, e.getMessage());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an OLM session in native side.<br>
|
||||||
|
* Do not forget to call {@link #releaseSASJni()} when JAVA side is done.
|
||||||
|
*
|
||||||
|
* @return native account instance identifier or throw an exception.
|
||||||
|
*/
|
||||||
|
private native long createNewSASJni();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy the corresponding OLM session native object.<br>
|
||||||
|
* This method must ALWAYS be called when this JAVA instance
|
||||||
|
* is destroyed (ie. garbage collected) to prevent memory leak in native side.
|
||||||
|
* See {@link #createNewSASJni()}.
|
||||||
|
*/
|
||||||
|
private native void releaseSASJni();
|
||||||
|
|
||||||
|
private native byte[] getPubKeyJni();
|
||||||
|
|
||||||
|
private native void setTheirPubKey(byte[] pubKey);
|
||||||
|
|
||||||
|
private native byte[] generateShortCodeJni(byte[] info, int byteNumber);
|
||||||
|
|
||||||
|
private native byte[] calculateMacJni(byte[] message, byte[] info);
|
||||||
|
|
||||||
|
private native byte[] calculateMacLongKdfJni(byte[] message, byte[] info);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Release native session and invalid its JAVA reference counter part.<br>
|
||||||
|
* Public API for {@link #releaseSASJni()}.
|
||||||
|
*/
|
||||||
|
public void releaseSas() {
|
||||||
|
if (0 != mNativeId) {
|
||||||
|
releaseSASJni();
|
||||||
|
}
|
||||||
|
mNativeId = 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -41,6 +41,7 @@ $(SRC_ROOT_DIR)/src/ratchet.cpp \
|
||||||
$(SRC_ROOT_DIR)/src/session.cpp \
|
$(SRC_ROOT_DIR)/src/session.cpp \
|
||||||
$(SRC_ROOT_DIR)/src/utility.cpp \
|
$(SRC_ROOT_DIR)/src/utility.cpp \
|
||||||
$(SRC_ROOT_DIR)/src/pk.cpp \
|
$(SRC_ROOT_DIR)/src/pk.cpp \
|
||||||
|
$(SRC_ROOT_DIR)/src/sas.c \
|
||||||
$(SRC_ROOT_DIR)/src/ed25519.c \
|
$(SRC_ROOT_DIR)/src/ed25519.c \
|
||||||
$(SRC_ROOT_DIR)/src/error.c \
|
$(SRC_ROOT_DIR)/src/error.c \
|
||||||
$(SRC_ROOT_DIR)/src/inbound_group_session.c \
|
$(SRC_ROOT_DIR)/src/inbound_group_session.c \
|
||||||
|
@ -57,7 +58,8 @@ olm_inbound_group_session.cpp \
|
||||||
olm_outbound_group_session.cpp \
|
olm_outbound_group_session.cpp \
|
||||||
olm_utility.cpp \
|
olm_utility.cpp \
|
||||||
olm_manager.cpp \
|
olm_manager.cpp \
|
||||||
olm_pk.cpp
|
olm_pk.cpp \
|
||||||
|
olm_sas.cpp
|
||||||
|
|
||||||
LOCAL_LDLIBS := -llog
|
LOCAL_LDLIBS := -llog
|
||||||
|
|
||||||
|
|
|
@ -73,6 +73,7 @@ struct OlmUtility* getUtilityInstanceId(JNIEnv* aJniEnv, jobject aJavaObject);
|
||||||
struct OlmPkDecryption* getPkDecryptionInstanceId(JNIEnv* aJniEnv, jobject aJavaObject);
|
struct OlmPkDecryption* getPkDecryptionInstanceId(JNIEnv* aJniEnv, jobject aJavaObject);
|
||||||
struct OlmPkEncryption* getPkEncryptionInstanceId(JNIEnv* aJniEnv, jobject aJavaObject);
|
struct OlmPkEncryption* getPkEncryptionInstanceId(JNIEnv* aJniEnv, jobject aJavaObject);
|
||||||
struct OlmPkSigning* getPkSigningInstanceId(JNIEnv* aJniEnv, jobject aJavaObject);
|
struct OlmPkSigning* getPkSigningInstanceId(JNIEnv* aJniEnv, jobject aJavaObject);
|
||||||
|
struct OlmSAS* getOlmSasInstanceId(JNIEnv* aJniEnv, jobject aJavaObject);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -227,3 +227,8 @@ struct OlmPkSigning* getPkSigningInstanceId(JNIEnv* aJniEnv, jobject aJavaObject
|
||||||
{
|
{
|
||||||
return (struct OlmPkSigning*)getInstanceId(aJniEnv, aJavaObject, CLASS_OLM_PK_SIGNING);
|
return (struct OlmPkSigning*)getInstanceId(aJniEnv, aJavaObject, CLASS_OLM_PK_SIGNING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct OlmSAS* getOlmSasInstanceId(JNIEnv* aJniEnv, jobject aJavaObject)
|
||||||
|
{
|
||||||
|
return (struct OlmSAS*)getInstanceId(aJniEnv, aJavaObject, CLASS_OLM_SAS);
|
||||||
|
}
|
||||||
|
|
|
@ -28,4 +28,5 @@ namespace AndroidOlmSdk
|
||||||
static const char *CLASS_OLM_PK_ENCRYPTION = "org/matrix/olm/OlmPkEncryption";
|
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_DECRYPTION = "org/matrix/olm/OlmPkDecryption";
|
||||||
static const char *CLASS_OLM_PK_SIGNING = "org/matrix/olm/OlmPkSigning";
|
static const char *CLASS_OLM_PK_SIGNING = "org/matrix/olm/OlmPkSigning";
|
||||||
|
static const char *CLASS_OLM_SAS = "org/matrix/olm/OlmSAS";
|
||||||
}
|
}
|
||||||
|
|
390
android/olm-sdk/src/main/jni/olm_sas.cpp
Normal file
390
android/olm-sdk/src/main/jni/olm_sas.cpp
Normal file
|
@ -0,0 +1,390 @@
|
||||||
|
/*
|
||||||
|
* Copyright 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.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "olm_sas.h"
|
||||||
|
|
||||||
|
#include "olm/olm.h"
|
||||||
|
|
||||||
|
using namespace AndroidOlmSdk;
|
||||||
|
|
||||||
|
JNIEXPORT jlong OLM_SAS_FUNC_DEF(createNewSASJni)(JNIEnv *env, jobject thiz)
|
||||||
|
{
|
||||||
|
|
||||||
|
size_t sasSize = olm_sas_size();
|
||||||
|
OlmSAS *sasPtr = (OlmSAS *) malloc(sasSize);
|
||||||
|
const char* errorMessage = NULL;
|
||||||
|
|
||||||
|
if (!sasPtr)
|
||||||
|
{
|
||||||
|
LOGE("## createNewSASJni(): failure - init SAS OOM");
|
||||||
|
env->ThrowNew(env->FindClass("java/lang/Exception"), "init sas OOM");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sasPtr = olm_sas(sasPtr)
|
||||||
|
LOGD(" ## createNewSASJni(): success - sasPtr=%p (jlong)(intptr_t)accountPtr=%lld",sasPtr,(jlong)(intptr_t)sasPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t randomSize = olm_create_sas_random_length(sasPtr);
|
||||||
|
uint8_t *randomBuffPtr = NULL;
|
||||||
|
|
||||||
|
LOGD("## createNewSASJni(): randomSize=%lu",static_cast<long unsigned int>(randomSize));
|
||||||
|
|
||||||
|
if ( (0 != randomSize) && !setRandomInBuffer(env, &randomBuffPtr, randomSize))
|
||||||
|
{
|
||||||
|
LOGE("## createNewSASJni(): failure - random buffer init");
|
||||||
|
errorMessage = "Failed to init private key";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size_t result = olm_create_sas(sasPtr, randomBuffPtr, randomSize);
|
||||||
|
if (result == olm_error())
|
||||||
|
{
|
||||||
|
errorMessage = (const char *)olm_sas_last_error(sasPtr);
|
||||||
|
LOGE("## createNewSASJni(): failure - error creating SAS Msg=%s", errorMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (randomBuffPtr)
|
||||||
|
{
|
||||||
|
memset(randomBuffPtr, 0, randomSize);
|
||||||
|
free(randomBuffPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errorMessage)
|
||||||
|
{
|
||||||
|
env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (jlong)(intptr_t)sasPtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void OLM_SAS_FUNC_DEF(releaseSASJni)(JNIEnv *env, jobject thiz)
|
||||||
|
{
|
||||||
|
LOGD("## releaseSASJni(): IN");
|
||||||
|
OlmSAS* sasPtr = getOlmSasInstanceId(env, thiz);
|
||||||
|
|
||||||
|
if (!sasPtr)
|
||||||
|
{
|
||||||
|
LOGE("## releaseSessionJni(): failure - invalid Session ptr=NULL");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
olm_clear_sas(sasPtr);
|
||||||
|
// even if free(NULL) does not crash, logs are performed for debug purpose
|
||||||
|
free(sasPtr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JNIEXPORT jbyteArray OLM_SAS_FUNC_DEF(getPubKeyJni)(JNIEnv *env, jobject thiz)
|
||||||
|
{
|
||||||
|
LOGD("## getPubKeyJni(): IN");
|
||||||
|
const char* errorMessage = NULL;
|
||||||
|
jbyteArray returnValue = 0;
|
||||||
|
OlmSAS* sasPtr = getOlmSasInstanceId(env, thiz);
|
||||||
|
|
||||||
|
if (!sasPtr)
|
||||||
|
{
|
||||||
|
LOGE("## getPubKeyJni(): failure - invalid SAS ptr=NULL");
|
||||||
|
errorMessage = "invalid SAS ptr=NULL";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size_t pubKeyLength = olm_sas_pubkey_length(sasPtr);
|
||||||
|
void *pubkey = malloc(pubKeyLength*sizeof(uint8_t));
|
||||||
|
size_t result = olm_sas_get_pubkey(sasPtr, pubkey, pubKeyLength);
|
||||||
|
if (result == olm_error())
|
||||||
|
{
|
||||||
|
errorMessage = (const char *)olm_sas_last_error(sasPtr);
|
||||||
|
LOGE("## getPubKeyJni(): failure - error getting pub key Msg=%s", errorMessage);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
returnValue = env->NewByteArray(pubKeyLength);
|
||||||
|
env->SetByteArrayRegion(returnValue, 0 , pubKeyLength, (jbyte*)pubkey);
|
||||||
|
}
|
||||||
|
if (pubkey) {
|
||||||
|
free(pubkey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errorMessage)
|
||||||
|
{
|
||||||
|
env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void OLM_SAS_FUNC_DEF(setTheirPubKey)(JNIEnv *env, jobject thiz,jbyteArray pubKeyBuffer) {
|
||||||
|
|
||||||
|
OlmSAS* sasPtr = getOlmSasInstanceId(env, thiz);
|
||||||
|
|
||||||
|
const char* errorMessage = NULL;
|
||||||
|
jbyte *pubKeyPtr = NULL;
|
||||||
|
jboolean pubKeyWasCopied = JNI_FALSE;
|
||||||
|
|
||||||
|
if (!sasPtr)
|
||||||
|
{
|
||||||
|
LOGE("## setTheirPubKey(): failure - invalid SAS ptr=NULL");
|
||||||
|
errorMessage = "invalid SAS ptr=NULL";
|
||||||
|
} else if(!pubKeyBuffer) {
|
||||||
|
LOGE("## setTheirPubKey(): failure - invalid info");
|
||||||
|
errorMessage = "invalid pubKey";
|
||||||
|
}
|
||||||
|
else if (!(pubKeyPtr = env->GetByteArrayElements(pubKeyBuffer, &pubKeyWasCopied)))
|
||||||
|
{
|
||||||
|
LOGE(" ## setTheirPubKey(): failure - info JNI allocation OOM");
|
||||||
|
errorMessage = "info JNI allocation OOM";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size_t pubKeyLength = (size_t)env->GetArrayLength(pubKeyBuffer);
|
||||||
|
size_t result = olm_sas_set_their_key(sasPtr,pubKeyPtr,pubKeyLength);
|
||||||
|
if (result == olm_error())
|
||||||
|
{
|
||||||
|
errorMessage = (const char *)olm_sas_last_error(sasPtr);
|
||||||
|
LOGE("## setTheirPubKey(): failure - error setting their key Msg=%s", errorMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// free alloc
|
||||||
|
if (pubKeyPtr)
|
||||||
|
{
|
||||||
|
if (pubKeyWasCopied)
|
||||||
|
{
|
||||||
|
memset(pubKeyPtr, 0, (size_t)env->GetArrayLength(pubKeyBuffer));
|
||||||
|
}
|
||||||
|
env->ReleaseByteArrayElements(pubKeyBuffer, pubKeyPtr, JNI_ABORT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errorMessage)
|
||||||
|
{
|
||||||
|
env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jbyteArray OLM_SAS_FUNC_DEF(generateShortCodeJni)(JNIEnv *env, jobject thiz, jbyteArray infoStringBytes, jint byteNb) {
|
||||||
|
LOGD("## generateShortCodeJni(): IN");
|
||||||
|
const char* errorMessage = NULL;
|
||||||
|
jbyteArray returnValue = 0;
|
||||||
|
OlmSAS* sasPtr = getOlmSasInstanceId(env, thiz);
|
||||||
|
|
||||||
|
jbyte *infoPtr = NULL;
|
||||||
|
jboolean infoWasCopied = JNI_FALSE;
|
||||||
|
|
||||||
|
if (!sasPtr)
|
||||||
|
{
|
||||||
|
LOGE("## generateShortCodeJni(): failure - invalid SAS ptr=NULL");
|
||||||
|
errorMessage = "invalid SAS ptr=NULL";
|
||||||
|
} else if(!infoStringBytes) {
|
||||||
|
LOGE("## generateShortCodeJni(): failure - invalid info");
|
||||||
|
errorMessage = "invalid info";
|
||||||
|
}
|
||||||
|
else if (!(infoPtr = env->GetByteArrayElements(infoStringBytes, &infoWasCopied)))
|
||||||
|
{
|
||||||
|
LOGE(" ## generateShortCodeJni(): failure - info JNI allocation OOM");
|
||||||
|
errorMessage = "info JNI allocation OOM";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
size_t shortBytesCodeLength = (size_t) byteNb;
|
||||||
|
void *shortBytesCode = malloc(shortBytesCodeLength * sizeof(uint8_t));
|
||||||
|
size_t infoLength = (size_t)env->GetArrayLength(infoStringBytes);
|
||||||
|
olm_sas_generate_bytes(sasPtr, infoPtr, infoLength, shortBytesCode, shortBytesCodeLength);
|
||||||
|
returnValue = env->NewByteArray(shortBytesCodeLength);
|
||||||
|
env->SetByteArrayRegion(returnValue, 0 , shortBytesCodeLength, (jbyte*)shortBytesCode);
|
||||||
|
free(shortBytesCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
// free alloc
|
||||||
|
if (infoPtr)
|
||||||
|
{
|
||||||
|
if (infoWasCopied)
|
||||||
|
{
|
||||||
|
memset(infoPtr, 0, (size_t)env->GetArrayLength(infoStringBytes));
|
||||||
|
}
|
||||||
|
env->ReleaseByteArrayElements(infoStringBytes, infoPtr, JNI_ABORT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errorMessage)
|
||||||
|
{
|
||||||
|
env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JNIEXPORT jbyteArray OLM_SAS_FUNC_DEF(calculateMacJni)(JNIEnv *env, jobject thiz,jbyteArray messageBuffer,jbyteArray infoBuffer) {
|
||||||
|
LOGD("## calculateMacJni(): IN");
|
||||||
|
const char* errorMessage = NULL;
|
||||||
|
jbyteArray returnValue = 0;
|
||||||
|
OlmSAS* sasPtr = getOlmSasInstanceId(env, thiz);
|
||||||
|
|
||||||
|
jbyte *messagePtr = NULL;
|
||||||
|
jboolean messageWasCopied = JNI_FALSE;
|
||||||
|
|
||||||
|
jbyte *infoPtr = NULL;
|
||||||
|
jboolean infoWasCopied = JNI_FALSE;
|
||||||
|
|
||||||
|
if (!sasPtr)
|
||||||
|
{
|
||||||
|
LOGE("## calculateMacJni(): failure - invalid SAS ptr=NULL");
|
||||||
|
errorMessage = "invalid SAS ptr=NULL";
|
||||||
|
} else if(!messageBuffer) {
|
||||||
|
LOGE("## calculateMacJni(): failure - invalid message");
|
||||||
|
errorMessage = "invalid info";
|
||||||
|
}
|
||||||
|
else if (!(messagePtr = env->GetByteArrayElements(messageBuffer, &messageWasCopied)))
|
||||||
|
{
|
||||||
|
LOGE(" ## calculateMacJni(): failure - message JNI allocation OOM");
|
||||||
|
errorMessage = "message JNI allocation OOM";
|
||||||
|
}
|
||||||
|
else if (!(infoPtr = env->GetByteArrayElements(infoBuffer, &infoWasCopied)))
|
||||||
|
{
|
||||||
|
LOGE(" ## calculateMacJni(): failure - info JNI allocation OOM");
|
||||||
|
errorMessage = "info JNI allocation OOM";
|
||||||
|
} else {
|
||||||
|
|
||||||
|
size_t infoLength = (size_t)env->GetArrayLength(infoBuffer);
|
||||||
|
size_t messageLength = (size_t)env->GetArrayLength(messageBuffer);
|
||||||
|
size_t macLength = olm_sas_mac_length(sasPtr);
|
||||||
|
|
||||||
|
void *macPtr = malloc(macLength*sizeof(uint8_t));
|
||||||
|
|
||||||
|
size_t result = olm_sas_calculate_mac(sasPtr,messagePtr,messageLength,infoPtr,infoLength,macPtr,macLength);
|
||||||
|
if (result == olm_error())
|
||||||
|
{
|
||||||
|
errorMessage = (const char *)olm_sas_last_error(sasPtr);
|
||||||
|
LOGE("## calculateMacJni(): failure - error calculating SAS mac Msg=%s", errorMessage);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
returnValue = env->NewByteArray(macLength);
|
||||||
|
env->SetByteArrayRegion(returnValue, 0 , macLength, (jbyte*)macPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (macPtr) {
|
||||||
|
free(macPtr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// free alloc
|
||||||
|
if (infoPtr)
|
||||||
|
{
|
||||||
|
if (infoWasCopied)
|
||||||
|
{
|
||||||
|
memset(infoPtr, 0, (size_t)env->GetArrayLength(infoBuffer));
|
||||||
|
}
|
||||||
|
env->ReleaseByteArrayElements(infoBuffer, infoPtr, JNI_ABORT);
|
||||||
|
}
|
||||||
|
if (messagePtr)
|
||||||
|
{
|
||||||
|
if (messageWasCopied)
|
||||||
|
{
|
||||||
|
memset(messagePtr, 0, (size_t)env->GetArrayLength(messageBuffer));
|
||||||
|
}
|
||||||
|
env->ReleaseByteArrayElements(messageBuffer, messagePtr, JNI_ABORT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errorMessage)
|
||||||
|
{
|
||||||
|
env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jbyteArray OLM_SAS_FUNC_DEF(calculateMacLongKdfJni)(JNIEnv *env, jobject thiz,jbyteArray messageBuffer,jbyteArray infoBuffer) {
|
||||||
|
LOGD("## calculateMacLongKdfJni(): IN");
|
||||||
|
const char* errorMessage = NULL;
|
||||||
|
jbyteArray returnValue = 0;
|
||||||
|
OlmSAS* sasPtr = getOlmSasInstanceId(env, thiz);
|
||||||
|
|
||||||
|
jbyte *messagePtr = NULL;
|
||||||
|
jboolean messageWasCopied = JNI_FALSE;
|
||||||
|
|
||||||
|
jbyte *infoPtr = NULL;
|
||||||
|
jboolean infoWasCopied = JNI_FALSE;
|
||||||
|
|
||||||
|
if (!sasPtr)
|
||||||
|
{
|
||||||
|
LOGE("## calculateMacLongKdfJni(): failure - invalid SAS ptr=NULL");
|
||||||
|
errorMessage = "invalid SAS ptr=NULL";
|
||||||
|
} else if(!messageBuffer) {
|
||||||
|
LOGE("## calculateMacLongKdfJni(): failure - invalid message");
|
||||||
|
errorMessage = "invalid info";
|
||||||
|
}
|
||||||
|
else if (!(messagePtr = env->GetByteArrayElements(messageBuffer, &messageWasCopied)))
|
||||||
|
{
|
||||||
|
LOGE(" ## calculateMacLongKdfJni(): failure - message JNI allocation OOM");
|
||||||
|
errorMessage = "message JNI allocation OOM";
|
||||||
|
}
|
||||||
|
else if (!(infoPtr = env->GetByteArrayElements(infoBuffer, &infoWasCopied)))
|
||||||
|
{
|
||||||
|
LOGE(" ## calculateMacLongKdfJni(): failure - info JNI allocation OOM");
|
||||||
|
errorMessage = "info JNI allocation OOM";
|
||||||
|
} else {
|
||||||
|
|
||||||
|
size_t infoLength = (size_t)env->GetArrayLength(infoBuffer);
|
||||||
|
size_t messageLength = (size_t)env->GetArrayLength(messageBuffer);
|
||||||
|
size_t macLength = olm_sas_mac_length(sasPtr);
|
||||||
|
|
||||||
|
void *macPtr = malloc(macLength*sizeof(uint8_t));
|
||||||
|
|
||||||
|
size_t result = olm_sas_calculate_mac_long_kdf(sasPtr,messagePtr,messageLength,infoPtr,infoLength,macPtr,macLength);
|
||||||
|
if (result == olm_error())
|
||||||
|
{
|
||||||
|
errorMessage = (const char *)olm_sas_last_error(sasPtr);
|
||||||
|
LOGE("## calculateMacLongKdfJni(): failure - error calculating SAS mac Msg=%s", errorMessage);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
returnValue = env->NewByteArray(macLength);
|
||||||
|
env->SetByteArrayRegion(returnValue, 0 , macLength, (jbyte*)macPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (macPtr) {
|
||||||
|
free(macPtr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// free alloc
|
||||||
|
if (infoPtr)
|
||||||
|
{
|
||||||
|
if (infoWasCopied)
|
||||||
|
{
|
||||||
|
memset(infoPtr, 0, (size_t)env->GetArrayLength(infoBuffer));
|
||||||
|
}
|
||||||
|
env->ReleaseByteArrayElements(infoBuffer, infoPtr, JNI_ABORT);
|
||||||
|
}
|
||||||
|
if (messagePtr)
|
||||||
|
{
|
||||||
|
if (messageWasCopied)
|
||||||
|
{
|
||||||
|
memset(messagePtr, 0, (size_t)env->GetArrayLength(messageBuffer));
|
||||||
|
}
|
||||||
|
env->ReleaseByteArrayElements(messageBuffer, messagePtr, JNI_ABORT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errorMessage)
|
||||||
|
{
|
||||||
|
env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
}
|
41
android/olm-sdk/src/main/jni/olm_sas.h
Normal file
41
android/olm-sdk/src/main/jni/olm_sas.h
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* Copyright 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.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _OMLSAS_H
|
||||||
|
#define _OMLSAS_H
|
||||||
|
|
||||||
|
#include "olm_jni.h"
|
||||||
|
#include "olm/sas.h"
|
||||||
|
|
||||||
|
#define OLM_SAS_FUNC_DEF(func_name) FUNC_DEF(OlmSAS,func_name)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
JNIEXPORT jlong OLM_SAS_FUNC_DEF(createNewSASJni)(JNIEnv *env, jobject thiz);
|
||||||
|
JNIEXPORT void OLM_SAS_FUNC_DEF(releaseSASJni)(JNIEnv *env, jobject thiz);
|
||||||
|
JNIEXPORT jbyteArray OLM_SAS_FUNC_DEF(getPubKeyJni)(JNIEnv *env, jobject thiz);
|
||||||
|
JNIEXPORT void OLM_SAS_FUNC_DEF(setTheirPubKey)(JNIEnv *env, jobject thiz,jbyteArray pubKey);
|
||||||
|
JNIEXPORT jbyteArray OLM_SAS_FUNC_DEF(generateShortCodeJni)(JNIEnv *env, jobject thiz, jbyteArray infoStringBytes, jint byteNb);
|
||||||
|
JNIEXPORT jbyteArray OLM_SAS_FUNC_DEF(calculateMacJni)(JNIEnv *env, jobject thiz, jbyteArray messageBuffer, jbyteArray infoBuffer);
|
||||||
|
JNIEXPORT jbyteArray OLM_SAS_FUNC_DEF(calculateMacLongKdfJni)(JNIEnv *env, jobject thiz, jbyteArray messageBuffer, jbyteArray infoBuffer);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in a new issue