Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,19 @@ internal static partial class Crypto
// the array with zeroes.
int offset = targetSize - compactSize;
byte[] buf = new byte[targetSize];
int written;
fixed (byte* to = buf)
{
byte* start = to + offset;
BigNumToBinary(bignum, start);
written = BigNumToBinary(bignum, start);
}

// A negative result means the native side cleared a pending JNI exception, so the
// output must be treated as invalid. Fail loudly rather than returning a buffer that
// may be zero-filled or only partially written.
if (written < 0)
throw new CryptographicException();

return buf;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@ internal static X509Certificate2[] X509ChainGetCertificates(SafeX509ChainContext
}
finally
{
// The native side can populate part of certPtrs and then fail (returning 0) if a JNI
// exception is thrown mid-loop, so release every non-null entry rather than only the
// first `res` entries.
// X509Certificate2 above duplicates each global ref, so release the native-returned
// refs here. On failure the native side already released and cleared its entries, so
// the surviving non-null entries are the ones we still own.
for (int i = 0; i < certPtrs.Length; i++)
{
if (certPtrs[i] != IntPtr.Zero)
Expand Down Expand Up @@ -112,6 +112,8 @@ private static unsafe partial int X509ChainGetErrors(
internal static ValidationError[] X509ChainGetErrors(SafeX509ChainContextHandle ctx)
{
int count = Interop.AndroidCrypto.X509ChainGetErrorCount(ctx);
if (count < 0)
throw new CryptographicException();
if (count == 0)
return Array.Empty<ValidationError>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,32 @@ int32_t AndroidCryptoNative_BigNumToBinary(jobject bignum, uint8_t* output)

// bigNum.toByteArray()
JNIEnv* env = GetJNIEnv();
jbyteArray bytes = (jbyteArray)(*env)->CallObjectMethod(env, bignum, g_toByteArrayMethod);
jsize bytesLen = (*env)->GetArrayLength(env, bytes);
int32_t ret = -1;
jsize bytesLen = 0;
jsize startingIndex = 0;
jbyte leadingByte = 0;
INIT_LOCALS(loc, bytes);

loc[bytes] = (jbyteArray)(*env)->CallObjectMethod(env, bignum, g_toByteArrayMethod);
ON_EXCEPTION_PRINT_AND_GOTO(cleanup);
bytesLen = (*env)->GetArrayLength(env, loc[bytes]);

Comment thread
simonrozsival marked this conversation as resolved.
// We strip the leading zero byte from the byte array.
jsize startingIndex = 0;
jbyte leadingByte;
(*env)->GetByteArrayRegion(env, bytes, 0, 1, &leadingByte);
(*env)->GetByteArrayRegion(env, loc[bytes], 0, 1, &leadingByte);
ON_EXCEPTION_PRINT_AND_GOTO(cleanup);
if (leadingByte == 0)
{
startingIndex++;
bytesLen--;
}

(*env)->GetByteArrayRegion(env, bytes, startingIndex, bytesLen, (jbyte*)output);
(*env)->DeleteLocalRef(env, bytes);
return CheckJNIExceptions(env) ? FAIL : (int32_t)bytesLen;
(*env)->GetByteArrayRegion(env, loc[bytes], startingIndex, bytesLen, (jbyte*)output);
ON_EXCEPTION_PRINT_AND_GOTO(cleanup);
ret = (int32_t)bytesLen;

cleanup:
RELEASE_LOCALS(loc, env);
return ret;
}

int32_t AndroidCryptoNative_GetBigNumBytes(jobject bignum)
Expand Down Expand Up @@ -65,8 +75,14 @@ int32_t AndroidCryptoNative_GetBigNumBytesIncludingPaddingByteForSign(jobject bi
// Use the array here to get the leading zero byte if it exists.
// bigNum.toByteArray().length();
JNIEnv* env = GetJNIEnv();
jbyteArray bytes = (jbyteArray)(*env)->CallObjectMethod(env, bignum, g_toByteArrayMethod);
jsize bytesLen = (*env)->GetArrayLength(env, bytes);
(*env)->DeleteLocalRef(env, bytes);
return CheckJNIExceptions(env) ? FAIL : (int32_t)bytesLen;
int32_t ret = FAIL;
INIT_LOCALS(loc, bytes);

loc[bytes] = (jbyteArray)(*env)->CallObjectMethod(env, bignum, g_toByteArrayMethod);
ON_EXCEPTION_PRINT_AND_GOTO(cleanup);
ret = (int32_t)(*env)->GetArrayLength(env, loc[bytes]);

Comment thread
simonrozsival marked this conversation as resolved.
cleanup:
RELEASE_LOCALS(loc, env);
return ret;
}
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,8 @@ int32_t AndroidCryptoNative_CipherSetKeyAndIV(CipherCtx* ctx, uint8_t* key, uint
// ivLength = cipher.getBlockSize();
JNIEnv *env = GetJNIEnv();
ctx->ivLength = (*env)->CallIntMethod(env, ctx->cipher, g_getBlockSizeMethod);
if (CheckJNIExceptions(env))
return FAIL;
}

SaveTo(iv, &ctx->iv, (size_t)ctx->ivLength, /* overwrite */ true);
Expand Down Expand Up @@ -241,11 +243,18 @@ int32_t AndroidCryptoNative_CipherUpdateAAD(CipherCtx* ctx, uint8_t* in, int32_t
abort_if_invalid_pointer_argument(in);

JNIEnv* env = GetJNIEnv();
jbyteArray inDataBytes = make_java_byte_array(env, inl);
(*env)->SetByteArrayRegion(env, inDataBytes, 0, inl, (jbyte*)in);
(*env)->CallVoidMethod(env, ctx->cipher, g_cipherUpdateAADMethod, inDataBytes);
(*env)->DeleteLocalRef(env, inDataBytes);
return CheckJNIExceptions(env) ? FAIL : SUCCESS;
int32_t ret = FAIL;
INIT_LOCALS(loc, inDataBytes);
loc[inDataBytes] = make_java_byte_array(env, inl);
(*env)->SetByteArrayRegion(env, loc[inDataBytes], 0, inl, (jbyte*)in);
ON_EXCEPTION_PRINT_AND_GOTO(cleanup);
(*env)->CallVoidMethod(env, ctx->cipher, g_cipherUpdateAADMethod, loc[inDataBytes]);
ON_EXCEPTION_PRINT_AND_GOTO(cleanup);
ret = SUCCESS;

cleanup:
RELEASE_LOCALS(loc, env);
return ret;
}

int32_t AndroidCryptoNative_CipherUpdate(CipherCtx* ctx, uint8_t* outm, int32_t* outl, uint8_t* in, int32_t inl)
Expand All @@ -261,22 +270,30 @@ int32_t AndroidCryptoNative_CipherUpdate(CipherCtx* ctx, uint8_t* outm, int32_t*
abort_if_invalid_pointer_argument(in);

JNIEnv* env = GetJNIEnv();
jbyteArray inDataBytes = make_java_byte_array(env, inl);
(*env)->SetByteArrayRegion(env, inDataBytes, 0, inl, (jbyte*)in);
int32_t ret = FAIL;
INIT_LOCALS(loc, inDataBytes, outDataBytes);

*outl = 0;
jbyteArray outDataBytes = (jbyteArray)(*env)->CallObjectMethod(env, ctx->cipher, g_cipherUpdateMethod, inDataBytes);

if (outDataBytes && outm)
loc[inDataBytes] = make_java_byte_array(env, inl);
(*env)->SetByteArrayRegion(env, loc[inDataBytes], 0, inl, (jbyte*)in);
ON_EXCEPTION_PRINT_AND_GOTO(cleanup);
Comment thread
simonrozsival marked this conversation as resolved.

loc[outDataBytes] = (jbyteArray)(*env)->CallObjectMethod(env, ctx->cipher, g_cipherUpdateMethod, loc[inDataBytes]);
ON_EXCEPTION_PRINT_AND_GOTO(cleanup);

if (loc[outDataBytes] && outm)
{
jsize outDataBytesLen = (*env)->GetArrayLength(env, outDataBytes);
jsize outDataBytesLen = (*env)->GetArrayLength(env, loc[outDataBytes]);
(*env)->GetByteArrayRegion(env, loc[outDataBytes], 0, outDataBytesLen, (jbyte*) outm);
ON_EXCEPTION_PRINT_AND_GOTO(cleanup);
*outl = outDataBytesLen;
(*env)->GetByteArrayRegion(env, outDataBytes, 0, outDataBytesLen, (jbyte*) outm);
(*env)->DeleteLocalRef(env, outDataBytes);
}
ret = SUCCESS;

(*env)->DeleteLocalRef(env, inDataBytes);
return CheckJNIExceptions(env) ? FAIL : SUCCESS;
cleanup:
RELEASE_LOCALS(loc, env);
return ret;
}

int32_t AndroidCryptoNative_CipherFinalEx(CipherCtx* ctx, uint8_t* outm, int32_t* outl)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,24 +25,22 @@ int32_t AndroidCryptoNative_EcDsaSign(const uint8_t* dgst, int32_t dgstlen, uint
abort_if_invalid_pointer_argument (siglen);

JNIEnv* env = GetJNIEnv();
int32_t ret = FAIL;
INIT_LOCALS(loc, signatureObject, privateKey);

jobject signatureObject = GetEcDsaSignatureObject(env);
if (!signatureObject)
{
return FAIL;
}
loc[signatureObject] = GetEcDsaSignatureObject(env);
if (!loc[signatureObject])
goto cleanup;

jobject privateKey = (*env)->CallObjectMethod(env, key->keyPair, g_keyPairGetPrivateMethod);
if (!privateKey)
{
ReleaseLRef(env, signatureObject);
return FAIL;
}
loc[privateKey] = (*env)->CallObjectMethod(env, key->keyPair, g_keyPairGetPrivateMethod);
if (CheckJNIExceptions(env) || !loc[privateKey])
goto cleanup;

int32_t returnValue = AndroidCryptoNative_SignWithSignatureObject(env, signatureObject, privateKey, dgst, dgstlen, sig, siglen);
ReleaseLRef(env, privateKey);
ReleaseLRef(env, signatureObject);
return returnValue;
ret = AndroidCryptoNative_SignWithSignatureObject(env, loc[signatureObject], loc[privateKey], dgst, dgstlen, sig, siglen);

cleanup:
RELEASE_LOCALS(loc, env);
return ret;
}

int32_t AndroidCryptoNative_EcDsaVerify(const uint8_t* dgst, int32_t dgstlen, const uint8_t* sig, int32_t siglen, EC_KEY* key)
Expand Down
Loading
Loading