mirror of
https://github.com/corda/corda.git
synced 2025-01-14 16:59:52 +00:00
Fix post-merge issues:
- Update Doorman to reflect the X500 naming and configuration changes - Minor other changes
This commit is contained in:
parent
dfb63231e3
commit
550be76787
@ -1,17 +1,45 @@
|
||||
package com.r3.corda.doorman
|
||||
|
||||
import com.r3.corda.doorman.OptionParserHelper.toConfigWithOptions
|
||||
import com.typesafe.config.Config
|
||||
import com.typesafe.config.ConfigFactory
|
||||
import com.typesafe.config.ConfigParseOptions
|
||||
import net.corda.core.div
|
||||
import net.corda.nodeapi.config.getOrElse
|
||||
import net.corda.nodeapi.config.getValue
|
||||
import net.corda.node.utilities.getPath
|
||||
import net.corda.nodeapi.config.parseAs
|
||||
import java.nio.file.Path
|
||||
import java.util.*
|
||||
|
||||
class DoormanParameters(vararg args: String) {
|
||||
private val argConfig = args.toConfigWithOptions {
|
||||
data class DoormanParameters(val basedir: Path,
|
||||
val keystorePassword: String?,
|
||||
val caPrivateKeyPassword: String?,
|
||||
val rootKeystorePassword: String?,
|
||||
val rootPrivateKeyPassword: String?,
|
||||
val host: String,
|
||||
val port: Int,
|
||||
val dataSourceProperties: Properties,
|
||||
val keygen: Boolean = false,
|
||||
val rootKeygen: Boolean = false,
|
||||
val jiraConfig: JiraConfig? = null,
|
||||
val keystorePath: Path = basedir / "certificates" / "caKeystore.jks",
|
||||
val rootStorePath: Path = basedir / "certificates" / "rootCAKeystore.jks"
|
||||
) {
|
||||
val mode = if (rootKeygen) Mode.ROOT_KEYGEN else if (keygen) Mode.CA_KEYGEN else Mode.DOORMAN
|
||||
|
||||
enum class Mode {
|
||||
DOORMAN, CA_KEYGEN, ROOT_KEYGEN
|
||||
}
|
||||
|
||||
data class JiraConfig(
|
||||
val address: String,
|
||||
val projectCode: String,
|
||||
val username: String,
|
||||
val password: String,
|
||||
val doneTransitionCode: Int
|
||||
)
|
||||
}
|
||||
|
||||
fun parseParameters(vararg args: String): DoormanParameters {
|
||||
val argConfig = args.toConfigWithOptions {
|
||||
accepts("basedir", "Overriding configuration filepath, default to current directory.").withRequiredArg().defaultsTo(".").describedAs("filepath")
|
||||
accepts("configFile", "Overriding configuration file, default to <<current directory>>/node.conf.").withRequiredArg().describedAs("filepath")
|
||||
accepts("keygen", "Generate CA keypair and certificate using provide Root CA key.").withOptionalArg()
|
||||
@ -25,33 +53,12 @@ class DoormanParameters(vararg args: String) {
|
||||
accepts("host", "Doorman web service host override").withRequiredArg().describedAs("hostname")
|
||||
accepts("port", "Doorman web service port override").withRequiredArg().ofType(Int::class.java).describedAs("port number")
|
||||
}
|
||||
private val basedir: Path by argConfig
|
||||
private val configFile by argConfig.getOrElse { basedir / "node.conf" }
|
||||
private val config = argConfig.withFallback(ConfigFactory.parseFile(configFile.toFile(), ConfigParseOptions.defaults().setAllowMissing(true))).resolve()
|
||||
val keystorePath: Path by config.getOrElse { basedir / "certificates" / "caKeystore.jks" }
|
||||
val rootStorePath: Path by config.getOrElse { basedir / "certificates" / "rootCAKeystore.jks" }
|
||||
val keystorePassword: String? by config
|
||||
val caPrivateKeyPassword: String? by config
|
||||
val rootKeystorePassword: String? by config
|
||||
val rootPrivateKeyPassword: String? by config
|
||||
val host: String by config
|
||||
val port: Int by config
|
||||
val dataSourceProperties: Properties by config
|
||||
val jiraConfig = if (config.hasPath("jiraConfig")) JiraConfig(config.getConfig("jiraConfig")) else null
|
||||
private val keygen: Boolean by config.getOrElse { false }
|
||||
private val rootKeygen: Boolean by config.getOrElse { false }
|
||||
|
||||
val mode = if (rootKeygen) Mode.ROOT_KEYGEN else if (keygen) Mode.CA_KEYGEN else Mode.DOORMAN
|
||||
|
||||
enum class Mode {
|
||||
DOORMAN, CA_KEYGEN, ROOT_KEYGEN
|
||||
}
|
||||
|
||||
class JiraConfig(config: Config) {
|
||||
val address: String by config
|
||||
val projectCode: String by config
|
||||
val username: String by config
|
||||
val password: String by config
|
||||
val doneTransitionCode: Int by config
|
||||
val configFile = if (argConfig.hasPath("configFile")) {
|
||||
argConfig.getPath("configFile")
|
||||
} else {
|
||||
argConfig.getPath("basedir") / "node.conf"
|
||||
}
|
||||
val config = argConfig.withFallback(ConfigFactory.parseFile(configFile.toFile(), ConfigParseOptions.defaults().setAllowMissing(true))).resolve()
|
||||
return config.parseAs<DoormanParameters>()
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ package com.r3.corda.doorman
|
||||
import com.r3.corda.doorman.persistence.CertificateResponse
|
||||
import com.r3.corda.doorman.persistence.CertificationRequestData
|
||||
import com.r3.corda.doorman.persistence.CertificationRequestStorage
|
||||
import net.corda.core.crypto.X509Utilities.CACertAndKey
|
||||
import net.corda.core.crypto.CertificateAndKey
|
||||
import net.corda.core.crypto.X509Utilities.CORDA_CLIENT_CA
|
||||
import net.corda.core.crypto.X509Utilities.CORDA_INTERMEDIATE_CA
|
||||
import net.corda.core.crypto.X509Utilities.CORDA_ROOT_CA
|
||||
@ -26,7 +26,7 @@ import javax.ws.rs.core.Response.Status.UNAUTHORIZED
|
||||
* Provides functionality for asynchronous submission of certificate signing requests and retrieval of the results.
|
||||
*/
|
||||
@Path("")
|
||||
class DoormanWebService(val intermediateCACertAndKey: CACertAndKey, val rootCert: Certificate, val storage: CertificationRequestStorage, val serverStatus: DoormanServerStatus) {
|
||||
class DoormanWebService(val intermediateCACertAndKey: CertificateAndKey, val rootCert: Certificate, val storage: CertificationRequestStorage, val serverStatus: DoormanServerStatus) {
|
||||
@Context lateinit var request: HttpServletRequest
|
||||
/**
|
||||
* Accept stream of [PKCS10CertificationRequest] from user and persists in [CertificationRequestStorage] for approval.
|
||||
|
@ -7,22 +7,19 @@ import com.r3.corda.doorman.persistence.CertificationRequestStorage
|
||||
import com.r3.corda.doorman.persistence.DBCertificateRequestStorage
|
||||
import com.r3.corda.doorman.persistence.JiraCertificateRequestStorage
|
||||
import net.corda.core.createDirectories
|
||||
import net.corda.core.crypto.X509Utilities
|
||||
import net.corda.core.crypto.X509Utilities.CACertAndKey
|
||||
import net.corda.core.crypto.*
|
||||
import net.corda.core.crypto.KeyStoreUtilities.loadKeyStore
|
||||
import net.corda.core.crypto.KeyStoreUtilities.loadOrCreateKeyStore
|
||||
import net.corda.core.crypto.X509Utilities.CORDA_INTERMEDIATE_CA
|
||||
import net.corda.core.crypto.X509Utilities.CORDA_INTERMEDIATE_CA_PRIVATE_KEY
|
||||
import net.corda.core.crypto.X509Utilities.CORDA_ROOT_CA
|
||||
import net.corda.core.crypto.X509Utilities.CORDA_ROOT_CA_PRIVATE_KEY
|
||||
import net.corda.core.crypto.X509Utilities.addOrReplaceKey
|
||||
import net.corda.core.crypto.X509Utilities.createIntermediateCert
|
||||
import net.corda.core.crypto.X509Utilities.createServerCert
|
||||
import net.corda.core.crypto.X509Utilities.loadCertificateAndKey
|
||||
import net.corda.core.crypto.X509Utilities.loadKeyStore
|
||||
import net.corda.core.crypto.X509Utilities.loadOrCreateKeyStore
|
||||
import net.corda.core.crypto.X509Utilities.saveKeyStore
|
||||
import net.corda.core.seconds
|
||||
import net.corda.core.utilities.loggerFor
|
||||
import net.corda.node.utilities.configureDatabase
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest
|
||||
import org.eclipse.jetty.server.Server
|
||||
import org.eclipse.jetty.server.ServerConnector
|
||||
@ -45,7 +42,7 @@ import kotlin.system.exitProcess
|
||||
* The server will require keystorePath, keystore password and key password via command line input.
|
||||
* The Intermediate CA certificate,Intermediate CA private key and Root CA Certificate should use alias name specified in [X509Utilities]
|
||||
*/
|
||||
class DoormanServer(webServerAddr: HostAndPort, val caCertAndKey: CACertAndKey, val rootCACert: Certificate, val storage: CertificationRequestStorage) : Closeable {
|
||||
class DoormanServer(webServerAddr: HostAndPort, val caCertAndKey: CertificateAndKey, val rootCACert: Certificate, val storage: CertificationRequestStorage) : Closeable {
|
||||
val serverStatus = DoormanServerStatus()
|
||||
|
||||
companion object {
|
||||
@ -147,9 +144,9 @@ private fun DoormanParameters.generateRootKeyPair() {
|
||||
exitProcess(1)
|
||||
}
|
||||
|
||||
val selfSignCert = X509Utilities.createSelfSignedCACert(CORDA_ROOT_CA)
|
||||
val selfSignCert = X509Utilities.createSelfSignedCACert(X500Name(CORDA_ROOT_CA))
|
||||
rootStore.addOrReplaceKey(CORDA_ROOT_CA_PRIVATE_KEY, selfSignCert.keyPair.private, rootPrivateKeyPassword.toCharArray(), arrayOf(selfSignCert.certificate))
|
||||
saveKeyStore(rootStore, rootStorePath, rootKeystorePassword)
|
||||
rootStore.save(rootStorePath, rootKeystorePassword)
|
||||
|
||||
println("Root CA keypair and certificate stored in $rootStorePath.")
|
||||
println(loadKeyStore(rootStorePath, rootKeystorePassword).getCertificate(CORDA_ROOT_CA_PRIVATE_KEY).publicKey)
|
||||
@ -162,7 +159,7 @@ private fun DoormanParameters.generateCAKeyPair() {
|
||||
val rootPrivateKeyPassword = rootPrivateKeyPassword ?: readPassword("Root Private Key Password: ")
|
||||
val rootKeyStore = loadKeyStore(rootStorePath, rootKeystorePassword)
|
||||
|
||||
val rootKeyAndCert = loadCertificateAndKey(rootKeyStore, rootPrivateKeyPassword, CORDA_ROOT_CA_PRIVATE_KEY)
|
||||
val rootKeyAndCert = rootKeyStore.getCertificateAndKey(rootPrivateKeyPassword, CORDA_ROOT_CA_PRIVATE_KEY)
|
||||
|
||||
val keystorePassword = keystorePassword ?: readPassword("Keystore Password: ")
|
||||
val caPrivateKeyPassword = caPrivateKeyPassword ?: readPassword("CA Private Key Password: ")
|
||||
@ -177,10 +174,10 @@ private fun DoormanParameters.generateCAKeyPair() {
|
||||
exitProcess(1)
|
||||
}
|
||||
|
||||
val intermediateKeyAndCert = createIntermediateCert(CORDA_INTERMEDIATE_CA, rootKeyAndCert)
|
||||
val intermediateKeyAndCert = createIntermediateCert(X500Name(CORDA_INTERMEDIATE_CA), rootKeyAndCert)
|
||||
keyStore.addOrReplaceKey(CORDA_INTERMEDIATE_CA_PRIVATE_KEY, intermediateKeyAndCert.keyPair.private,
|
||||
caPrivateKeyPassword.toCharArray(), arrayOf(intermediateKeyAndCert.certificate, rootKeyAndCert.certificate))
|
||||
saveKeyStore(keyStore, keystorePath, keystorePassword)
|
||||
keyStore.save(keystorePath, keystorePassword)
|
||||
println("Intermediate CA keypair and certificate stored in $keystorePath.")
|
||||
println(loadKeyStore(keystorePath, keystorePassword).getCertificate(CORDA_INTERMEDIATE_CA_PRIVATE_KEY).publicKey)
|
||||
}
|
||||
@ -190,9 +187,10 @@ private fun DoormanParameters.startDoorman() {
|
||||
// Get password from console if not in config.
|
||||
val keystorePassword = keystorePassword ?: readPassword("Keystore Password: ")
|
||||
val caPrivateKeyPassword = caPrivateKeyPassword ?: readPassword("CA Private Key Password: ")
|
||||
val keystore = X509Utilities.loadKeyStore(keystorePath, keystorePassword)
|
||||
|
||||
val keystore = loadOrCreateKeyStore(keystorePath, keystorePassword)
|
||||
val rootCACert = keystore.getCertificateChain(CORDA_INTERMEDIATE_CA_PRIVATE_KEY).last()
|
||||
val caCertAndKey = X509Utilities.loadCertificateAndKey(keystore, caPrivateKeyPassword, CORDA_INTERMEDIATE_CA_PRIVATE_KEY)
|
||||
val caCertAndKey = keystore.getCertificateAndKey(caPrivateKeyPassword, CORDA_INTERMEDIATE_CA_PRIVATE_KEY)
|
||||
// Create DB connection.
|
||||
val (datasource, database) = configureDatabase(dataSourceProperties)
|
||||
|
||||
@ -218,7 +216,7 @@ private fun DoormanParameters.startDoorman() {
|
||||
fun main(args: Array<String>) {
|
||||
try {
|
||||
// TODO : Remove config overrides and solely use config file after testnet is finalized.
|
||||
DoormanParameters(*args).run {
|
||||
parseParameters(*args).run {
|
||||
when (mode) {
|
||||
DoormanParameters.Mode.ROOT_KEYGEN -> generateRootKeyPair()
|
||||
DoormanParameters.Mode.CA_KEYGEN -> generateCAKeyPair()
|
||||
|
@ -24,7 +24,7 @@ class DBCertificateRequestStorage(private val database: Database) : Certificatio
|
||||
|
||||
init {
|
||||
// Create table if not exists.
|
||||
databaseTransaction(database) {
|
||||
database.transaction {
|
||||
SchemaUtils.create(DataTable)
|
||||
}
|
||||
}
|
||||
@ -32,7 +32,7 @@ class DBCertificateRequestStorage(private val database: Database) : Certificatio
|
||||
override fun saveRequest(certificationData: CertificationRequestData): String {
|
||||
val legalName = certificationData.request.subject.commonName
|
||||
val requestId = SecureHash.randomSHA256().toString()
|
||||
databaseTransaction(database) {
|
||||
database.transaction {
|
||||
val duplicate = DataTable.select {
|
||||
// A duplicate legal name is one where a previously approved, or currently pending, request has the same legal name.
|
||||
// A rejected request with the same legal name doesn't count as a duplicate
|
||||
@ -65,7 +65,7 @@ class DBCertificateRequestStorage(private val database: Database) : Certificatio
|
||||
}
|
||||
|
||||
override fun getResponse(requestId: String): CertificateResponse {
|
||||
return databaseTransaction(database) {
|
||||
return database.transaction {
|
||||
val response = DataTable
|
||||
.select { DataTable.requestId eq requestId and DataTable.processTimestamp.isNotNull() }
|
||||
.map { Pair(it[DataTable.certificate], it[DataTable.rejectReason]) }
|
||||
@ -84,7 +84,7 @@ class DBCertificateRequestStorage(private val database: Database) : Certificatio
|
||||
}
|
||||
|
||||
override fun approveRequest(requestId: String, generateCertificate: CertificationRequestData.() -> Certificate) {
|
||||
databaseTransaction(database) {
|
||||
database.transaction {
|
||||
val request = singleRequestWhere { DataTable.requestId eq requestId and DataTable.processTimestamp.isNull() }
|
||||
if (request != null) {
|
||||
withFinalizables { finalizables ->
|
||||
@ -98,7 +98,7 @@ class DBCertificateRequestStorage(private val database: Database) : Certificatio
|
||||
}
|
||||
|
||||
override fun rejectRequest(requestId: String, rejectReason: String) {
|
||||
databaseTransaction(database) {
|
||||
database.transaction {
|
||||
val request = singleRequestWhere { DataTable.requestId eq requestId and DataTable.processTimestamp.isNull() }
|
||||
if (request != null) {
|
||||
DataTable.update({ DataTable.requestId eq requestId }) {
|
||||
@ -110,13 +110,13 @@ class DBCertificateRequestStorage(private val database: Database) : Certificatio
|
||||
}
|
||||
|
||||
override fun getRequest(requestId: String): CertificationRequestData? {
|
||||
return databaseTransaction(database) {
|
||||
return database.transaction {
|
||||
singleRequestWhere { DataTable.requestId eq requestId }
|
||||
}
|
||||
}
|
||||
|
||||
override fun getPendingRequestIds(): List<String> {
|
||||
return databaseTransaction(database) {
|
||||
return database.transaction {
|
||||
DataTable.select { DataTable.processTimestamp.isNull() }.map { it[DataTable.requestId] }
|
||||
}
|
||||
}
|
||||
|
@ -9,29 +9,32 @@ import kotlin.test.assertFailsWith
|
||||
|
||||
class DoormanParametersTest {
|
||||
private val testDummyPath = ".${File.separator}testDummyPath.jks"
|
||||
private val validConfigPath = javaClass.getResource("/node.conf").path
|
||||
private val invalidConfigPath = javaClass.getResource("/node_fail.conf").path
|
||||
|
||||
@Test
|
||||
fun `parse mode flag arg correctly`() {
|
||||
assertEquals(DoormanParameters.Mode.CA_KEYGEN, DoormanParameters("--keygen").mode)
|
||||
assertEquals(DoormanParameters.Mode.ROOT_KEYGEN, DoormanParameters("--rootKeygen").mode)
|
||||
assertEquals(DoormanParameters.Mode.DOORMAN, DoormanParameters().mode)
|
||||
assertEquals(DoormanParameters.Mode.CA_KEYGEN, parseParameters("--keygen", "--configFile", validConfigPath).mode)
|
||||
assertEquals(DoormanParameters.Mode.ROOT_KEYGEN, parseParameters("--rootKeygen", "--configFile", validConfigPath).mode)
|
||||
assertEquals(DoormanParameters.Mode.DOORMAN, parseParameters("--configFile", validConfigPath).mode)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `command line arg should override config file`() {
|
||||
val params = DoormanParameters("--keystorePath", testDummyPath, "--port", "1000", "--configFile", javaClass.getResource("/node.conf").path)
|
||||
val params = parseParameters("--keystorePath", testDummyPath, "--port", "1000", "--configFile", validConfigPath)
|
||||
assertEquals(testDummyPath, params.keystorePath.toString())
|
||||
assertEquals(1000, params.port)
|
||||
|
||||
val params2 = DoormanParameters("--configFile", javaClass.getResource("/node.conf").path)
|
||||
val params2 = parseParameters("--configFile", validConfigPath)
|
||||
assertEquals(Paths.get("/opt/doorman/certificates/caKeystore.jks"), params2.keystorePath)
|
||||
assertEquals(8080, params2.port)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should fail when config missing`() {
|
||||
// dataSourceProperties is missing from node_fail.conf and it should fail when accessed, and shouldn't use default from reference.conf.
|
||||
val params = DoormanParameters("--keygen", "--keystorePath", testDummyPath, "--configFile", javaClass.getResource("/node_fail.conf").path)
|
||||
assertFailsWith<ConfigException.Missing> { params.dataSourceProperties }
|
||||
// dataSourceProperties is missing from node_fail.conf and it should fail during parsing, and shouldn't use default from reference.conf.
|
||||
assertFailsWith<ConfigException.Missing> {
|
||||
parseParameters("--keygen", "--keystorePath", testDummyPath, "--configFile", invalidConfigPath)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,11 +5,11 @@ import com.nhaarman.mockito_kotlin.*
|
||||
import com.r3.corda.doorman.persistence.CertificateResponse
|
||||
import com.r3.corda.doorman.persistence.CertificationRequestData
|
||||
import com.r3.corda.doorman.persistence.CertificationRequestStorage
|
||||
import net.corda.core.crypto.CertificateStream
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.crypto.X509Utilities
|
||||
import net.corda.core.crypto.*
|
||||
import net.corda.core.crypto.X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME
|
||||
import org.apache.commons.io.IOUtils
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import org.bouncycastle.pkcs.PKCS10CertificationRequest
|
||||
import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest
|
||||
import org.junit.After
|
||||
@ -26,8 +26,8 @@ import javax.ws.rs.core.MediaType
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class DoormanServiceTest {
|
||||
private val rootCA = X509Utilities.createSelfSignedCACert("Corda Node Root CA")
|
||||
private val intermediateCA = X509Utilities.createSelfSignedCACert("Corda Node Intermediate CA")
|
||||
private val rootCA = X509Utilities.createSelfSignedCACert(X500Name("CN=Corda Node Root CA,L=London"))
|
||||
private val intermediateCA = X509Utilities.createSelfSignedCACert(X500Name("CN=Corda Node Intermediate CA,L=London"))
|
||||
private lateinit var doormanServer: DoormanServer
|
||||
|
||||
private fun startSigningServer(storage: CertificationRequestStorage) {
|
||||
@ -50,8 +50,8 @@ class DoormanServiceTest {
|
||||
|
||||
startSigningServer(storage)
|
||||
|
||||
val keyPair = X509Utilities.generateECDSAKeyPairForSSL()
|
||||
val request = X509Utilities.createCertificateSigningRequest("LegalName", "London", "admin@test.com", keyPair)
|
||||
val keyPair = Crypto.generateKeyPair(DEFAULT_TLS_SIGNATURE_SCHEME)
|
||||
val request = X509Utilities.createCertificateSigningRequest(X500Name("CN=LegalName"), keyPair)
|
||||
// Post request to signing server via http.
|
||||
|
||||
assertEquals(id, submitRequest(request))
|
||||
@ -62,7 +62,7 @@ class DoormanServiceTest {
|
||||
|
||||
@Test
|
||||
fun `retrieve certificate`() {
|
||||
val keyPair = X509Utilities.generateECDSAKeyPairForSSL()
|
||||
val keyPair = Crypto.generateKeyPair(DEFAULT_TLS_SIGNATURE_SCHEME)
|
||||
val id = SecureHash.randomSHA256().toString()
|
||||
|
||||
// Mock Storage behaviour.
|
||||
@ -74,7 +74,7 @@ class DoormanServiceTest {
|
||||
on { approveRequest(eq(id), any()) }.then {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val certGen = it.arguments[1] as ((CertificationRequestData) -> Certificate)
|
||||
val request = CertificationRequestData("", "", X509Utilities.createCertificateSigningRequest("LegalName", "London", "admin@test.com", keyPair))
|
||||
val request = CertificationRequestData("", "", X509Utilities.createCertificateSigningRequest(X500Name("CN=LegalName,L=London"), keyPair))
|
||||
certificateStore[id] = certGen(request)
|
||||
Unit
|
||||
}
|
||||
|
@ -3,10 +3,13 @@ package com.r3.corda.doorman.internal.persistence
|
||||
import com.r3.corda.doorman.persistence.CertificateResponse
|
||||
import com.r3.corda.doorman.persistence.CertificationRequestData
|
||||
import com.r3.corda.doorman.persistence.DBCertificateRequestStorage
|
||||
import net.corda.core.crypto.Crypto
|
||||
import net.corda.core.crypto.X509Utilities
|
||||
import net.corda.core.crypto.X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME
|
||||
import net.corda.node.utilities.configureDatabase
|
||||
import net.corda.testing.node.makeTestDataSourceProperties
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
@ -18,7 +21,7 @@ import kotlin.test.assertNotNull
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class DBCertificateRequestStorageTest {
|
||||
private val intermediateCA = X509Utilities.createSelfSignedCACert("Corda Node Intermediate CA")
|
||||
private val intermediateCA = X509Utilities.createSelfSignedCACert(X500Name("CN=Corda Node Intermediate CA"))
|
||||
private var closeDb: Closeable? = null
|
||||
private lateinit var storage: DBCertificateRequestStorage
|
||||
|
||||
@ -106,28 +109,12 @@ class DBCertificateRequestStorageTest {
|
||||
assertThat(storage.getResponse(requestId2)).isInstanceOf(CertificateResponse.Ready::class.java)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `request with equals symbol in legal name`() {
|
||||
val requestId = storage.saveRequest(createRequest("Bank=A").first)
|
||||
assertThat(storage.getPendingRequestIds()).isEmpty()
|
||||
val response = storage.getResponse(requestId) as CertificateResponse.Unauthorised
|
||||
assertThat(response.message).contains("=")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `request with comma in legal name`() {
|
||||
val requestId = storage.saveRequest(createRequest("Bank,A").first)
|
||||
assertThat(storage.getPendingRequestIds()).isEmpty()
|
||||
val response = storage.getResponse(requestId) as CertificateResponse.Unauthorised
|
||||
assertThat(response.message).contains(",")
|
||||
}
|
||||
|
||||
private fun createRequest(legalName: String): Pair<CertificationRequestData, KeyPair> {
|
||||
val keyPair = X509Utilities.generateECDSAKeyPairForSSL()
|
||||
val keyPair = Crypto.generateKeyPair(DEFAULT_TLS_SIGNATURE_SCHEME)
|
||||
val request = CertificationRequestData(
|
||||
"hostname",
|
||||
"0.0.0.0",
|
||||
X509Utilities.createCertificateSigningRequest(legalName, "London", "admin@test.com", keyPair))
|
||||
X509Utilities.createCertificateSigningRequest(X500Name("CN=$legalName"), keyPair))
|
||||
return Pair(request, keyPair)
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,6 @@ import java.net.URL
|
||||
import java.security.cert.Certificate
|
||||
import java.util.*
|
||||
import java.util.zip.ZipInputStream
|
||||
import javax.ws.rs.core.MediaType
|
||||
|
||||
class HTTPNetworkRegistrationService(val server: URL) : NetworkRegistrationService {
|
||||
companion object {
|
||||
@ -46,7 +45,7 @@ class HTTPNetworkRegistrationService(val server: URL) : NetworkRegistrationServi
|
||||
val conn = URL("$server/api/certificate").openConnection() as HttpURLConnection
|
||||
conn.doOutput = true
|
||||
conn.requestMethod = "POST"
|
||||
conn.setRequestProperty("Content-Type", MediaType.APPLICATION_OCTET_STREAM)
|
||||
conn.setRequestProperty("Content-Type", MediaType.OCTET_STREAM.toString())
|
||||
conn.setRequestProperty("Client-Version", clientVersion)
|
||||
conn.outputStream.write(request.encoded)
|
||||
|
||||
|
@ -3,21 +3,33 @@
|
||||
package com.r3.enclaves.txverify
|
||||
|
||||
import com.esotericsoftware.minlog.Log
|
||||
import net.corda.core.contracts.*
|
||||
import net.corda.core.crypto.*
|
||||
import net.corda.core.contracts.Attachment
|
||||
import net.corda.core.contracts.StateRef
|
||||
import net.corda.core.contracts.TransactionResolutionException
|
||||
import net.corda.core.contracts.TransactionState
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.identity.AnonymousParty
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.node.ServicesForResolution
|
||||
import net.corda.core.node.services.AttachmentStorage
|
||||
import net.corda.core.node.services.AttachmentsStorageService
|
||||
import net.corda.core.node.services.IdentityService
|
||||
import net.corda.core.serialization.*
|
||||
import net.corda.core.serialization.CordaSerializable
|
||||
import net.corda.core.serialization.SerializedBytes
|
||||
import net.corda.core.serialization.createTestKryo
|
||||
import net.corda.core.serialization.deserialize
|
||||
import net.corda.core.transactions.WireTransaction
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import java.io.File
|
||||
import java.io.InputStream
|
||||
import java.nio.file.Path
|
||||
import java.security.PublicKey
|
||||
|
||||
// This file implements the functionality of the SGX transaction verification enclave.
|
||||
|
||||
private class ServicesForVerification(dependenciesList: List<WireTransaction>, attachments: Array<ByteArray>) : ServicesForResolution, IdentityService, AttachmentsStorageService, AttachmentStorage {
|
||||
override val attachmentsClassLoaderEnabled: Boolean
|
||||
get() = TODO("not implemented")
|
||||
override var automaticallyExtractAttachments: Boolean
|
||||
get() = throw UnsupportedOperationException()
|
||||
set(value) = throw UnsupportedOperationException()
|
||||
@ -37,10 +49,12 @@ private class ServicesForVerification(dependenciesList: List<WireTransaction>, a
|
||||
}
|
||||
|
||||
// Identities: this stuff will all change in future so we don't bother implementing it now.
|
||||
override fun registerIdentity(party: Party) = throw UnsupportedOperationException()
|
||||
override fun partyFromKey(key: CompositeKey): Party? = null
|
||||
override fun partyFromName(name: String): Party? = null
|
||||
override fun partyFromAnonymous(party: AnonymousParty) = null
|
||||
override fun registerIdentity(party: net.corda.core.identity.Party) = TODO("not implemented")
|
||||
|
||||
override fun partyFromKey(key: PublicKey): net.corda.core.identity.Party? = null
|
||||
override fun partyFromName(name: String): net.corda.core.identity.Party? = null
|
||||
override fun partyFromX500Name(principal: X500Name): net.corda.core.identity.Party? = null
|
||||
override fun partyFromAnonymous(party: AnonymousParty): net.corda.core.identity.Party? = null
|
||||
|
||||
// TODO: Implement attachments.
|
||||
override val attachments: AttachmentStorage = this
|
||||
|
Loading…
Reference in New Issue
Block a user