mirror of
https://github.com/corda/corda.git
synced 2024-12-28 00:38:55 +00:00
Tweaking hibernate to support Azure and H2 dbs (#60)
This commit is contained in:
parent
40b1eca0aa
commit
5deb708bb3
@ -1,7 +1,7 @@
|
||||
ext {
|
||||
// We use Corda release artifact dependencies instead of project dependencies to make sure each doorman releases are
|
||||
// align with the corresponding Corda release.
|
||||
corda_dependency_version = '1.0.0'
|
||||
corda_dependency_version = '2.0-20171017.135310-6'
|
||||
}
|
||||
|
||||
version "$corda_dependency_version"
|
||||
|
@ -33,10 +33,10 @@ class DoormanIntegrationTest {
|
||||
val intermediateCACert = X509Utilities.createCertificate(CertificateType.INTERMEDIATE_CA, rootCACert, rootCAKey,
|
||||
CordaX500Name(commonName = "Integration Test Corda Node Intermediate CA", locality = "London", country = "GB", organisation = "R3 Ltd"), intermediateCAKey.public)
|
||||
|
||||
val database = configureDatabase(makeTestDataSourceProperties(), null, { DoormanSchemaService() }, createIdentityService = {
|
||||
val database = configureDatabase(makeTestDataSourceProperties(), null, {
|
||||
// Identity service not needed doorman, corda persistence is not very generic.
|
||||
throw UnsupportedOperationException()
|
||||
})
|
||||
}, DoormanSchemaService())
|
||||
val signer = Signer(intermediateCAKey, arrayOf(intermediateCACert.toX509Certificate(), rootCACert.toX509Certificate()))
|
||||
|
||||
//Start doorman server
|
||||
|
@ -237,7 +237,7 @@ fun main(args: Array<String>) {
|
||||
keystorePassword,
|
||||
caPrivateKeyPassword)
|
||||
DoormanParameters.Mode.DOORMAN -> {
|
||||
val database = configureDatabase(dataSourceProperties, databaseProperties, { DoormanSchemaService() }, { throw UnsupportedOperationException() })
|
||||
val database = configureDatabase(dataSourceProperties, databaseProperties, { throw UnsupportedOperationException() }, DoormanSchemaService())
|
||||
val signer = buildLocalSigner(this)
|
||||
startDoorman(NetworkHostAndPort(host, port), database, approveAll, signer, jiraConfig)
|
||||
}
|
||||
|
@ -10,14 +10,16 @@ import net.corda.node.utilities.DatabaseTransaction
|
||||
import org.bouncycastle.pkcs.PKCS10CertificationRequest
|
||||
import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest
|
||||
import java.security.cert.CertPath
|
||||
import java.sql.Connection
|
||||
import java.time.Instant
|
||||
import javax.persistence.LockModeType
|
||||
import javax.persistence.criteria.CriteriaBuilder
|
||||
import javax.persistence.criteria.Path
|
||||
import javax.persistence.criteria.Predicate
|
||||
|
||||
class DBCertificateRequestStorage(private val database: CordaPersistence) : CertificationRequestStorage {
|
||||
override fun putCertificatePath(requestId: String, certificates: CertPath, signedBy: List<String>) {
|
||||
return database.transaction {
|
||||
return database.transaction(Connection.TRANSACTION_SERIALIZABLE) {
|
||||
val request = singleRequestWhere { builder, path ->
|
||||
val requestIdEq = builder.equal(path.get<String>(CertificateSigningRequest::requestId.name), requestId)
|
||||
val statusEq = builder.equal(path.get<String>(CertificateSigningRequest::status.name), Approved)
|
||||
@ -37,7 +39,7 @@ class DBCertificateRequestStorage(private val database: CordaPersistence) : Cert
|
||||
override fun saveRequest(rawRequest: PKCS10CertificationRequest): String {
|
||||
val request = JcaPKCS10CertificationRequest(rawRequest)
|
||||
val requestId = SecureHash.randomSHA256().toString()
|
||||
database.transaction {
|
||||
database.transaction(Connection.TRANSACTION_SERIALIZABLE) {
|
||||
// TODO ensure public key not duplicated.
|
||||
val (legalName, rejectReason) = try {
|
||||
// This will fail with IllegalArgumentException if subject name is malformed.
|
||||
@ -73,7 +75,7 @@ class DBCertificateRequestStorage(private val database: CordaPersistence) : Cert
|
||||
|
||||
override fun approveRequest(requestId: String, approvedBy: String): Boolean {
|
||||
var approved = false
|
||||
database.transaction {
|
||||
database.transaction(Connection.TRANSACTION_SERIALIZABLE) {
|
||||
val request = singleRequestWhere { builder, path ->
|
||||
builder.and(builder.equal(path.get<String>(CertificateSigningRequest::requestId.name), requestId),
|
||||
builder.equal(path.get<String>(CertificateSigningRequest::status.name), New))
|
||||
@ -90,7 +92,7 @@ class DBCertificateRequestStorage(private val database: CordaPersistence) : Cert
|
||||
}
|
||||
|
||||
override fun rejectRequest(requestId: String, rejectedBy: String, rejectReason: String) {
|
||||
database.transaction {
|
||||
database.transaction(Connection.TRANSACTION_SERIALIZABLE) {
|
||||
val request = singleRequestWhere { builder, path ->
|
||||
builder.equal(path.get<String>(CertificateSigningRequest::requestId.name), requestId)
|
||||
}
|
||||
@ -130,6 +132,6 @@ class DBCertificateRequestStorage(private val database: CordaPersistence) : Cert
|
||||
val query = criteriaQuery.from(CertificateSigningRequest::class.java).run {
|
||||
criteriaQuery.where(predicate(builder, this))
|
||||
}
|
||||
return session.createQuery(query).uniqueResultOptional().orElse(null)
|
||||
return session.createQuery(query).setLockMode(LockModeType.PESSIMISTIC_WRITE).uniqueResultOptional().orElse(null)
|
||||
}
|
||||
}
|
@ -18,9 +18,4 @@ class DoormanSchemaService : SchemaService {
|
||||
|
||||
override fun generateMappedObject(state: ContractState, schema: MappedSchema): PersistentState = throw UnsupportedOperationException()
|
||||
|
||||
override fun registerCustomSchemas(customSchemas: Set<MappedSchema>) {
|
||||
schemaOptions = schemaOptions.plus(customSchemas.map { mappedSchema ->
|
||||
Pair(mappedSchema, SchemaService.SchemaOptions())
|
||||
})
|
||||
}
|
||||
}
|
@ -29,7 +29,7 @@ class DBCertificateRequestStorageTest {
|
||||
|
||||
@Before
|
||||
fun startDb() {
|
||||
persistence = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), { DoormanSchemaService() }, createIdentityService = { throw UnsupportedOperationException() })
|
||||
persistence = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), { throw UnsupportedOperationException() }, DoormanSchemaService())
|
||||
storage = DBCertificateRequestStorage(persistence)
|
||||
}
|
||||
|
||||
|
@ -58,7 +58,7 @@ class PersistenceNodeInfoStorageTest {
|
||||
|
||||
@Before
|
||||
fun startDb() {
|
||||
persistence = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), { DoormanSchemaService() }, createIdentityService = { throw UnsupportedOperationException() })
|
||||
persistence = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), { throw UnsupportedOperationException() }, DoormanSchemaService())
|
||||
nodeInfoStorage = PersistenceNodeInfoStorage(persistence)
|
||||
requestStorage = DBCertificateRequestStorage(persistence)
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
ext {
|
||||
// We use Corda release artifact dependencies instead of project dependencies to make sure each doorman releases are
|
||||
// align with the corresponding Corda release.
|
||||
corda_dependency_version = '0.16-20170913.101300-6'
|
||||
corda_dependency_version = '2.0-20171017.135310-6'
|
||||
}
|
||||
|
||||
version "$corda_dependency_version"
|
||||
|
@ -1,6 +1,5 @@
|
||||
package com.r3.corda.signing
|
||||
|
||||
import net.corda.node.utilities.configureDatabase
|
||||
import com.r3.corda.signing.authentication.Authenticator
|
||||
import com.r3.corda.signing.authentication.createProvider
|
||||
import com.r3.corda.signing.configuration.Parameters
|
||||
@ -12,6 +11,7 @@ import com.r3.corda.signing.persistence.ApprovedCertificateRequestData
|
||||
import com.r3.corda.signing.persistence.DBCertificateRequestStorage
|
||||
import com.r3.corda.signing.persistence.SigningServerSchemaService
|
||||
import com.r3.corda.signing.utils.mapCryptoServerException
|
||||
import net.corda.node.utilities.configureDatabase
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
run(parseParameters(*args))
|
||||
@ -21,10 +21,10 @@ fun run(parameters: Parameters) {
|
||||
parameters.run {
|
||||
// Create DB connection.
|
||||
checkNotNull(dataSourceProperties)
|
||||
val database = configureDatabase(dataSourceProperties, databaseProperties, { SigningServerSchemaService() }, createIdentityService = {
|
||||
val database = configureDatabase(dataSourceProperties, databaseProperties, {
|
||||
// Identity service not needed
|
||||
throw UnsupportedOperationException()
|
||||
})
|
||||
}, SigningServerSchemaService())
|
||||
|
||||
val storage = DBCertificateRequestStorage(database)
|
||||
val provider = createProvider()
|
||||
|
@ -3,8 +3,7 @@ package com.r3.corda.signing.persistence
|
||||
import net.corda.node.utilities.CordaPersistence
|
||||
import org.bouncycastle.pkcs.PKCS10CertificationRequest
|
||||
import java.security.cert.CertPath
|
||||
import java.security.cert.Certificate
|
||||
import java.security.cert.CertificateFactory
|
||||
import java.sql.Connection
|
||||
import java.time.Instant
|
||||
import javax.persistence.*
|
||||
import javax.persistence.criteria.CriteriaBuilder
|
||||
@ -53,7 +52,7 @@ class DBCertificateRequestStorage(private val database: CordaPersistence) : Cert
|
||||
|
||||
override fun sign(requests: List<ApprovedCertificateRequestData>, signers: List<String>) {
|
||||
requests.forEach {
|
||||
database.transaction {
|
||||
database.transaction(Connection.TRANSACTION_SERIALIZABLE) {
|
||||
val request = singleRequestWhere { builder, path ->
|
||||
builder.and(
|
||||
builder.equal(path.get<String>(CertificateSigningRequest::requestId.name), it.requestId),
|
||||
|
@ -3,6 +3,7 @@ package com.r3.corda.signing.utils
|
||||
import CryptoServerJCE.CryptoServerProvider
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.internal.toX509CertHolder
|
||||
import net.corda.core.internal.x500Name
|
||||
import net.corda.node.utilities.CertificateAndKeyPair
|
||||
import net.corda.node.utilities.CertificateType
|
||||
import net.corda.node.utilities.X509Utilities
|
||||
@ -108,7 +109,7 @@ object X509Utilities {
|
||||
fun retrieveCertificateAndKeys(certificateKeyName: String, privateKeyPassword: String, keyStore: KeyStore): CertificateAndKeyPair {
|
||||
val privateKey = keyStore.getKey(certificateKeyName, privateKeyPassword.toCharArray()) as PrivateKey
|
||||
val publicKey = keyStore.getCertificate(certificateKeyName).publicKey
|
||||
val certificate = keyStore.getX509Certificate(certificateKeyName)
|
||||
val certificate = keyStore.getX509Certificate(certificateKeyName).toX509CertHolder()
|
||||
return CertificateAndKeyPair(certificate, getCleanEcdsaKeyPair(publicKey, privateKey))
|
||||
}
|
||||
|
||||
@ -176,13 +177,13 @@ object X509Utilities {
|
||||
provider: Provider): Certificate {
|
||||
val jcaRequest = JcaPKCS10CertificationRequest(request)
|
||||
// This can be adjusted more to our future needs.
|
||||
val nameConstraints = NameConstraints(arrayOf(GeneralSubtree(GeneralName(GeneralName.directoryName, CordaX500Name.build(jcaRequest.subject).copy(commonName = null).x500Name))), arrayOf())
|
||||
val nameConstraints = NameConstraints(arrayOf(GeneralSubtree(GeneralName(GeneralName.directoryName, CordaX500Name.parse(jcaRequest.subject.toString()).copy(commonName = null).x500Name))), arrayOf())
|
||||
val issuerCertificate = caCertAndKey.certificate
|
||||
val issuerKeyPair = caCertAndKey.keyPair
|
||||
val certificateType = CertificateType.CLIENT_CA
|
||||
val validityWindow = getCertificateValidityWindow(0, validDays, issuerCertificate.notBefore, issuerCertificate.notAfter)
|
||||
val serial = BigInteger.valueOf(random63BitValue(provider))
|
||||
val subject = CordaX500Name.build(jcaRequest.subject).copy(commonName = X509Utilities.CORDA_CLIENT_CA_CN).x500Name
|
||||
val subject = CordaX500Name.parse(jcaRequest.subject.toString()).copy(commonName = X509Utilities.CORDA_CLIENT_CA_CN).x500Name
|
||||
val subjectPublicKeyInfo = SubjectPublicKeyInfo.getInstance(ASN1Sequence.getInstance(jcaRequest.publicKey.encoded))
|
||||
val keyPurposes = DERSequence(ASN1EncodableVector().apply { certificateType.purposes.forEach { add(it) } })
|
||||
val builder = JcaX509v3CertificateBuilder(issuerCertificate.subject, serial, validityWindow.first, validityWindow.second, subject, jcaRequest.publicKey)
|
||||
|
@ -1,5 +1,8 @@
|
||||
package com.r3.corda.signing.persistence
|
||||
|
||||
import com.r3.corda.signing.persistence.DBCertificateRequestStorage.CertificateSigningRequest
|
||||
import com.r3.corda.signing.persistence.DBCertificateRequestStorage.Status
|
||||
import com.r3.corda.signing.utils.X509Utilities.buildCertPath
|
||||
import net.corda.core.crypto.Crypto
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
@ -7,8 +10,6 @@ import net.corda.node.utilities.CertificateType
|
||||
import net.corda.node.utilities.CordaPersistence
|
||||
import net.corda.node.utilities.X509Utilities
|
||||
import net.corda.node.utilities.configureDatabase
|
||||
import com.r3.corda.signing.persistence.DBCertificateRequestStorage.CertificateSigningRequest
|
||||
import com.r3.corda.signing.persistence.DBCertificateRequestStorage.Status
|
||||
import org.bouncycastle.asn1.x509.GeneralName
|
||||
import org.bouncycastle.asn1.x509.GeneralSubtree
|
||||
import org.bouncycastle.asn1.x509.NameConstraints
|
||||
@ -27,17 +28,16 @@ import javax.persistence.criteria.Path
|
||||
import javax.persistence.criteria.Predicate
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNotNull
|
||||
import com.r3.corda.signing.utils.X509Utilities.buildCertPath
|
||||
|
||||
class DBCertificateRequestStorageTest {
|
||||
private val intermediateCAKey = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
|
||||
private val intermediateCACert = X509Utilities.createSelfSignedCACertificate(CordaX500Name(commonName = "Corda Node Intermediate CA", organisation = "R3 Ltd", locality = "London", country = "GB").x500Name, intermediateCAKey)
|
||||
private val intermediateCACert = X509Utilities.createSelfSignedCACertificate(CordaX500Name(commonName = "Corda Node Intermediate CA", organisation = "R3 Ltd", locality = "London", country = "GB"), intermediateCAKey)
|
||||
private lateinit var storage: DBCertificateRequestStorage
|
||||
private lateinit var persistence: CordaPersistence
|
||||
|
||||
@Before
|
||||
fun startDb() {
|
||||
persistence = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), { SigningServerSchemaService() }, createIdentityService = { throw UnsupportedOperationException() })
|
||||
persistence = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), { throw UnsupportedOperationException() }, SigningServerSchemaService())
|
||||
storage = DBCertificateRequestStorage(persistence)
|
||||
}
|
||||
|
||||
@ -131,7 +131,7 @@ class DBCertificateRequestStorageTest {
|
||||
val requestId = SecureHash.randomSHA256().toString()
|
||||
persistence.transaction {
|
||||
val keyPair = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
|
||||
val x500Name = CordaX500Name(organisation = legalName, locality = "London", country = "GB").x500Name
|
||||
val x500Name = CordaX500Name(organisation = legalName, locality = "London", country = "GB")
|
||||
session.save(CertificateSigningRequest(
|
||||
requestId = requestId,
|
||||
status = status,
|
||||
|
Loading…
Reference in New Issue
Block a user