mirror of
https://github.com/corda/corda.git
synced 2025-02-07 03:29:19 +00:00
Remove verify-enclave
This commit is contained in:
parent
dcfcd4f64b
commit
013f1a3cb6
23
.idea/compiler.xml
generated
23
.idea/compiler.xml
generated
@ -45,6 +45,8 @@
|
||||
<module name="capsule-hsm_test" target="1.8" />
|
||||
<module name="client_main" target="1.8" />
|
||||
<module name="client_test" target="1.8" />
|
||||
<module name="common_main" target="1.8" />
|
||||
<module name="common_test" target="1.8" />
|
||||
<module name="confidential-identities_main" target="1.8" />
|
||||
<module name="confidential-identities_test" target="1.8" />
|
||||
<module name="contracts-states_integrationTest" target="1.8" />
|
||||
@ -53,6 +55,8 @@
|
||||
<module name="corda-core_integrationTest" target="1.8" />
|
||||
<module name="corda-core_smokeTest" target="1.8" />
|
||||
<module name="corda-finance_integrationTest" target="1.8" />
|
||||
<module name="corda-project-testing_main" target="1.8" />
|
||||
<module name="corda-project-testing_test" target="1.8" />
|
||||
<module name="corda-project-tools_main" target="1.8" />
|
||||
<module name="corda-project-tools_test" target="1.8" />
|
||||
<module name="corda-project_main" target="1.8" />
|
||||
@ -73,11 +77,17 @@
|
||||
<module name="cordformation_main" target="1.8" />
|
||||
<module name="cordformation_runnodes" target="1.8" />
|
||||
<module name="cordformation_test" target="1.8" />
|
||||
<module name="core-deterministic-testing_main" target="1.8" />
|
||||
<module name="core-deterministic-testing_test" target="1.8" />
|
||||
<module name="core-deterministic_main" target="1.8" />
|
||||
<module name="core-deterministic_test" target="1.8" />
|
||||
<module name="core_extraResource" target="1.8" />
|
||||
<module name="core_integrationTest" target="1.8" />
|
||||
<module name="core_main" target="1.8" />
|
||||
<module name="core_smokeTest" target="1.8" />
|
||||
<module name="core_test" target="1.8" />
|
||||
<module name="data_main" target="1.8" />
|
||||
<module name="data_test" target="1.8" />
|
||||
<module name="dbmigration_main" target="1.8" />
|
||||
<module name="dbmigration_test" target="1.8" />
|
||||
<module name="demobench_main" target="1.8" />
|
||||
@ -122,6 +132,8 @@
|
||||
<module name="graphs_test" target="1.8" />
|
||||
<module name="ha-testing_main" target="1.8" />
|
||||
<module name="ha-testing_test" target="1.8" />
|
||||
<module name="hsm-tool_main" target="1.8" />
|
||||
<module name="hsm-tool_test" target="1.8" />
|
||||
<module name="intellij-plugin_main" target="1.8" />
|
||||
<module name="intellij-plugin_test" target="1.8" />
|
||||
<module name="irs-demo-cordapp_integrationTest" target="1.8" />
|
||||
@ -139,6 +151,10 @@
|
||||
<module name="isolated_test" target="1.8" />
|
||||
<module name="jackson_main" target="1.8" />
|
||||
<module name="jackson_test" target="1.8" />
|
||||
<module name="jarfilter_main" target="1.8" />
|
||||
<module name="jarfilter_test" target="1.8" />
|
||||
<module name="jdk8u-deterministic_main" target="1.8" />
|
||||
<module name="jdk8u-deterministic_test" target="1.8" />
|
||||
<module name="jfx_integrationTest" target="1.8" />
|
||||
<module name="jfx_main" target="1.8" />
|
||||
<module name="jfx_test" target="1.8" />
|
||||
@ -200,10 +216,15 @@
|
||||
<module name="samples_test" target="1.8" />
|
||||
<module name="sandbox_main" target="1.8" />
|
||||
<module name="sandbox_test" target="1.8" />
|
||||
<module name="serialization-deterministic_main" target="1.8" />
|
||||
<module name="serialization-deterministic_test" target="1.8" />
|
||||
<module name="serialization_main" target="1.8" />
|
||||
<module name="serialization_test" target="1.8" />
|
||||
<module name="sgx-hsm-tool_main" target="1.8" />
|
||||
<module name="sgx-hsm-tool_test" target="1.8" />
|
||||
<module name="shell-cli_integrationTest" target="1.8" />
|
||||
<module name="shell-cli_main" target="1.8" />
|
||||
<module name="shell-cli_test" target="1.8" />
|
||||
<module name="shell_integrationTest" target="1.8" />
|
||||
<module name="shell_main" target="1.8" />
|
||||
<module name="shell_test" target="1.8" />
|
||||
@ -239,6 +260,8 @@
|
||||
<module name="trader-demo_integrationTest" target="1.8" />
|
||||
<module name="trader-demo_main" target="1.8" />
|
||||
<module name="trader-demo_test" target="1.8" />
|
||||
<module name="unwanteds_main" target="1.8" />
|
||||
<module name="unwanteds_test" target="1.8" />
|
||||
<module name="verifier_integrationTest" target="1.8" />
|
||||
<module name="verifier_main" target="1.8" />
|
||||
<module name="verifier_test" target="1.8" />
|
||||
|
@ -82,11 +82,6 @@ include 'samples:cordapp-configuration'
|
||||
include 'serialization'
|
||||
include 'serialization-deterministic'
|
||||
include 'cordform-common'
|
||||
include 'verify-enclave'
|
||||
include 'hsm-tool'
|
||||
project(':hsm-tool').with {
|
||||
name = 'sgx-hsm-tool'
|
||||
projectDir = file("$settingsDir/sgx-jvm/hsm-tool")
|
||||
}
|
||||
include 'launcher'
|
||||
include 'node:dist'
|
||||
|
@ -1 +0,0 @@
|
||||
To build the enclavelet just run ./gradlew verify-enclave:jar
|
@ -1,97 +0,0 @@
|
||||
apply plugin: 'kotlin'
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
maven {
|
||||
url 'http://oss.sonatype.org/content/repositories/snapshots'
|
||||
}
|
||||
jcenter()
|
||||
maven {
|
||||
url 'https://dl.bintray.com/kotlin/exposed'
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* R3 Proprietary and Confidential
|
||||
*
|
||||
* Copyright (c) 2018 R3 Limited. All rights reserved.
|
||||
*
|
||||
* The intellectual and technical concepts contained herein are proprietary to R3 and its suppliers and are protected by trade secret law.
|
||||
*
|
||||
* Distribution of this file or any portion thereof via any medium without the express permission of R3 is strictly prohibited.
|
||||
*/
|
||||
|
||||
//noinspection GroovyAssignabilityCheck
|
||||
configurations {
|
||||
// we don't want isolated.jar in classPath, since we want to test jar being dynamically loaded as an attachment
|
||||
runtime.exclude module: 'isolated'
|
||||
|
||||
integrationTestCompile.extendsFrom testCompile
|
||||
integrationTestRuntime.extendsFrom testRuntime
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
integrationTest {
|
||||
kotlin {
|
||||
compileClasspath += main.output + test.output
|
||||
runtimeClasspath += main.output + test.output
|
||||
srcDir file('src/integration-test/kotlin')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile project(':core')
|
||||
compile project(':finance')
|
||||
// This is added so that we include node-api/src/main/resources/META-INF/services/net.corda.core.node.CordaPluginRegistry
|
||||
// which is needed for the serialisation whitelist initialisation.
|
||||
// TODO think about this.
|
||||
compile project(':node-api')
|
||||
|
||||
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
||||
compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
|
||||
testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
|
||||
|
||||
testCompile project(':node-driver')
|
||||
}
|
||||
|
||||
jar {
|
||||
|
||||
// De-duplicate dependencies - otherwise, they will appear multiple times in the resulting JAR file, which in turn
|
||||
// will confuse ProGuard in the processing step in sgx-jvm/jvm-enclave.
|
||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||
|
||||
from '../node/capsule/NOTICE' // Copy CDDL notice
|
||||
// Create a fat jar by packing all deps into the output
|
||||
from {
|
||||
configurations.runtime.collect { it.isDirectory() ? it : zipTree(it) }
|
||||
}
|
||||
exclude "META-INF/*.DSA"
|
||||
exclude "META-INF/*.RSA"
|
||||
exclude "META-INF/*.SF"
|
||||
exclude "META-INF/*.MF"
|
||||
archiveName "corda-enclavelet.jar"
|
||||
manifest {
|
||||
attributes(
|
||||
'Main-Class': 'com.r3.enclaves.txverify.Enclavelet',
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
task integrationTest(type: Test) {
|
||||
testClassesDirs = sourceSets.integrationTest.output.classesDirs
|
||||
classpath = sourceSets.integrationTest.runtimeClasspath
|
||||
systemProperties['java.library.path'] = '../sgx-jvm/jvm-enclave/jni/build'
|
||||
}
|
||||
|
||||
test {
|
||||
// Pending Gradle bug: https://github.com/gradle/gradle/issues/2657
|
||||
//systemProperties['java.system.class.loader'] = 'com.r3.enclaves.DummySystemClassLoader'
|
||||
}
|
||||
|
||||
task generateNativeSgxHeaders(type: Exec) {
|
||||
def classpath = sourceSets.main.output.classesDirs.asPath
|
||||
commandLine "javah", "-o", "$buildDir/native/include/jni_sgx_api.h", "-cp", classpath, "com.r3.enclaves.txverify.NativeSgxApi"
|
||||
dependsOn classes
|
||||
}
|
@ -1,86 +0,0 @@
|
||||
/*
|
||||
* R3 Proprietary and Confidential
|
||||
*
|
||||
* Copyright (c) 2018 R3 Limited. All rights reserved.
|
||||
*
|
||||
* The intellectual and technical concepts contained herein are proprietary to R3 and its suppliers and are protected by trade secret law.
|
||||
*
|
||||
* Distribution of this file or any portion thereof via any medium without the express permission of R3 is strictly prohibited.
|
||||
*/
|
||||
|
||||
package com.r3.enclaves.verify
|
||||
|
||||
import com.nhaarman.mockito_kotlin.doReturn
|
||||
import com.nhaarman.mockito_kotlin.whenever
|
||||
import com.r3.enclaves.txverify.MockContractAttachment
|
||||
import com.r3.enclaves.txverify.NativeSgxApi
|
||||
import com.r3.enclaves.txverify.TransactionVerificationRequest
|
||||
import net.corda.core.crypto.entropyToKeyPair
|
||||
import net.corda.core.identity.AnonymousParty
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.serialization.serialize
|
||||
import net.corda.finance.POUNDS
|
||||
import net.corda.finance.`issued by`
|
||||
import net.corda.finance.contracts.asset.Cash
|
||||
import net.corda.node.services.api.IdentityServiceInternal
|
||||
import net.corda.testing.core.DUMMY_NOTARY_NAME
|
||||
import net.corda.testing.core.TestIdentity
|
||||
import net.corda.testing.core.getTestPartyAndCertificate
|
||||
import net.corda.testing.internal.rigorousMock
|
||||
import net.corda.testing.node.MockServices
|
||||
import net.corda.testing.node.ledger
|
||||
import org.junit.Ignore
|
||||
import org.junit.Test
|
||||
import java.math.BigInteger
|
||||
import kotlin.test.assertNull
|
||||
|
||||
class NativeSgxApiTest {
|
||||
companion object {
|
||||
val enclavePath = "../sgx-jvm/jvm-enclave/enclave/build/cordaenclave.signed.so"
|
||||
val DUMMY_NOTARY = TestIdentity(DUMMY_NOTARY_NAME, 20).party
|
||||
val DUMMY_CASH_ISSUER_KEY = entropyToKeyPair(BigInteger.valueOf(10))
|
||||
val DUMMY_CASH_ISSUER_IDENTITY = getTestPartyAndCertificate(Party(CordaX500Name("Snake Oil Issuer", "London", "GB"), DUMMY_CASH_ISSUER_KEY.public))
|
||||
val DUMMY_CASH_ISSUER = DUMMY_CASH_ISSUER_IDENTITY.party.ref(1)
|
||||
val megaCorp = TestIdentity(CordaX500Name("MegaCorp", "London", "GB"))
|
||||
val MEGA_CORP get() = megaCorp.party
|
||||
val MEGA_CORP_PUBKEY get() = megaCorp.keyPair.public
|
||||
val MINI_CORP_PUBKEY = TestIdentity(CordaX500Name("MiniCorp", "London", "GB")).keyPair.public
|
||||
}
|
||||
|
||||
private val ledgerServices = MockServices(emptyList(), NativeSgxApiTest.MEGA_CORP.name, rigorousMock<IdentityServiceInternal>().also {
|
||||
doReturn(NativeSgxApiTest.MEGA_CORP).whenever(it).partyFromKey(NativeSgxApiTest.MEGA_CORP_PUBKEY)
|
||||
})
|
||||
|
||||
@Ignore("The SGX code is not part of the standard build yet")
|
||||
@Test
|
||||
fun `verification of valid transaction works`() {
|
||||
ledgerServices.ledger(DUMMY_NOTARY) {
|
||||
// Issue a couple of cash states and spend them.
|
||||
val wtx1 = transaction {
|
||||
attachments(Cash.PROGRAM_ID)
|
||||
output(Cash.PROGRAM_ID, "c1", Cash.State(1000.POUNDS `issued by` DUMMY_CASH_ISSUER, AnonymousParty(MEGA_CORP_PUBKEY)))
|
||||
command(DUMMY_CASH_ISSUER.party.owningKey, Cash.Commands.Issue())
|
||||
verifies()
|
||||
}
|
||||
val wtx2 = transaction {
|
||||
attachments(Cash.PROGRAM_ID)
|
||||
output(Cash.PROGRAM_ID, "c2", Cash.State(2000.POUNDS `issued by` DUMMY_CASH_ISSUER, AnonymousParty(MEGA_CORP_PUBKEY)))
|
||||
command(DUMMY_CASH_ISSUER.party.owningKey, Cash.Commands.Issue())
|
||||
verifies()
|
||||
}
|
||||
val wtx3 = transaction {
|
||||
attachments(Cash.PROGRAM_ID)
|
||||
input("c1")
|
||||
input("c2")
|
||||
output(Cash.PROGRAM_ID, "c3", Cash.State(3000.POUNDS `issued by` DUMMY_CASH_ISSUER, AnonymousParty(MINI_CORP_PUBKEY)))
|
||||
command(MEGA_CORP_PUBKEY, Cash.Commands.Move())
|
||||
verifies()
|
||||
}
|
||||
val cashContract = MockContractAttachment(interpreter.services.cordappProvider.getContractAttachmentID(Cash.PROGRAM_ID)!!, Cash.PROGRAM_ID)
|
||||
val req = TransactionVerificationRequest(wtx3.serialize(), arrayOf(wtx1.serialize(), wtx2.serialize()), arrayOf(cashContract.serialize().bytes))
|
||||
val serialized = req.serialize()
|
||||
assertNull(NativeSgxApi.verify(enclavePath, serialized.bytes))
|
||||
}
|
||||
}
|
||||
}
|
@ -1,89 +0,0 @@
|
||||
/*
|
||||
* R3 Proprietary and Confidential
|
||||
*
|
||||
* Copyright (c) 2018 R3 Limited. All rights reserved.
|
||||
*
|
||||
* The intellectual and technical concepts contained herein are proprietary to R3 and its suppliers and are protected by trade secret law.
|
||||
*
|
||||
* Distribution of this file or any portion thereof via any medium without the express permission of R3 is strictly prohibited.
|
||||
*/
|
||||
|
||||
@file:JvmName("Enclavelet")
|
||||
|
||||
package com.r3.enclaves.txverify
|
||||
|
||||
import net.corda.core.contracts.Attachment
|
||||
import net.corda.core.serialization.CordaSerializable
|
||||
import net.corda.core.serialization.SerializedBytes
|
||||
import net.corda.core.serialization.deserialize
|
||||
import net.corda.core.transactions.LedgerTransaction
|
||||
import net.corda.core.transactions.WireTransaction
|
||||
import java.io.File
|
||||
|
||||
// This file implements the functionality of the SGX transaction verification enclave.
|
||||
|
||||
/** This is just used to simplify marshalling across the enclave boundary (EDL is a bit awkward) */
|
||||
@CordaSerializable
|
||||
class TransactionVerificationRequest(private val wtxToVerify: SerializedBytes<WireTransaction>,
|
||||
private val dependencies: Array<SerializedBytes<WireTransaction>>,
|
||||
val attachments: Array<ByteArray>) {
|
||||
fun toLedgerTransaction(): LedgerTransaction {
|
||||
val deps = dependencies.map { it.deserialize() }.associateBy(WireTransaction::id)
|
||||
val attachments = attachments.map { it.deserialize<Attachment>() }
|
||||
val attachmentMap = attachments.associateBy(Attachment::id)
|
||||
val contractAttachmentMap = attachments.mapNotNull { it as? MockContractAttachment }.associateBy(MockContractAttachment::contract)
|
||||
return wtxToVerify.deserialize().toLedgerTransaction(
|
||||
resolveIdentity = { null },
|
||||
resolveAttachment = { attachmentMap[it] },
|
||||
resolveStateRef = { deps[it.txhash]?.outputs?.get(it.index) },
|
||||
resolveContractAttachment = { contractAttachmentMap[it.contract]?.id }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns either null to indicate success when the transactions are validated, or a string with the
|
||||
* contents of the error. Invoked via JNI in response to an enclave RPC. The argument is a serialised
|
||||
* [TransactionVerificationRequest].
|
||||
*
|
||||
* Note that it is assumed the signatures were already checked outside the sandbox: the purpose of this code
|
||||
* is simply to check the sensitive, app specific parts of a transaction.
|
||||
*
|
||||
* TODO: Transaction data is meant to be encrypted under an enclave-private key.
|
||||
*/
|
||||
@Throws(Exception::class)
|
||||
fun verifyInEnclave(reqBytes: ByteArray) {
|
||||
var ex: Throwable? = null
|
||||
val ltx = deserialise(reqBytes)
|
||||
// Prevent this thread from linking new classes against any
|
||||
// blacklisted classes, e.g. ones needed by Kryo or by the
|
||||
// JVM itself. Note that java.lang.Thread is also blacklisted.
|
||||
Thread {
|
||||
ltx.verify()
|
||||
}.apply {
|
||||
startClassBlacklisting(this)
|
||||
setUncaughtExceptionHandler { _, e -> ex = e }
|
||||
start()
|
||||
join()
|
||||
}
|
||||
throw ex ?: return
|
||||
}
|
||||
|
||||
private fun startClassBlacklisting(t: Thread) {
|
||||
val systemClassLoader = ClassLoader.getSystemClassLoader()
|
||||
systemClassLoader.javaClass.getMethod("startBlacklisting", t.javaClass).apply {
|
||||
invoke(systemClassLoader, t)
|
||||
}
|
||||
}
|
||||
|
||||
private fun deserialise(reqBytes: ByteArray): LedgerTransaction {
|
||||
return reqBytes.deserialize<TransactionVerificationRequest>()
|
||||
.toLedgerTransaction()
|
||||
}
|
||||
|
||||
// Note: This is only here for debugging purposes
|
||||
fun main(args: Array<String>) {
|
||||
Class.forName("com.r3.enclaves.txverify.EnclaveletSerializationScheme")
|
||||
val reqBytes = File(args[0]).readBytes()
|
||||
verifyInEnclave(reqBytes)
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
/*
|
||||
* R3 Proprietary and Confidential
|
||||
*
|
||||
* Copyright (c) 2018 R3 Limited. All rights reserved.
|
||||
*
|
||||
* The intellectual and technical concepts contained herein are proprietary to R3 and its suppliers and are protected by trade secret law.
|
||||
*
|
||||
* Distribution of this file or any portion thereof via any medium without the express permission of R3 is strictly prohibited.
|
||||
*/
|
||||
|
||||
@file:JvmName("EnclaveletSerializationScheme")
|
||||
package com.r3.enclaves.txverify
|
||||
|
||||
import net.corda.core.serialization.SerializationContext
|
||||
import net.corda.core.serialization.internal.SerializationEnvironmentImpl
|
||||
import net.corda.core.serialization.internal.nodeSerializationEnv
|
||||
import net.corda.core.utilities.toHexString
|
||||
import net.corda.serialization.internal.AMQP_P2P_CONTEXT
|
||||
import net.corda.serialization.internal.CordaSerializationMagic
|
||||
import net.corda.serialization.internal.SerializationFactoryImpl
|
||||
import net.corda.serialization.internal.amqp.AbstractAMQPSerializationScheme
|
||||
import net.corda.serialization.internal.amqp.SerializerFactory
|
||||
import net.corda.serialization.internal.amqp.amqpMagic
|
||||
|
||||
@Suppress("UNUSED")
|
||||
private class EnclaveletSerializationScheme {
|
||||
/*
|
||||
* Registers the serialisation schemes as soon as this class is loaded into the JVM.
|
||||
*/
|
||||
private companion object {
|
||||
init {
|
||||
nodeSerializationEnv = SerializationEnvironmentImpl(
|
||||
SerializationFactoryImpl(HashMap()).apply {
|
||||
registerScheme(AMQPVerifierSerializationScheme)
|
||||
},
|
||||
/**
|
||||
* Even though default context is set to Amqp P2P, the encoding will be adjusted depending on the
|
||||
* incoming request received.
|
||||
*/
|
||||
AMQP_P2P_CONTEXT)
|
||||
|
||||
/*
|
||||
* Ensure that we initialise JAXP before blacklisting is enabled.
|
||||
*/
|
||||
ByteArray(0).toHexString()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private object AMQPVerifierSerializationScheme : AbstractAMQPSerializationScheme(emptySet(), HashMap()) {
|
||||
override fun canDeserializeVersion(magic: CordaSerializationMagic, target: SerializationContext.UseCase): Boolean {
|
||||
return magic == amqpMagic && target == SerializationContext.UseCase.P2P
|
||||
}
|
||||
|
||||
override fun rpcClientSerializerFactory(context: SerializationContext): SerializerFactory = throw UnsupportedOperationException()
|
||||
override fun rpcServerSerializerFactory(context: SerializationContext): SerializerFactory = throw UnsupportedOperationException()
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
/*
|
||||
* R3 Proprietary and Confidential
|
||||
*
|
||||
* Copyright (c) 2018 R3 Limited. All rights reserved.
|
||||
*
|
||||
* The intellectual and technical concepts contained herein are proprietary to R3 and its suppliers and are protected by trade secret law.
|
||||
*
|
||||
* Distribution of this file or any portion thereof via any medium without the express permission of R3 is strictly prohibited.
|
||||
*/
|
||||
|
||||
package com.r3.enclaves.txverify
|
||||
|
||||
import net.corda.core.contracts.Attachment
|
||||
import net.corda.core.contracts.ContractClassName
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.serialization.CordaSerializable
|
||||
import java.io.ByteArrayInputStream
|
||||
|
||||
@CordaSerializable
|
||||
class MockContractAttachment(override val id: SecureHash = SecureHash.zeroHash, val contract: ContractClassName, override val signers: List<Party> = ArrayList()) : Attachment {
|
||||
override fun open() = ByteArrayInputStream(id.bytes)
|
||||
override val size = id.size
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
/*
|
||||
* R3 Proprietary and Confidential
|
||||
*
|
||||
* Copyright (c) 2018 R3 Limited. All rights reserved.
|
||||
*
|
||||
* The intellectual and technical concepts contained herein are proprietary to R3 and its suppliers and are protected by trade secret law.
|
||||
*
|
||||
* Distribution of this file or any portion thereof via any medium without the express permission of R3 is strictly prohibited.
|
||||
*/
|
||||
|
||||
package com.r3.enclaves.txverify
|
||||
|
||||
object NativeSgxApi {
|
||||
|
||||
init {
|
||||
System.loadLibrary("untrusted_corda_sgx")
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
external fun verify(enclavePath: String, transactionBytes: ByteArray): String?
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
/*
|
||||
* R3 Proprietary and Confidential
|
||||
*
|
||||
* Copyright (c) 2018 R3 Limited. All rights reserved.
|
||||
*
|
||||
* The intellectual and technical concepts contained herein are proprietary to R3 and its suppliers and are protected by trade secret law.
|
||||
*
|
||||
* Distribution of this file or any portion thereof via any medium without the express permission of R3 is strictly prohibited.
|
||||
*/
|
||||
|
||||
package com.r3.enclaves.txverify
|
||||
|
||||
import java.security.SecureRandomSpi
|
||||
|
||||
class SgxSecureRandomSpi : SecureRandomSpi() {
|
||||
override fun engineSetSeed(p0: ByteArray?) {
|
||||
println("SgxSecureRandomSpi.engineSetSeed called")
|
||||
}
|
||||
|
||||
override fun engineNextBytes(p0: ByteArray?) {
|
||||
println("SgxSecureRandomSpi.engineNextBytes called")
|
||||
}
|
||||
|
||||
override fun engineGenerateSeed(numberOfBytes: Int): ByteArray {
|
||||
println("SgxSecureRandomSpi.engineGenerateSeed called")
|
||||
return ByteArray(numberOfBytes)
|
||||
}
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
/*
|
||||
* R3 Proprietary and Confidential
|
||||
*
|
||||
* Copyright (c) 2018 R3 Limited. All rights reserved.
|
||||
*
|
||||
* The intellectual and technical concepts contained herein are proprietary to R3 and its suppliers and are protected by trade secret law.
|
||||
*
|
||||
* Distribution of this file or any portion thereof via any medium without the express permission of R3 is strictly prohibited.
|
||||
*/
|
||||
|
||||
package com.r3.enclaves
|
||||
|
||||
@Suppress("unused", "unused_parameter")
|
||||
class DummySystemClassLoader(parent: ClassLoader) : ClassLoader(parent) {
|
||||
fun startBlacklisting(t: Thread) {}
|
||||
}
|
@ -1,120 +0,0 @@
|
||||
/*
|
||||
* R3 Proprietary and Confidential
|
||||
*
|
||||
* Copyright (c) 2018 R3 Limited. All rights reserved.
|
||||
*
|
||||
* The intellectual and technical concepts contained herein are proprietary to R3 and its suppliers and are protected by trade secret law.
|
||||
*
|
||||
* Distribution of this file or any portion thereof via any medium without the express permission of R3 is strictly prohibited.
|
||||
*/
|
||||
|
||||
package com.r3.enclaves.txverify
|
||||
|
||||
import com.nhaarman.mockito_kotlin.doReturn
|
||||
import com.nhaarman.mockito_kotlin.whenever
|
||||
import net.corda.core.crypto.entropyToKeyPair
|
||||
import net.corda.core.identity.AnonymousParty
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.serialization.serialize
|
||||
import net.corda.finance.POUNDS
|
||||
import net.corda.finance.`issued by`
|
||||
import net.corda.finance.contracts.asset.Cash
|
||||
import net.corda.node.services.api.IdentityServiceInternal
|
||||
import net.corda.testing.core.*
|
||||
import net.corda.testing.internal.rigorousMock
|
||||
import net.corda.testing.node.MockServices
|
||||
import net.corda.testing.node.ledger
|
||||
import org.junit.Ignore
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import java.math.BigInteger
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Paths
|
||||
import kotlin.test.assertFailsWith
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class EnclaveletTest {
|
||||
private companion object {
|
||||
val DUMMY_NOTARY = TestIdentity(DUMMY_NOTARY_NAME, 20).party
|
||||
val DUMMY_CASH_ISSUER_KEY = entropyToKeyPair(BigInteger.valueOf(10))
|
||||
val DUMMY_CASH_ISSUER_IDENTITY = getTestPartyAndCertificate(Party(CordaX500Name("Snake Oil Issuer", "London", "GB"), DUMMY_CASH_ISSUER_KEY.public))
|
||||
val DUMMY_CASH_ISSUER = DUMMY_CASH_ISSUER_IDENTITY.party.ref(1)
|
||||
val megaCorp = TestIdentity(CordaX500Name("MegaCorp", "London", "GB"))
|
||||
val MEGA_CORP get() = megaCorp.party
|
||||
val MEGA_CORP_PUBKEY get() = megaCorp.keyPair.public
|
||||
val MINI_CORP_PUBKEY = TestIdentity(CordaX500Name("MiniCorp", "London", "GB")).keyPair.public
|
||||
}
|
||||
@Rule
|
||||
@JvmField
|
||||
val testSerialization = SerializationEnvironmentRule()
|
||||
|
||||
private val ledgerServices = MockServices(emptyList(), MEGA_CORP.name, rigorousMock<IdentityServiceInternal>().also {
|
||||
doReturn(MEGA_CORP).whenever(it).partyFromKey(MEGA_CORP_PUBKEY)
|
||||
})
|
||||
|
||||
@Ignore("Pending Gradle bug: https://github.com/gradle/gradle/issues/2657")
|
||||
@Test
|
||||
fun success() {
|
||||
ledgerServices.ledger(DUMMY_NOTARY) {
|
||||
// Issue a couple of cash states and spend them.
|
||||
val wtx1 = transaction {
|
||||
attachments(Cash.PROGRAM_ID)
|
||||
output(Cash.PROGRAM_ID, "c1", Cash.State(1000.POUNDS `issued by` DUMMY_CASH_ISSUER, AnonymousParty(MEGA_CORP_PUBKEY)))
|
||||
command(DUMMY_CASH_ISSUER.party.owningKey, Cash.Commands.Issue())
|
||||
verifies()
|
||||
}
|
||||
val wtx2 = transaction {
|
||||
attachments(Cash.PROGRAM_ID)
|
||||
output(Cash.PROGRAM_ID, "c2", Cash.State(2000.POUNDS `issued by` DUMMY_CASH_ISSUER, AnonymousParty(MEGA_CORP_PUBKEY)))
|
||||
command(DUMMY_CASH_ISSUER.party.owningKey, Cash.Commands.Issue())
|
||||
verifies()
|
||||
}
|
||||
val wtx3 = transaction {
|
||||
attachments(Cash.PROGRAM_ID)
|
||||
input("c1")
|
||||
input("c2")
|
||||
output(Cash.PROGRAM_ID, "c3", Cash.State(3000.POUNDS `issued by` DUMMY_CASH_ISSUER, AnonymousParty(MINI_CORP_PUBKEY)))
|
||||
command(MEGA_CORP_PUBKEY, Cash.Commands.Move())
|
||||
verifies()
|
||||
}
|
||||
val cashContract = MockContractAttachment(interpreter.services.cordappProvider.getContractAttachmentID(Cash.PROGRAM_ID)!!, Cash.PROGRAM_ID)
|
||||
val req = TransactionVerificationRequest(wtx3.serialize(), arrayOf(wtx1.serialize(), wtx2.serialize()), arrayOf(cashContract.serialize().bytes))
|
||||
val serialized = req.serialize()
|
||||
Files.write(Paths.get(System.getProperty("java.io.tmpdir"), "req"), serialized.bytes)
|
||||
verifyInEnclave(serialized.bytes)
|
||||
}
|
||||
}
|
||||
|
||||
@Ignore("Pending Gradle bug: https://github.com/gradle/gradle/issues/2657")
|
||||
@Test
|
||||
fun fail() {
|
||||
ledgerServices.ledger(DUMMY_NOTARY) {
|
||||
// Issue a couple of cash states and spend them.
|
||||
val wtx1 = transaction {
|
||||
attachments(Cash.PROGRAM_ID)
|
||||
output(Cash.PROGRAM_ID, "c1", Cash.State(1000.POUNDS `issued by` DUMMY_CASH_ISSUER, AnonymousParty(MEGA_CORP_PUBKEY)))
|
||||
command(DUMMY_CASH_ISSUER.party.owningKey, Cash.Commands.Issue())
|
||||
verifies()
|
||||
}
|
||||
val wtx2 = transaction {
|
||||
attachments(Cash.PROGRAM_ID)
|
||||
output(Cash.PROGRAM_ID, "c2", Cash.State(2000.POUNDS `issued by` DUMMY_CASH_ISSUER, AnonymousParty(MEGA_CORP_PUBKEY)))
|
||||
command(DUMMY_CASH_ISSUER.party.owningKey, Cash.Commands.Issue())
|
||||
verifies()
|
||||
}
|
||||
val wtx3 = transaction {
|
||||
attachments(Cash.PROGRAM_ID)
|
||||
input("c1")
|
||||
input("c2")
|
||||
command(DUMMY_CASH_ISSUER.party.owningKey, DummyCommandData)
|
||||
output(Cash.PROGRAM_ID, "c3", Cash.State(3000.POUNDS `issued by` DUMMY_CASH_ISSUER, AnonymousParty(MINI_CORP_PUBKEY)))
|
||||
failsWith("Required ${Cash.Commands.Move::class.java.canonicalName} command")
|
||||
}
|
||||
val cashContract = MockContractAttachment(interpreter.services.cordappProvider.getContractAttachmentID(Cash.PROGRAM_ID)!!, Cash.PROGRAM_ID)
|
||||
val req = TransactionVerificationRequest(wtx3.serialize(), arrayOf(wtx1.serialize(), wtx2.serialize()), arrayOf(cashContract.serialize().bytes))
|
||||
val e = assertFailsWith<Exception> { verifyInEnclave(req.serialize().bytes) }
|
||||
assertTrue(e.message!!.contains("Required ${Cash.Commands.Move::class.java.canonicalName} command"))
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user