mirror of
https://github.com/corda/corda.git
synced 2025-01-12 16:02:41 +00:00
Doorman db entity attributes which are hashes are of type SecureHash where possible. (#695)
Also made use of InputStream.readObject extension method.
This commit is contained in:
parent
00a22c91df
commit
11af3992db
8
.idea/compiler.xml
generated
8
.idea/compiler.xml
generated
@ -28,12 +28,14 @@
|
||||
<module name="business-network-demo_integrationTest" target="1.8" />
|
||||
<module name="business-network-demo_main" target="1.8" />
|
||||
<module name="business-network-demo_test" target="1.8" />
|
||||
<module name="canonicalizer_main" target="1.8" />
|
||||
<module name="canonicalizer_test" target="1.8" />
|
||||
<module name="capsule-crr-submission_main" target="1.8" />
|
||||
<module name="capsule-crr-submission_test" target="1.8" />
|
||||
<module name="capsule-hsm-cert-generator_main" target="1.8" />
|
||||
<module name="capsule-hsm-cert-generator_test" target="1.8" />
|
||||
<module name="capsule-hsm_main" target="1.8" />
|
||||
<module name="capsule-hsm_test" target="1.8" />
|
||||
<module name="canonicalizer_main" target="1.8" />
|
||||
<module name="canonicalizer_test" target="1.8" />
|
||||
<module name="client_main" target="1.8" />
|
||||
<module name="client_test" target="1.8" />
|
||||
<module name="confidential-identities_main" target="1.8" />
|
||||
@ -184,4 +186,4 @@
|
||||
<component name="JavacSettings">
|
||||
<option name="ADDITIONAL_OPTIONS_STRING" value="-parameters" />
|
||||
</component>
|
||||
</project>
|
||||
</project>
|
@ -13,11 +13,11 @@ package com.r3.corda.networkmanage.common.persistence
|
||||
import com.r3.corda.networkmanage.common.persistence.entity.CertificateDataEntity
|
||||
import com.r3.corda.networkmanage.common.persistence.entity.CertificateSigningRequestEntity
|
||||
import com.r3.corda.networkmanage.common.utils.getCertRole
|
||||
import com.r3.corda.networkmanage.common.utils.hashString
|
||||
import net.corda.core.crypto.Crypto.toSupportedPublicKey
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.internal.CertRole
|
||||
import net.corda.core.internal.hash
|
||||
import net.corda.nodeapi.internal.crypto.x509Certificates
|
||||
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
||||
import net.corda.nodeapi.internal.persistence.DatabaseTransaction
|
||||
@ -70,7 +70,7 @@ class PersistentCertificateSigningRequestStorage(private val database: CordaPers
|
||||
val requestEntity = CertificateSigningRequestEntity(
|
||||
requestId = requestId,
|
||||
legalName = legalNameOrRejectMessage as? CordaX500Name,
|
||||
publicKeyHash = toSupportedPublicKey(request.subjectPublicKeyInfo).hashString(),
|
||||
publicKeyHash = toSupportedPublicKey(request.subjectPublicKeyInfo).hash,
|
||||
request = request,
|
||||
remark = legalNameOrRejectMessage as? String,
|
||||
modifiedBy = CertificateSigningRequestStorage.DOORMAN_SIGNATURE,
|
||||
@ -136,7 +136,7 @@ class PersistentCertificateSigningRequestStorage(private val database: CordaPers
|
||||
session.createQuery(
|
||||
"select a.certificateData.certPath from ${CertificateSigningRequestEntity::class.java.name} a " +
|
||||
"where a.publicKeyHash = :publicKeyHash and a.status = 'DONE' and a.certificateData.certificateStatus = 'VALID'", CertPath::class.java)
|
||||
.setParameter("publicKeyHash", publicKey.hashString())
|
||||
.setParameter("publicKeyHash", publicKey.hash.toString())
|
||||
.uniqueResult()
|
||||
}
|
||||
}
|
||||
@ -175,7 +175,7 @@ class PersistentCertificateSigningRequestStorage(private val database: CordaPers
|
||||
// What if we approved something by mistake.
|
||||
nonRejectedRequestExists(CertificateSigningRequestEntity::legalName.name, legalName) -> throw RequestValidationException(legalName.toString(), "Duplicate legal name")
|
||||
//TODO Consider following scenario: There is a CSR that is signed but the certificate itself has expired or was revoked
|
||||
nonRejectedRequestExists(CertificateSigningRequestEntity::publicKeyHash.name, toSupportedPublicKey(request.subjectPublicKeyInfo).hashString()) -> throw RequestValidationException(legalName.toString(), "Duplicate public key")
|
||||
nonRejectedRequestExists(CertificateSigningRequestEntity::publicKeyHash.name, toSupportedPublicKey(request.subjectPublicKeyInfo).hash) -> throw RequestValidationException(legalName.toString(), "Duplicate public key")
|
||||
else -> legalName
|
||||
}
|
||||
}
|
||||
|
@ -14,12 +14,12 @@ import com.r3.corda.networkmanage.common.persistence.entity.CertificateSigningRe
|
||||
import com.r3.corda.networkmanage.common.persistence.entity.NodeInfoEntity
|
||||
import com.r3.corda.networkmanage.common.persistence.entity.ParametersUpdateEntity
|
||||
import com.r3.corda.networkmanage.common.persistence.entity.UpdateStatus
|
||||
import com.r3.corda.networkmanage.common.utils.hashString
|
||||
import com.r3.corda.networkmanage.common.utils.logger
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.crypto.sha256
|
||||
import net.corda.core.internal.CertRole
|
||||
import net.corda.core.internal.CertRole.NODE_CA
|
||||
import net.corda.core.internal.hash
|
||||
import net.corda.nodeapi.internal.NodeInfoAndSigned
|
||||
import net.corda.nodeapi.internal.SignedNodeInfo
|
||||
import net.corda.nodeapi.internal.crypto.x509Certificates
|
||||
@ -67,7 +67,7 @@ class PersistentNodeInfoStorage(private val database: CordaPersistence) : NodeIn
|
||||
|
||||
session.saveOrUpdate(NodeInfoEntity(
|
||||
nodeInfoHash = nodeInfoHash.toString(),
|
||||
publicKeyHash = nodeInfo.legalIdentities[0].owningKey.hashString(),
|
||||
publicKeyHash = nodeInfo.legalIdentities[0].owningKey.hash,
|
||||
certificateSigningRequest = request,
|
||||
signedNodeInfo = signedNodeInfo,
|
||||
isCurrent = true,
|
||||
@ -101,7 +101,7 @@ class PersistentNodeInfoStorage(private val database: CordaPersistence) : NodeIn
|
||||
return database.transaction {
|
||||
val nodeInfoEntity = session.fromQuery<NodeInfoEntity>(
|
||||
"n where n.publicKeyHash = :publicKeyHash and isCurrent = true")
|
||||
.setParameter("publicKeyHash", publicKey.hashString())
|
||||
.setParameter("publicKeyHash", publicKey.hash)
|
||||
.singleResult
|
||||
val parametersUpdateEntity = session.fromQuery<ParametersUpdateEntity>(
|
||||
"u where u.networkParameters.hash = :acceptedParametersHash").
|
||||
@ -116,7 +116,7 @@ class PersistentNodeInfoStorage(private val database: CordaPersistence) : NodeIn
|
||||
|
||||
private fun DatabaseTransaction.getSignedRequestByPublicHash(publicKeyHash: SecureHash): CertificateSigningRequestEntity? {
|
||||
return uniqueEntityWhere { builder, path ->
|
||||
val publicKeyEq = builder.equal(path.get<String>(CertificateSigningRequestEntity::publicKeyHash.name), publicKeyHash.toString())
|
||||
val publicKeyEq = builder.equal(path.get<String>(CertificateSigningRequestEntity::publicKeyHash.name), publicKeyHash)
|
||||
val statusEq = builder.equal(path.get<RequestStatus>(CertificateSigningRequestEntity::status.name), RequestStatus.DONE)
|
||||
builder.and(publicKeyEq, statusEq)
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
package com.r3.corda.networkmanage.common.persistence.entity
|
||||
|
||||
import com.r3.corda.networkmanage.common.utils.buildCertPath
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.node.NetworkParameters
|
||||
import net.corda.core.serialization.SerializationFactory
|
||||
import net.corda.core.serialization.serialize
|
||||
@ -13,7 +15,6 @@ import java.security.cert.CertPath
|
||||
import java.security.cert.X509CRL
|
||||
import java.security.cert.X509Certificate
|
||||
import javax.persistence.AttributeConverter
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
|
||||
class PKCS10CertificationRequestConverter : AttributeConverter<PKCS10CertificationRequest, ByteArray> {
|
||||
override fun convertToEntityAttribute(dbData: ByteArray?): PKCS10CertificationRequest? = dbData?.let(::PKCS10CertificationRequest)
|
||||
@ -45,7 +46,11 @@ class NetworkMapConverter : CordaSerializationConverter<NetworkMap>(NetworkMap::
|
||||
|
||||
class SignedNodeInfoConverter : CordaSerializationConverter<SignedNodeInfo>(SignedNodeInfo::class.java)
|
||||
|
||||
sealed class CordaSerializationConverter<T : Any>(private val clazz: Class<T>) : AttributeConverter<T, ByteArray> {
|
||||
class CordaX500NameAttributeConverter : ToStringConverter<CordaX500Name>(CordaX500Name.Companion::parse)
|
||||
|
||||
class SecureHashAttributeConverter : ToStringConverter<SecureHash>(SecureHash.Companion::parse)
|
||||
|
||||
abstract class CordaSerializationConverter<T : Any>(private val clazz: Class<T>) : AttributeConverter<T, ByteArray> {
|
||||
override fun convertToEntityAttribute(dbData: ByteArray?): T? {
|
||||
return dbData?.let {
|
||||
val serializationFactory = SerializationFactory.defaultFactory
|
||||
@ -56,14 +61,7 @@ sealed class CordaSerializationConverter<T : Any>(private val clazz: Class<T>) :
|
||||
override fun convertToDatabaseColumn(attribute: T?): ByteArray? = attribute?.serialize()?.bytes
|
||||
}
|
||||
|
||||
class CordaX500NameAttributeConverter : AttributeConverter<CordaX500Name, String> {
|
||||
override fun convertToDatabaseColumn(attribute: CordaX500Name?): String? = attribute?.toString()
|
||||
override fun convertToEntityAttribute(dbData: String?): CordaX500Name? = dbData?.let { CordaX500Name.parse(it) }
|
||||
abstract class ToStringConverter<T : Any>(private val parser: (String) -> T) : AttributeConverter<T, String> {
|
||||
override fun convertToDatabaseColumn(attribute: T?): String? = attribute?.toString()
|
||||
override fun convertToEntityAttribute(dbData: String?): T? = dbData?.let { parser(it) }
|
||||
}
|
||||
|
||||
// TODO Use SecureHash in entities
|
||||
//class SecureHashAttributeConverter : AttributeConverter<SecureHash, String> {
|
||||
// override fun convertToDatabaseColumn(attribute: SecureHash?): String? = attribute?.toString()
|
||||
// override fun convertToEntityAttribute(dbData: String?): SecureHash? = dbData?.let { SecureHash.parse(it) }
|
||||
//}
|
||||
|
||||
|
@ -38,7 +38,8 @@ data class CertificateSigningRequestEntity(
|
||||
val legalName: CordaX500Name?,
|
||||
|
||||
@Column(name = "public_key_hash", length = 64, nullable = false)
|
||||
val publicKeyHash: String,
|
||||
@Convert(converter = SecureHashAttributeConverter::class)
|
||||
val publicKeyHash: SecureHash,
|
||||
|
||||
// Setting [columnDefinition] is a work around for a hibernate problem when using SQL database.
|
||||
// TODO: Remove this when we find out the cause of the problem.
|
||||
@ -75,7 +76,7 @@ data class CertificateSigningRequestEntity(
|
||||
return CertificateSigningRequest(
|
||||
requestId = requestId,
|
||||
legalName = legalName,
|
||||
publicKeyHash = SecureHash.parse(publicKeyHash),
|
||||
publicKeyHash = publicKeyHash,
|
||||
status = status,
|
||||
request = request,
|
||||
remark = remark,
|
||||
|
@ -24,6 +24,7 @@ import javax.persistence.*
|
||||
class NetworkParametersEntity(
|
||||
@Id
|
||||
@Column(name = "hash", length = 64, nullable = false)
|
||||
// AttributeConverters can't be used on @Id attributes, otherwise this would be SecureHash
|
||||
val hash: String,
|
||||
|
||||
@Column(nullable = false)
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
package com.r3.corda.networkmanage.common.persistence.entity
|
||||
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.nodeapi.internal.SignedNodeInfo
|
||||
import java.io.Serializable
|
||||
import java.time.Instant
|
||||
@ -21,10 +22,12 @@ data class NodeInfoEntity(
|
||||
// Hash of serialized [NodeInfo] without signatures.
|
||||
@Id
|
||||
@Column(name = "node_info_hash", length = 64)
|
||||
// AttributeConverters can't be used on @Id attributes, otherwise this would be SecureHash
|
||||
val nodeInfoHash: String,
|
||||
|
||||
@Column(name = "public_key_hash", length = 64)
|
||||
val publicKeyHash: String,
|
||||
@Convert(converter = SecureHashAttributeConverter::class)
|
||||
val publicKeyHash: SecureHash,
|
||||
|
||||
@ManyToOne(optional = false, fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "cert_signing_request", nullable = false)
|
||||
|
@ -46,12 +46,6 @@ data class CertPathAndKey(val certPath: List<X509Certificate>, val key: PrivateK
|
||||
fun toKeyPair(): KeyPair = KeyPair(certPath[0].publicKey, key)
|
||||
}
|
||||
|
||||
// TODO: replace this with Crypto.hash when its available.
|
||||
/**
|
||||
* Returns SHA256 hash of this public key
|
||||
*/
|
||||
fun PublicKey.hashString() = encoded.sha256().toString()
|
||||
|
||||
inline fun <reified T : Any> parseConfig(file: Path): T {
|
||||
val config = ConfigFactory.parseFile(file.toFile(), ConfigParseOptions.defaults().setAllowMissing(true)).resolve()
|
||||
logger.info(config.root().render(ConfigRenderOptions.defaults()))
|
||||
|
@ -2,7 +2,7 @@ package com.r3.corda.networkmanage.doorman.webservice
|
||||
|
||||
import com.r3.corda.networkmanage.doorman.signer.CrrHandler
|
||||
import com.r3.corda.networkmanage.doorman.webservice.CertificateRevocationRequestWebService.Companion.CRR_PATH
|
||||
import net.corda.core.serialization.deserialize
|
||||
import net.corda.core.internal.readObject
|
||||
import net.corda.core.utilities.contextLogger
|
||||
import net.corda.nodeapi.internal.network.CertificateRevocationRequest
|
||||
import java.io.InputStream
|
||||
@ -28,7 +28,7 @@ class CertificateRevocationRequestWebService(private val crrHandler: CrrHandler)
|
||||
@Produces(MediaType.TEXT_PLAIN)
|
||||
fun submitRequest(input: InputStream): Response {
|
||||
return try {
|
||||
val request = input.readBytes().deserialize<CertificateRevocationRequest>()
|
||||
val request = input.readObject<CertificateRevocationRequest>()
|
||||
val requestId = crrHandler.saveRevocationRequest(request)
|
||||
ok(requestId)
|
||||
} catch (e: Exception) {
|
||||
|
@ -22,9 +22,9 @@ import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.crypto.SignedData
|
||||
import net.corda.core.crypto.sha256
|
||||
import net.corda.core.internal.CertRole
|
||||
import net.corda.core.internal.readObject
|
||||
import net.corda.core.node.NetworkParameters
|
||||
import net.corda.core.node.NodeInfo
|
||||
import net.corda.core.serialization.deserialize
|
||||
import net.corda.core.serialization.serialize
|
||||
import net.corda.core.utilities.contextLogger
|
||||
import net.corda.core.utilities.debug
|
||||
@ -84,7 +84,7 @@ class NetworkMapWebService(private val nodeInfoStorage: NodeInfoStorage,
|
||||
@Path("publish")
|
||||
@Consumes(MediaType.APPLICATION_OCTET_STREAM)
|
||||
fun registerNode(input: InputStream): Response {
|
||||
val signedNodeInfo = input.readBytes().deserialize<SignedNodeInfo>()
|
||||
val signedNodeInfo = input.readObject<SignedNodeInfo>()
|
||||
var nodeInfo: NodeInfo? = null
|
||||
return try {
|
||||
// Store the NodeInfo
|
||||
@ -111,7 +111,7 @@ class NetworkMapWebService(private val nodeInfoStorage: NodeInfoStorage,
|
||||
@Consumes(MediaType.APPLICATION_OCTET_STREAM)
|
||||
fun ackNetworkParameters(input: InputStream): Response {
|
||||
return try {
|
||||
val signedParametersHash = input.readBytes().deserialize<SignedData<SecureHash>>()
|
||||
val signedParametersHash = input.readObject<SignedData<SecureHash>>()
|
||||
val hash = signedParametersHash.verified()
|
||||
networkMapStorage.getSignedNetworkParameters(hash) ?: throw IllegalArgumentException("No network parameters with hash $hash")
|
||||
logger.debug { "Received ack-parameters with $hash from ${signedParametersHash.sig.by}" }
|
||||
|
@ -12,6 +12,7 @@ package com.r3.corda.networkmanage.doorman.webservice
|
||||
|
||||
import com.r3.corda.networkmanage.common.persistence.CertificateResponse
|
||||
import com.r3.corda.networkmanage.doorman.signer.CsrHandler
|
||||
import net.corda.core.internal.readFully
|
||||
import net.corda.nodeapi.internal.crypto.X509Utilities.CORDA_CLIENT_CA
|
||||
import net.corda.nodeapi.internal.crypto.X509Utilities.CORDA_INTERMEDIATE_CA
|
||||
import net.corda.nodeapi.internal.crypto.X509Utilities.CORDA_ROOT_CA
|
||||
@ -45,7 +46,7 @@ class RegistrationWebService(private val csrHandler: CsrHandler, private val cli
|
||||
@Consumes(MediaType.APPLICATION_OCTET_STREAM)
|
||||
@Produces(MediaType.TEXT_PLAIN)
|
||||
fun submitRequest(input: InputStream): Response {
|
||||
val csr = input.use { JcaPKCS10CertificationRequest(it.readBytes()) }
|
||||
val csr = JcaPKCS10CertificationRequest(input.readFully())
|
||||
if (!csr.isSignatureValid()) {
|
||||
return status(Response.Status.BAD_REQUEST).entity("Invalid CSR signature").build()
|
||||
}
|
||||
|
@ -12,7 +12,6 @@ package com.r3.corda.networkmanage.hsm.authentication
|
||||
|
||||
import CryptoServerJCE.CryptoServerProvider
|
||||
import com.r3.corda.networkmanage.common.signer.AuthenticationException
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.nio.file.Path
|
||||
import kotlin.reflect.full.memberProperties
|
||||
@ -155,9 +154,6 @@ fun createProvider(config: CryptoServerProviderConfig): CryptoServerProvider {
|
||||
writer.write("${property.name} = ${property.get(config)}\n")
|
||||
}
|
||||
writer.close()
|
||||
val cfg = ByteArrayInputStream(cfgBuffer.toByteArray())
|
||||
cfgBuffer.close()
|
||||
val provider = CryptoServerProvider(cfg)
|
||||
cfg.close()
|
||||
return provider
|
||||
val cfg = cfgBuffer.toByteArray().inputStream()
|
||||
return CryptoServerProvider(cfg)
|
||||
}
|
@ -14,9 +14,7 @@ import com.r3.corda.networkmanage.TestBase
|
||||
import com.r3.corda.networkmanage.common.persistence.entity.NodeInfoEntity
|
||||
import com.r3.corda.networkmanage.common.persistence.entity.ParametersUpdateEntity
|
||||
import com.r3.corda.networkmanage.common.persistence.entity.UpdateStatus
|
||||
import com.r3.corda.networkmanage.common.utils.hashString
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.crypto.sha256
|
||||
import net.corda.core.serialization.serialize
|
||||
import net.corda.core.utilities.days
|
||||
import net.corda.nodeapi.internal.createDevNetworkMapCa
|
||||
|
@ -12,12 +12,11 @@ package com.r3.corda.networkmanage.common.persistence
|
||||
|
||||
import com.r3.corda.networkmanage.TestBase
|
||||
import com.r3.corda.networkmanage.common.persistence.entity.NodeInfoEntity
|
||||
import com.r3.corda.networkmanage.common.utils.hashString
|
||||
import net.corda.core.crypto.Crypto
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.crypto.sha256
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.internal.CertRole
|
||||
import net.corda.core.internal.hash
|
||||
import net.corda.core.serialization.serialize
|
||||
import net.corda.core.utilities.days
|
||||
import net.corda.nodeapi.internal.NodeInfoAndSigned
|
||||
@ -86,14 +85,14 @@ class PersistentNodeInfoStorageTest : TestBase() {
|
||||
requestStorage.markRequestTicketCreated(requestId)
|
||||
requestStorage.approveRequest(requestId, CertificateSigningRequestStorage.DOORMAN_SIGNATURE)
|
||||
|
||||
assertNull(nodeInfoStorage.getCertificatePath(SecureHash.parse(keyPair.public.hashString())))
|
||||
assertNull(nodeInfoStorage.getCertificatePath(keyPair.public.hash))
|
||||
|
||||
requestStorage.putCertificatePath(
|
||||
requestId,
|
||||
X509Utilities.buildCertPath(nodeCaCert, doormanCertAndKeyPair.certificate, rootCaCert),
|
||||
CertificateSigningRequestStorage.DOORMAN_SIGNATURE)
|
||||
|
||||
val storedCertPath = nodeInfoStorage.getCertificatePath(SecureHash.parse(keyPair.public.hashString()))
|
||||
val storedCertPath = nodeInfoStorage.getCertificatePath(keyPair.public.hash)
|
||||
assertNotNull(storedCertPath)
|
||||
|
||||
assertEquals(nodeCaCert, storedCertPath!!.certificates.first())
|
||||
|
Loading…
Reference in New Issue
Block a user