Commit c79d9282 authored by Valere's avatar Valere Committed by GitHub

Merge pull request #83 from matrix-org/BillCarsonFr/java_sas

Java binding for SAS
parents ebc156e7 eb7347bb
/*
* 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_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
public static final String EXCEPTION_MSG_INVALID_PARAMS_DESERIALIZATION = "invalid de-serialized parameters";
......
/*
* 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/utility.cpp \
$(SRC_ROOT_DIR)/src/pk.cpp \
$(SRC_ROOT_DIR)/src/sas.c \
$(SRC_ROOT_DIR)/src/ed25519.c \
$(SRC_ROOT_DIR)/src/error.c \
$(SRC_ROOT_DIR)/src/inbound_group_session.c \
......@@ -57,7 +58,8 @@ olm_inbound_group_session.cpp \
olm_outbound_group_session.cpp \
olm_utility.cpp \
olm_manager.cpp \
olm_pk.cpp
olm_pk.cpp \
olm_sas.cpp
LOCAL_LDLIBS := -llog
......
......@@ -73,6 +73,7 @@ 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);
struct OlmSAS* getOlmSasInstanceId(JNIEnv* aJniEnv, jobject aJavaObject);
#ifdef __cplusplus
}
......
......@@ -227,3 +227,8 @@ struct OlmPkSigning* getPkSigningInstanceId(JNIEnv* aJniEnv, jobject aJavaObject
{
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_DECRYPTION = "org/matrix/olm/OlmPkDecryption";
static const char *CLASS_OLM_PK_SIGNING = "org/matrix/olm/OlmPkSigning";
static const char *CLASS_OLM_SAS = "org/matrix/olm/OlmSAS";
}
This diff is collapsed.
/*
* 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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment