Skip to content
Closed
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
41 changes: 0 additions & 41 deletions common/src/jni/main/cpp/conscrypt/native_crypto.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1584,46 +1584,6 @@ static jbyteArray NativeCrypto_EVP_PKEY_get_private_seed(JNIEnv* env, jclass cls
return seedArray.release();
}

static jbyteArray NativeCrypto_EVP_raw_X25519_private_key(
JNIEnv* env, jclass cls, jbyteArray keyJavaBytes) {
CHECK_ERROR_QUEUE_ON_RETURN;
JNI_TRACE("NativeCrypto_EVP_raw_X25519_private_key(%p)", keyJavaBytes);

jlong key_ptr = NativeCrypto_EVP_parse_private_key(env, cls, keyJavaBytes);
if (key_ptr == 0) {
return nullptr;
}
bssl::UniquePtr<EVP_PKEY> pkey(reinterpret_cast<EVP_PKEY*>(key_ptr));
if (EVP_PKEY_id(pkey.get()) != EVP_PKEY_X25519) {
conscrypt::jniutil::throwInvalidKeyException(env, "Invalid key type");
return nullptr;
}

size_t key_length = X25519_PRIVATE_KEY_LEN;
ScopedLocalRef<jbyteArray> byteArray(env, env->NewByteArray(static_cast<jsize>(key_length)));
if (byteArray.get() == nullptr) {
conscrypt::jniutil::throwOutOfMemory(env, "Allocating byte[]");
JNI_TRACE("NativeCrypto_EVP_raw_X25519_private_key: byte array creation failed");
return nullptr;
}

ScopedByteArrayRW bytes(env, byteArray.get());
if (bytes.get() == nullptr) {
conscrypt::jniutil::throwOutOfMemory(env, "Allocating scoped byte array");
JNI_TRACE("NativeCrypto_EVP_raw_X25519_private_key: scoped byte array failed");
return nullptr;
}

if (EVP_PKEY_get_raw_private_key(
pkey.get(), reinterpret_cast<uint8_t *>(bytes.get()), &key_length) == 0) {
conscrypt::jniutil::throwExceptionFromBoringSSLError(env, "EVP_PKEY_get_raw_private_key");
return nullptr;
}
jbyteArray result = byteArray.release();
JNI_TRACE("bytes=%p NativeCrypto_EVP_raw_X25519_private_key => %p", keyJavaBytes, result);
return result;
}

/*
* static native byte[] EVP_marshal_public_key(long)
*/
Expand Down Expand Up @@ -12238,7 +12198,6 @@ static JNINativeMethod sNativeCryptoMethods[] = {
CONSCRYPT_NATIVE_METHOD(EVP_PKEY_get_raw_public_key, "(" REF_EVP_PKEY ")[B"),
CONSCRYPT_NATIVE_METHOD(EVP_PKEY_from_private_seed, "(I[B)J"),
CONSCRYPT_NATIVE_METHOD(EVP_PKEY_get_private_seed, "(" REF_EVP_PKEY ")[B"),
CONSCRYPT_NATIVE_METHOD(EVP_raw_X25519_private_key, "([B)[B"),
CONSCRYPT_NATIVE_METHOD(EVP_marshal_public_key, "(" REF_EVP_PKEY ")[B"),
CONSCRYPT_NATIVE_METHOD(EVP_parse_public_key, "([B)J"),
CONSCRYPT_NATIVE_METHOD(PEM_read_bio_PUBKEY, "(J)J"),
Expand Down
3 changes: 0 additions & 3 deletions common/src/main/java/org/conscrypt/NativeCrypto.java
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,6 @@ static native long EVP_PKEY_from_subject_public_key_info(byte[] data, int[] algs

static native byte[] EVP_PKEY_get_private_seed(NativeRef.EVP_PKEY pkey);

static native byte[] EVP_raw_X25519_private_key(byte[] data)
throws ParsingException, InvalidKeyException;

static native long EVP_parse_public_key(byte[] data) throws ParsingException;

static native long PEM_read_bio_PUBKEY(long bioCtx);
Expand Down
23 changes: 11 additions & 12 deletions common/src/main/java/org/conscrypt/OpenSSLX25519PrivateKey.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,13 @@
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.security.InvalidKeyException;
import java.security.PrivateKey;
import java.security.spec.EncodedKeySpec;
import java.security.spec.InvalidKeySpecException;
import java.util.Arrays;

public class OpenSSLX25519PrivateKey implements OpenSSLX25519Key, PrivateKey {
private static final long serialVersionUID = -3136201500221850916L;
private static final byte[] PKCS8_PREAMBLE = new byte[]{
0x30, 0x2e, // Sequence: 46 bytes
0x02, 0x01, 0x00, // Integer: 0 (version)
0x30, 0x05, // Sequence: 5 bytes
0x06, 0x03, 0x2b, 0x65, 0x6e, // OID: 1.3.101.110 (X25519)
0x04, 0x22, 0x04, 0x20, // Octet string: 32 bytes
// Key bytes follow directly
};

private byte[] uCoordinate;

Expand All @@ -45,8 +36,10 @@ public OpenSSLX25519PrivateKey(EncodedKeySpec keySpec)
byte[] encoded = keySpec.getEncoded();
if ("PKCS#8".equals(keySpec.getFormat())) {
try {
uCoordinate = NativeCrypto.EVP_raw_X25519_private_key(encoded);
} catch (InvalidKeyException | ParsingException e) {
OpenSSLKey key = new OpenSSLKey(NativeCrypto.EVP_PKEY_from_private_key_info(
encoded, new int[] {NativeConstants.EVP_PKEY_X25519}));
uCoordinate = NativeCrypto.EVP_PKEY_get_raw_private_key(key.getNativeRef());
} catch (ParsingException e) {
throw new InvalidKeySpecException(e);
}
} else if ("raw".equalsIgnoreCase(keySpec.getFormat())) {
Expand Down Expand Up @@ -81,7 +74,13 @@ public byte[] getEncoded() {
if (uCoordinate == null) {
throw new IllegalStateException("key is destroyed");
}
return ArrayUtils.concat(PKCS8_PREAMBLE, uCoordinate);
try {
OpenSSLKey key = new OpenSSLKey(NativeCrypto.EVP_PKEY_from_raw_private_key(
NativeConstants.EVP_PKEY_X25519, uCoordinate));
return NativeCrypto.EVP_marshal_private_key(key.getNativeRef());
} catch (ParsingException e) {
throw new IllegalStateException("unable to create key", e);
}
}

@Override
Expand Down
32 changes: 15 additions & 17 deletions common/src/main/java/org/conscrypt/OpenSSLX25519PublicKey.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

package org.conscrypt;

import org.conscrypt.OpenSSLX509CertificateFactory.ParsingException;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
Expand All @@ -27,27 +29,18 @@
public class OpenSSLX25519PublicKey implements OpenSSLX25519Key, PublicKey {
private static final long serialVersionUID = 453861992373478445L;

private static final byte[] X509_PREAMBLE = new byte[] {
0x30, 0x2a, // Sequence: 42 bytes
0x30, 0x05, // Sequence: 5 bytes
0x06, 0x03, 0x2b, 0x65, 0x6e, // OID: 1.3.101.110 (X25519)
0x03, 0x21, 0x00, // Bit string: 256 bits
// Key bytes follow directly
};

private final byte[] uCoordinate;

public OpenSSLX25519PublicKey(EncodedKeySpec keySpec) throws InvalidKeySpecException {
byte[] encoded = keySpec.getEncoded();
if ("X.509".equals(keySpec.getFormat())) {
if (!ArrayUtils.startsWith(encoded, X509_PREAMBLE)) {
throw new InvalidKeySpecException("Invalid format");
}
int totalLength = X509_PREAMBLE.length + X25519_KEY_SIZE_BYTES;
if (encoded.length < totalLength) {
throw new InvalidKeySpecException("Invalid key size");
try {
OpenSSLKey key = new OpenSSLKey(NativeCrypto.EVP_PKEY_from_subject_public_key_info(
encoded, new int[] {NativeConstants.EVP_PKEY_X25519}));
uCoordinate = NativeCrypto.EVP_PKEY_get_raw_public_key(key.getNativeRef());
} catch (ParsingException e) {
throw new InvalidKeySpecException("Invalid format", e);
}
uCoordinate = Arrays.copyOfRange(encoded, X509_PREAMBLE.length, totalLength);
} else if ("raw".equalsIgnoreCase(keySpec.getFormat())) {
if (encoded.length != X25519_KEY_SIZE_BYTES) {
throw new InvalidKeySpecException("Invalid key size");
Expand Down Expand Up @@ -80,8 +73,13 @@ public byte[] getEncoded() {
if (uCoordinate == null) {
throw new IllegalStateException("key is destroyed");
}

return ArrayUtils.concat(X509_PREAMBLE, uCoordinate);
try {
OpenSSLKey key = new OpenSSLKey(NativeCrypto.EVP_PKEY_from_raw_public_key(
NativeConstants.EVP_PKEY_X25519, uCoordinate));
return NativeCrypto.EVP_marshal_public_key(key.getNativeRef());
} catch (ParsingException e) {
throw new IllegalStateException("unable to create key", e);
}
}

@Override
Expand Down
Loading