mirror of
https://github.com/corda/corda.git
synced 2025-06-18 15:18:16 +00:00
This reverts commitf46377556c
, reversing changes made toba675e73b9
.
This commit is contained in:
@ -0,0 +1,37 @@
|
||||
package net.corda.core.schemas;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class BadSchemaJavaV1 extends MappedSchema {
|
||||
|
||||
public BadSchemaJavaV1() {
|
||||
super(TestJavaSchemaFamily.class, 1, Arrays.asList(State.class));
|
||||
}
|
||||
|
||||
@Entity
|
||||
public static class State extends PersistentState {
|
||||
private String id;
|
||||
private GoodSchemaJavaV1.State other;
|
||||
|
||||
@Column
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@JoinColumns({@JoinColumn(name = "itid"), @JoinColumn(name = "outid")})
|
||||
@OneToOne
|
||||
@MapsId
|
||||
public GoodSchemaJavaV1.State getOther() {
|
||||
return other;
|
||||
}
|
||||
|
||||
public void setOther(GoodSchemaJavaV1.State other) {
|
||||
this.other = other;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package net.corda.core.schemas;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class BadSchemaNoGetterJavaV1 extends MappedSchema {
|
||||
|
||||
public BadSchemaNoGetterJavaV1() {
|
||||
super(TestJavaSchemaFamily.class, 1, Arrays.asList(State.class));
|
||||
}
|
||||
|
||||
@Entity
|
||||
public static class State extends PersistentState {
|
||||
@JoinColumns({@JoinColumn(name = "itid"), @JoinColumn(name = "outid")})
|
||||
@OneToOne
|
||||
@MapsId
|
||||
public GoodSchemaJavaV1.State other;
|
||||
private String id;
|
||||
|
||||
@Column
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package net.corda.core.schemas;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class GoodSchemaJavaV1 extends MappedSchema {
|
||||
|
||||
public GoodSchemaJavaV1() {
|
||||
super(TestJavaSchemaFamily.class, 1, Arrays.asList(State.class));
|
||||
}
|
||||
|
||||
@Entity
|
||||
public static class State extends PersistentState {
|
||||
private String id;
|
||||
|
||||
@Column
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package net.corda.core.schemas;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Transient;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class PoliteSchemaJavaV1 extends MappedSchema {
|
||||
|
||||
public PoliteSchemaJavaV1() {
|
||||
super(TestJavaSchemaFamily.class, 1, Arrays.asList(State.class));
|
||||
}
|
||||
|
||||
@Entity
|
||||
public static class State extends PersistentState {
|
||||
private String id;
|
||||
private GoodSchemaJavaV1.State other;
|
||||
|
||||
@Column
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Transient
|
||||
public GoodSchemaJavaV1.State getOther() {
|
||||
return other;
|
||||
}
|
||||
|
||||
public void setOther(GoodSchemaJavaV1.State other) {
|
||||
this.other = other;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
package net.corda.core.schemas;
|
||||
|
||||
public class TestJavaSchemaFamily {
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
package net.corda.core.schemas;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class TrickySchemaJavaV1 extends MappedSchema {
|
||||
|
||||
public TrickySchemaJavaV1() {
|
||||
super(TestJavaSchemaFamily.class, 1, Arrays.asList(TrickySchemaJavaV1.State.class));
|
||||
}
|
||||
|
||||
@Entity
|
||||
public static class State extends PersistentState {
|
||||
private String id;
|
||||
private GoodSchemaJavaV1.State other;
|
||||
|
||||
@Column
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
//the field is a cross-reference to other MappedSchema however the field is not persistent (no JPA annotation)
|
||||
public GoodSchemaJavaV1.State getOther() {
|
||||
return other;
|
||||
}
|
||||
|
||||
public void setOther(GoodSchemaJavaV1.State other) {
|
||||
this.other = other;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,125 @@
|
||||
package net.corda.core.internal
|
||||
|
||||
import net.corda.core.crypto.Crypto
|
||||
import net.i2p.crypto.eddsa.EdDSAEngine
|
||||
import net.i2p.crypto.eddsa.EdDSAPublicKey
|
||||
import org.junit.Test
|
||||
import sun.security.util.BitArray
|
||||
import sun.security.util.ObjectIdentifier
|
||||
import sun.security.x509.AlgorithmId
|
||||
import sun.security.x509.X509Key
|
||||
import java.math.BigInteger
|
||||
import java.security.InvalidKeyException
|
||||
import java.util.*
|
||||
import kotlin.test.assertFailsWith
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class TestX509Key(algorithmId: AlgorithmId, key: BitArray) : X509Key() {
|
||||
init {
|
||||
this.algid = algorithmId
|
||||
this.setKey(key)
|
||||
this.encode()
|
||||
}
|
||||
}
|
||||
|
||||
class X509EdDSAEngineTest {
|
||||
companion object {
|
||||
private const val SEED = 20170920L
|
||||
private const val TEST_DATA_SIZE = 2000
|
||||
|
||||
// offset into an EdDSA header indicating where the key header and actual key start
|
||||
// in the underlying byte array
|
||||
private const val keyHeaderStart = 9
|
||||
private const val keyStart = 12
|
||||
|
||||
private fun toX509Key(publicKey: EdDSAPublicKey): X509Key {
|
||||
val internals = publicKey.encoded
|
||||
|
||||
// key size in the header includes the count unused bits at the end of the key
|
||||
// [keyHeaderStart + 2] but NOT the key header ID [keyHeaderStart] so the
|
||||
// actual length of the key blob is size - 1
|
||||
val keySize = (internals[keyHeaderStart + 1].toInt()) - 1
|
||||
|
||||
val key = ByteArray(keySize)
|
||||
System.arraycopy(internals, keyStart, key, 0, keySize)
|
||||
|
||||
// 1.3.101.102 is the EdDSA OID
|
||||
return TestX509Key(AlgorithmId(ObjectIdentifier("1.3.101.112")), BitArray(keySize * 8, key))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Put the X509EdDSA engine through basic tests to verify that the functions are hooked up correctly.
|
||||
*/
|
||||
@Test
|
||||
fun `sign and verify`() {
|
||||
val engine = X509EdDSAEngine()
|
||||
val keyPair = Crypto.deriveKeyPairFromEntropy(Crypto.EDDSA_ED25519_SHA512, BigInteger.valueOf(SEED))
|
||||
val publicKey = keyPair.public as EdDSAPublicKey
|
||||
val randomBytes = ByteArray(TEST_DATA_SIZE)
|
||||
Random(SEED).nextBytes(randomBytes)
|
||||
engine.initSign(keyPair.private)
|
||||
engine.update(randomBytes[0])
|
||||
engine.update(randomBytes, 1, randomBytes.size - 1)
|
||||
|
||||
// Now verify the signature
|
||||
val signature = engine.sign()
|
||||
|
||||
engine.initVerify(publicKey)
|
||||
engine.update(randomBytes)
|
||||
assertTrue { engine.verify(signature) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that signing with an X509Key wrapped EdDSA key works.
|
||||
*/
|
||||
@Test
|
||||
fun `sign and verify with X509Key`() {
|
||||
val engine = X509EdDSAEngine()
|
||||
val keyPair = Crypto.deriveKeyPairFromEntropy(Crypto.EDDSA_ED25519_SHA512, BigInteger.valueOf(SEED + 1))
|
||||
val publicKey = toX509Key(keyPair.public as EdDSAPublicKey)
|
||||
val randomBytes = ByteArray(TEST_DATA_SIZE)
|
||||
Random(SEED + 1).nextBytes(randomBytes)
|
||||
engine.initSign(keyPair.private)
|
||||
engine.update(randomBytes[0])
|
||||
engine.update(randomBytes, 1, randomBytes.size - 1)
|
||||
|
||||
// Now verify the signature
|
||||
val signature = engine.sign()
|
||||
|
||||
engine.initVerify(publicKey)
|
||||
engine.update(randomBytes)
|
||||
assertTrue { engine.verify(signature) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that signing with an X509Key wrapped EdDSA key fails when using the underlying EdDSAEngine.
|
||||
*/
|
||||
@Test
|
||||
fun `sign and verify with X509Key and old engine fails`() {
|
||||
val engine = EdDSAEngine()
|
||||
val keyPair = Crypto.deriveKeyPairFromEntropy(Crypto.EDDSA_ED25519_SHA512, BigInteger.valueOf(SEED + 1))
|
||||
val publicKey = toX509Key(keyPair.public as EdDSAPublicKey)
|
||||
val randomBytes = ByteArray(TEST_DATA_SIZE)
|
||||
Random(SEED + 1).nextBytes(randomBytes)
|
||||
engine.initSign(keyPair.private)
|
||||
engine.update(randomBytes[0])
|
||||
engine.update(randomBytes, 1, randomBytes.size - 1)
|
||||
|
||||
// Now verify the signature
|
||||
val signature = engine.sign()
|
||||
assertFailsWith<InvalidKeyException> {
|
||||
engine.initVerify(publicKey)
|
||||
engine.update(randomBytes)
|
||||
engine.verify(signature)
|
||||
}
|
||||
}
|
||||
|
||||
/** Verify will fail if the input public key cannot be converted to EdDSA public key. */
|
||||
@Test
|
||||
fun `verify with non-supported key type fails`() {
|
||||
val engine = EdDSAEngine()
|
||||
val keyPair = Crypto.deriveKeyPairFromEntropy(Crypto.ECDSA_SECP256K1_SHA256, BigInteger.valueOf(SEED))
|
||||
assertFailsWith<InvalidKeyException> { engine.initVerify(keyPair.public) }
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
package net.corda.core.schemas
|
||||
|
||||
import java.util.*
|
||||
import javax.persistence.*
|
||||
|
||||
class BadSchemaNoGetterV1 : MappedSchema(TestJavaSchemaFamily::class.java, 1, Arrays.asList(State::class.java)) {
|
||||
|
||||
@Entity
|
||||
class State : PersistentState() {
|
||||
@JoinColumns(JoinColumn(name = "itid"), JoinColumn(name = "outid"))
|
||||
@OneToOne
|
||||
@MapsId
|
||||
var other: GoodSchemaV1.State? = null
|
||||
@get:Column
|
||||
var id: String? = null
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
package net.corda.core.schemas
|
||||
|
||||
import java.util.*
|
||||
import javax.persistence.*
|
||||
|
||||
class BadSchemaV1 : MappedSchema(TestJavaSchemaFamily::class.java, 1, Arrays.asList(State::class.java)) {
|
||||
|
||||
@Entity
|
||||
class State : PersistentState() {
|
||||
@get:Column
|
||||
var id: String? = null
|
||||
@get:JoinColumns(JoinColumn(name = "itid"), JoinColumn(name = "outid"))
|
||||
@get:OneToOne
|
||||
@get:MapsId
|
||||
var other: GoodSchemaV1.State? = null
|
||||
}
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
package net.corda.core.schemas
|
||||
|
||||
import java.util.*
|
||||
import javax.persistence.Column
|
||||
import javax.persistence.Entity
|
||||
|
||||
class GoodSchemaV1 : MappedSchema(TestJavaSchemaFamily::class.java, 1, Arrays.asList(State::class.java)) {
|
||||
|
||||
@Entity
|
||||
class State : PersistentState() {
|
||||
@get:Column
|
||||
var id: String? = null
|
||||
}
|
||||
}
|
@ -78,31 +78,31 @@ class MappedSchemasCrossReferenceDetectionTests {
|
||||
|
||||
@Test
|
||||
fun `no cross reference to other schema java`() {
|
||||
assertThat(fieldsFromOtherMappedSchema(GoodSchemaV1())).isEmpty()
|
||||
assertThat(methodsFromOtherMappedSchema(GoodSchemaV1())).isEmpty()
|
||||
assertThat(fieldsFromOtherMappedSchema(GoodSchemaJavaV1())).isEmpty()
|
||||
assertThat(methodsFromOtherMappedSchema(GoodSchemaJavaV1())).isEmpty()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `cross reference to other schema is detected java`() {
|
||||
assertThat(fieldsFromOtherMappedSchema(BadSchemaV1())).isEmpty()
|
||||
assertThat(methodsFromOtherMappedSchema(BadSchemaV1())).isNotEmpty
|
||||
assertThat(fieldsFromOtherMappedSchema(BadSchemaJavaV1())).isEmpty()
|
||||
assertThat(methodsFromOtherMappedSchema(BadSchemaJavaV1())).isNotEmpty
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `cross reference to other schema via field is detected java`() {
|
||||
assertThat(fieldsFromOtherMappedSchema(BadSchemaNoGetterV1())).isNotEmpty
|
||||
assertThat(methodsFromOtherMappedSchema(BadSchemaNoGetterV1())).isEmpty()
|
||||
assertThat(fieldsFromOtherMappedSchema(BadSchemaNoGetterJavaV1())).isNotEmpty
|
||||
assertThat(methodsFromOtherMappedSchema(BadSchemaNoGetterJavaV1())).isEmpty()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `cross reference via non JPA field is allowed java`() {
|
||||
assertThat(fieldsFromOtherMappedSchema(TrickySchemaV1())).isEmpty()
|
||||
assertThat(methodsFromOtherMappedSchema(TrickySchemaV1())).isEmpty()
|
||||
assertThat(fieldsFromOtherMappedSchema(TrickySchemaJavaV1())).isEmpty()
|
||||
assertThat(methodsFromOtherMappedSchema(TrickySchemaJavaV1())).isEmpty()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `cross reference via transient field is allowed java`() {
|
||||
assertThat(fieldsFromOtherMappedSchema(PoliteSchemaV1())).isEmpty()
|
||||
assertThat(methodsFromOtherMappedSchema(PoliteSchemaV1())).isEmpty()
|
||||
assertThat(fieldsFromOtherMappedSchema(PoliteSchemaJavaV1())).isEmpty()
|
||||
assertThat(methodsFromOtherMappedSchema(PoliteSchemaJavaV1())).isEmpty()
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
package net.corda.core.schemas
|
||||
|
||||
import java.util.*
|
||||
import javax.persistence.Column
|
||||
import javax.persistence.Entity
|
||||
import javax.persistence.Transient
|
||||
|
||||
class PoliteSchemaV1 : MappedSchema(TestJavaSchemaFamily::class.java, 1, Arrays.asList(State::class.java)) {
|
||||
|
||||
@Entity
|
||||
class State : PersistentState() {
|
||||
@get:Column
|
||||
var id: String? = null
|
||||
@get:Transient
|
||||
var other: GoodSchemaV1.State? = null
|
||||
}
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
package net.corda.core.schemas
|
||||
|
||||
class TestJavaSchemaFamily
|
@ -1,16 +0,0 @@
|
||||
package net.corda.core.schemas
|
||||
|
||||
import java.util.*
|
||||
import javax.persistence.Column
|
||||
import javax.persistence.Entity
|
||||
|
||||
class TrickySchemaV1 : MappedSchema(TestJavaSchemaFamily::class.java, 1, Arrays.asList(TrickySchemaV1.State::class.java)) {
|
||||
|
||||
@Entity
|
||||
class State : PersistentState() {
|
||||
@get:Column
|
||||
var id: String? = null
|
||||
//the field is a cross-reference to other MappedSchema however the field is not persistent (no JPA annotation)
|
||||
var other: GoodSchemaV1.State? = null
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user