add functions for dealing with private keys directly

This commit is contained in:
Hubert Chathi 2018-10-17 22:29:01 -04:00
parent 1c7ff7f48d
commit 2cace25fba
5 changed files with 195 additions and 0 deletions

View file

@ -19,6 +19,8 @@ package org.matrix.olm;
import android.support.test.runner.AndroidJUnit4; import android.support.test.runner.AndroidJUnit4;
import android.util.Log; import android.util.Log;
import java.util.Arrays;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.FixMethodOrder; import org.junit.FixMethodOrder;
import org.junit.Test; import org.junit.Test;
@ -91,4 +93,46 @@ public class OlmPkTest {
assertTrue(mOlmPkEncryption.isReleased()); assertTrue(mOlmPkEncryption.isReleased());
assertTrue(mOlmPkDecryption.isReleased()); assertTrue(mOlmPkDecryption.isReleased());
} }
@Test
public void test02PrivateKey() {
try {
mOlmPkDecryption = new OlmPkDecryption();
} catch (OlmException e) {
e.printStackTrace();
assertTrue("OlmPkEncryption failed " + e.getMessage(), false);
}
assertNotNull(mOlmPkDecryption);
byte[] privateKey = {
(byte)0x77, (byte)0x07, (byte)0x6D, (byte)0x0A,
(byte)0x73, (byte)0x18, (byte)0xA5, (byte)0x7D,
(byte)0x3C, (byte)0x16, (byte)0xC1, (byte)0x72,
(byte)0x51, (byte)0xB2, (byte)0x66, (byte)0x45,
(byte)0xDF, (byte)0x4C, (byte)0x2F, (byte)0x87,
(byte)0xEB, (byte)0xC0, (byte)0x99, (byte)0x2A,
(byte)0xB1, (byte)0x77, (byte)0xFB, (byte)0xA5,
(byte)0x1D, (byte)0xB9, (byte)0x2C, (byte)0x2A
};
try {
mOlmPkDecryption.setPrivateKey(privateKey);
} catch (OlmException e) {
assertTrue("Exception in setPrivateKey, Exception code=" + e.getExceptionCode(), false);
}
byte[] privateKeyCopy = null;
try {
privateKeyCopy = mOlmPkDecryption.privateKey();
} catch (OlmException e) {
assertTrue("Exception in privateKey, Exception code=" + e.getExceptionCode(), false);
}
assertTrue(Arrays.equals(privateKey, privateKeyCopy));
mOlmPkDecryption.releaseDecryption();
assertTrue(mOlmPkDecryption.isReleased());
}
} }

View file

@ -68,6 +68,8 @@ public class OlmException extends IOException {
public static final int EXCEPTION_CODE_PK_DECRYPTION_CREATION = 700; public static final int EXCEPTION_CODE_PK_DECRYPTION_CREATION = 700;
public static final int EXCEPTION_CODE_PK_DECRYPTION_GENERATE_KEY = 701; public static final int EXCEPTION_CODE_PK_DECRYPTION_GENERATE_KEY = 701;
public static final int EXCEPTION_CODE_PK_DECRYPTION_DECRYPT = 702; public static final int EXCEPTION_CODE_PK_DECRYPTION_DECRYPT = 702;
public static final int EXCEPTION_CODE_PK_DECRYPTION_SET_PRIVATE_KEY = 703;
public static final int EXCEPTION_CODE_PK_DECRYPTION_PRIVATE_KEY = 704;
// 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";

View file

@ -51,6 +51,18 @@ public class OlmPkDecryption {
return (0 == mNativeId); return (0 == mNativeId);
} }
public String setPrivateKey(byte[] privateKey) throws OlmException {
try {
byte[] key = setPrivateKeyJni(privateKey);
return new String(key, "UTF-8");
} catch (Exception e) {
Log.e(LOG_TAG, "## setPrivateKey(): failed " + e.getMessage());
throw new OlmException(OlmException.EXCEPTION_CODE_PK_DECRYPTION_SET_PRIVATE_KEY, e.getMessage());
}
}
private native byte[] setPrivateKeyJni(byte[] privateKey);
public String generateKey() throws OlmException { public String generateKey() throws OlmException {
try { try {
byte[] key = generateKeyJni(); byte[] key = generateKeyJni();
@ -63,6 +75,17 @@ public class OlmPkDecryption {
private native byte[] generateKeyJni(); private native byte[] generateKeyJni();
public byte[] privateKey() throws OlmException {
try {
return privateKeyJni();
} catch (Exception e) {
Log.e(LOG_TAG, "## privateKey(): failed " + e.getMessage());
throw new OlmException(OlmException.EXCEPTION_CODE_PK_DECRYPTION_PRIVATE_KEY, e.getMessage());
}
}
private native byte[] privateKeyJni();
public String decrypt(OlmPkMessage aMessage) throws OlmException { public String decrypt(OlmPkMessage aMessage) throws OlmException {
if (null == aMessage) { if (null == aMessage) {
return null; return null;

View file

@ -364,6 +364,79 @@ JNIEXPORT void OLM_PK_DECRYPTION_FUNC_DEF(releasePkDecryptionJni)(JNIEnv *env, j
} }
} }
JNIEXPORT jbyteArray OLM_PK_DECRYPTION_FUNC_DEF(setPrivateKeyJni)(JNIEnv *env, jobject thiz, jbyteArray key)
{
jbyteArray publicKeyRet = 0;
jbyte *keyPtr = NULL;
jboolean keyWasCopied = JNI_FALSE;
const char* errorMessage = NULL;
OlmPkDecryption* decryptionPtr = getPkDecryptionInstanceId(env, thiz);
if (!decryptionPtr)
{
LOGE(" ## pkSetPrivateKeyJni(): failure - invalid Decryption ptr=NULL");
}
else if (!key)
{
LOGE(" ## pkSetPrivateKeyJni(): failure - invalid key");
errorMessage = "invalid key";
}
else if (!(keyPtr = env->GetByteArrayElements(key, &keyWasCopied)))
{
LOGE(" ## pkSetPrivateKeyJni(): failure - key JNI allocation OOM");
errorMessage = "key JNI allocation OOM";
}
else
{
size_t publicKeyLength = olm_pk_key_length();
uint8_t *publicKeyPtr = NULL;
size_t keyLength = (size_t)env->GetArrayLength(key);
if (!(publicKeyPtr = (uint8_t*)malloc(publicKeyLength)))
{
LOGE("## pkSetPrivateKeyJni(): failure - public key JNI allocation OOM");
errorMessage = "public key JNI allocation OOM";
}
else
{
size_t returnValue = olm_pk_key_from_private(
decryptionPtr,
publicKeyPtr, publicKeyLength,
keyPtr, keyLength
);
if (returnValue == olm_error())
{
errorMessage = olm_pk_decryption_last_error(decryptionPtr);
LOGE(" ## pkSetPrivateKeyJni(): failure - olm_pk_key_from_private Msg=%s", errorMessage);
}
else
{
publicKeyRet = env->NewByteArray(publicKeyLength);
env->SetByteArrayRegion(
publicKeyRet, 0, publicKeyLength, (jbyte*)publicKeyPtr
);
}
}
}
if (keyPtr)
{
if (keyWasCopied)
{
memset(keyPtr, 0, (size_t)env->GetArrayLength(key));
}
env->ReleaseByteArrayElements(key, keyPtr, JNI_ABORT);
}
if (errorMessage)
{
env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage);
}
return publicKeyRet;
}
JNIEXPORT jbyteArray OLM_PK_DECRYPTION_FUNC_DEF(generateKeyJni)(JNIEnv *env, jobject thiz) JNIEXPORT jbyteArray OLM_PK_DECRYPTION_FUNC_DEF(generateKeyJni)(JNIEnv *env, jobject thiz)
{ {
size_t randomLength = olm_pk_private_key_length(); size_t randomLength = olm_pk_private_key_length();
@ -420,6 +493,57 @@ JNIEXPORT jbyteArray OLM_PK_DECRYPTION_FUNC_DEF(generateKeyJni)(JNIEnv *env, job
return publicKeyRet; return publicKeyRet;
} }
JNIEXPORT jbyteArray OLM_PK_DECRYPTION_FUNC_DEF(privateKeyJni)(JNIEnv *env, jobject thiz)
{
jbyteArray privateKeyRet = 0;
const char* errorMessage = NULL;
OlmPkDecryption* decryptionPtr = getPkDecryptionInstanceId(env, thiz);
if (!decryptionPtr)
{
LOGE(" ## pkPrivateKeyJni(): failure - invalid Decryption ptr=NULL");
}
else
{
size_t privateKeyLength = olm_pk_private_key_length();
uint8_t *privateKeyPtr = NULL;
if (!(privateKeyPtr = (uint8_t*)malloc(privateKeyLength)))
{
LOGE("## pkPrivateKeyJni(): failure - private key JNI allocation OOM");
errorMessage = "private key JNI allocation OOM";
}
else
{
size_t returnValue = olm_pk_get_private_key(
decryptionPtr,
privateKeyPtr, privateKeyLength
);
if (returnValue == olm_error())
{
errorMessage = olm_pk_decryption_last_error(decryptionPtr);
LOGE(" ## pkPrivateKeyJni(): failure - olm_pk_get_private_key Msg=%s", errorMessage);
}
else
{
privateKeyRet = env->NewByteArray(privateKeyLength);
env->SetByteArrayRegion(
privateKeyRet, 0, privateKeyLength, (jbyte*)privateKeyPtr
);
memset(privateKeyPtr, 0, privateKeyLength);
}
}
}
if (errorMessage)
{
env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage);
}
return privateKeyRet;
}
JNIEXPORT jbyteArray OLM_PK_DECRYPTION_FUNC_DEF(decryptJni)( JNIEXPORT jbyteArray OLM_PK_DECRYPTION_FUNC_DEF(decryptJni)(
JNIEnv *env, jobject thiz, jobject aEncryptedMsg JNIEnv *env, jobject thiz, jobject aEncryptedMsg
) { ) {

View file

@ -35,7 +35,9 @@ JNIEXPORT jbyteArray OLM_PK_ENCRYPTION_FUNC_DEF(encryptJni)(JNIEnv *env, jobject
JNIEXPORT jlong OLM_PK_DECRYPTION_FUNC_DEF(createNewPkDecryptionJni)(JNIEnv *env, jobject thiz); JNIEXPORT jlong OLM_PK_DECRYPTION_FUNC_DEF(createNewPkDecryptionJni)(JNIEnv *env, jobject thiz);
JNIEXPORT void OLM_PK_DECRYPTION_FUNC_DEF(releasePkDecryptionJni)(JNIEnv *env, jobject thiz); JNIEXPORT void OLM_PK_DECRYPTION_FUNC_DEF(releasePkDecryptionJni)(JNIEnv *env, jobject thiz);
JNIEXPORT jbyteArray OLM_PK_DECRYPTION_FUNC_DEF(setPrivateKeyJni)(JNIEnv *env, jobject thiz, jbyteArray key);
JNIEXPORT jbyteArray OLM_PK_DECRYPTION_FUNC_DEF(generateKeyJni)(JNIEnv *env, jobject thiz); JNIEXPORT jbyteArray OLM_PK_DECRYPTION_FUNC_DEF(generateKeyJni)(JNIEnv *env, jobject thiz);
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 jbyteArray OLM_PK_DECRYPTION_FUNC_DEF(decryptJni)(JNIEnv *env, jobject thiz, jobject aEncryptedMsg);
#ifdef __cplusplus #ifdef __cplusplus