mirror of
https://github.com/corda/corda.git
synced 2025-01-31 08:25:50 +00:00
Added commonName extension method to X500Name and helper class for x509 cert factories
This commit is contained in:
parent
57975c6e91
commit
9d98673c66
@ -430,14 +430,8 @@ object X509Utilities {
|
|||||||
fun loadCertificateFromPEMFile(filename: Path): X509Certificate {
|
fun loadCertificateFromPEMFile(filename: Path): X509Certificate {
|
||||||
val reader = PemReader(FileReader(filename.toFile()))
|
val reader = PemReader(FileReader(filename.toFile()))
|
||||||
val pemObject = reader.readPemObject()
|
val pemObject = reader.readPemObject()
|
||||||
val certFact = CertificateFactory.getInstance("X.509", BouncyCastleProvider.PROVIDER_NAME)
|
return CertificateStream(pemObject.content.inputStream()).nextCertificate().apply {
|
||||||
val inputStream = ByteArrayInputStream(pemObject.content)
|
checkValidity()
|
||||||
try {
|
|
||||||
val cert = certFact.generateCertificate(inputStream) as X509Certificate
|
|
||||||
cert.checkValidity()
|
|
||||||
return cert
|
|
||||||
} finally {
|
|
||||||
inputStream.close()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -609,3 +603,11 @@ object X509Utilities {
|
|||||||
return keyStore
|
return keyStore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val X500Name.commonName: String get() = getRDNs(BCStyle.CN).first().first.value.toString()
|
||||||
|
|
||||||
|
class CertificateStream(val input: InputStream) {
|
||||||
|
private val certificateFactory = CertificateFactory.getInstance("X.509")
|
||||||
|
|
||||||
|
fun nextCertificate(): X509Certificate = certificateFactory.generateCertificate(input) as X509Certificate
|
||||||
|
}
|
@ -8,7 +8,6 @@ import net.corda.core.serialization.DeserializeAsKotlinObjectDef
|
|||||||
import net.corda.core.serialization.deserialize
|
import net.corda.core.serialization.deserialize
|
||||||
import net.corda.core.serialization.serialize
|
import net.corda.core.serialization.serialize
|
||||||
import org.bouncycastle.asn1.x500.X500Name
|
import org.bouncycastle.asn1.x500.X500Name
|
||||||
import org.bouncycastle.asn1.x500.style.BCStyle
|
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.concurrent.atomic.AtomicBoolean
|
import java.util.concurrent.atomic.AtomicBoolean
|
||||||
@ -184,7 +183,6 @@ interface Message {
|
|||||||
interface ReceivedMessage : Message {
|
interface ReceivedMessage : Message {
|
||||||
/** The authenticated sender. */
|
/** The authenticated sender. */
|
||||||
val peer: X500Name
|
val peer: X500Name
|
||||||
val peerLegalName: String get() = peer.getRDNs(BCStyle.CN).first().first.value.toString()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A singleton that's useful for validating topic strings */
|
/** A singleton that's useful for validating topic strings */
|
||||||
|
@ -2,7 +2,6 @@ package net.corda.core.crypto
|
|||||||
|
|
||||||
import net.corda.core.div
|
import net.corda.core.div
|
||||||
import org.bouncycastle.asn1.x500.X500Name
|
import org.bouncycastle.asn1.x500.X500Name
|
||||||
import org.bouncycastle.asn1.x500.style.BCStyle
|
|
||||||
import org.bouncycastle.asn1.x509.GeneralName
|
import org.bouncycastle.asn1.x509.GeneralName
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
@ -249,8 +248,7 @@ class X509UtilitiesTest {
|
|||||||
val peerChain = clientSocket.session.peerCertificates
|
val peerChain = clientSocket.session.peerCertificates
|
||||||
val peerX500Principal = (peerChain[0] as X509Certificate).subjectX500Principal
|
val peerX500Principal = (peerChain[0] as X509Certificate).subjectX500Principal
|
||||||
val x500name = X500Name(peerX500Principal.name)
|
val x500name = X500Name(peerX500Principal.name)
|
||||||
val cn = x500name.getRDNs(BCStyle.CN).first().first.value.toString()
|
assertEquals("Mega Corp.", x500name.commonName)
|
||||||
assertEquals("Mega Corp.", cn)
|
|
||||||
|
|
||||||
|
|
||||||
val output = DataOutputStream(clientSocket.outputStream)
|
val output = DataOutputStream(clientSocket.outputStream)
|
||||||
|
@ -8,6 +8,7 @@ import com.esotericsoftware.kryo.io.Output
|
|||||||
import com.google.common.annotations.VisibleForTesting
|
import com.google.common.annotations.VisibleForTesting
|
||||||
import com.google.common.collect.HashMultimap
|
import com.google.common.collect.HashMultimap
|
||||||
import net.corda.core.ErrorOr
|
import net.corda.core.ErrorOr
|
||||||
|
import net.corda.core.crypto.commonName
|
||||||
import net.corda.core.messaging.RPCOps
|
import net.corda.core.messaging.RPCOps
|
||||||
import net.corda.core.messaging.RPCReturnsObservables
|
import net.corda.core.messaging.RPCReturnsObservables
|
||||||
import net.corda.core.serialization.SerializedBytes
|
import net.corda.core.serialization.SerializedBytes
|
||||||
@ -16,14 +17,12 @@ import net.corda.core.serialization.serialize
|
|||||||
import net.corda.core.utilities.debug
|
import net.corda.core.utilities.debug
|
||||||
import net.corda.node.services.RPCUserService
|
import net.corda.node.services.RPCUserService
|
||||||
import net.corda.node.services.User
|
import net.corda.node.services.User
|
||||||
import net.corda.node.services.config.NodeConfiguration
|
|
||||||
import net.corda.node.services.messaging.ArtemisMessagingComponent.Companion.NODE_USER
|
import net.corda.node.services.messaging.ArtemisMessagingComponent.Companion.NODE_USER
|
||||||
import net.corda.node.utilities.AffinityExecutor
|
import net.corda.node.utilities.AffinityExecutor
|
||||||
import org.apache.activemq.artemis.api.core.Message
|
import org.apache.activemq.artemis.api.core.Message
|
||||||
import org.apache.activemq.artemis.api.core.client.ClientConsumer
|
import org.apache.activemq.artemis.api.core.client.ClientConsumer
|
||||||
import org.apache.activemq.artemis.api.core.client.ClientMessage
|
import org.apache.activemq.artemis.api.core.client.ClientMessage
|
||||||
import org.bouncycastle.asn1.x500.X500Name
|
import org.bouncycastle.asn1.x500.X500Name
|
||||||
import org.bouncycastle.asn1.x500.style.BCStyle
|
|
||||||
import rx.Notification
|
import rx.Notification
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
import rx.Subscription
|
import rx.Subscription
|
||||||
@ -168,7 +167,7 @@ abstract class RPCDispatcher(val ops: RPCOps, val userService: RPCUserService, v
|
|||||||
val rpcUser = userService.getUser(validatedUser)
|
val rpcUser = userService.getUser(validatedUser)
|
||||||
if (rpcUser != null) {
|
if (rpcUser != null) {
|
||||||
return rpcUser
|
return rpcUser
|
||||||
} else if (X500Name(validatedUser).getRDNs(BCStyle.CN).first().first.value.toString() == nodeLegalName) {
|
} else if (X500Name(validatedUser).commonName == nodeLegalName) {
|
||||||
return nodeUser
|
return nodeUser
|
||||||
} else {
|
} else {
|
||||||
throw IllegalArgumentException("Validated user '$validatedUser' is not an RPC user nor the NODE user")
|
throw IllegalArgumentException("Validated user '$validatedUser' is not an RPC user nor the NODE user")
|
||||||
|
@ -12,6 +12,7 @@ import kotlinx.support.jdk8.collections.removeIf
|
|||||||
import net.corda.core.ThreadBox
|
import net.corda.core.ThreadBox
|
||||||
import net.corda.core.abbreviate
|
import net.corda.core.abbreviate
|
||||||
import net.corda.core.crypto.Party
|
import net.corda.core.crypto.Party
|
||||||
|
import net.corda.core.crypto.commonName
|
||||||
import net.corda.core.flows.FlowLogic
|
import net.corda.core.flows.FlowLogic
|
||||||
import net.corda.core.flows.FlowStateMachine
|
import net.corda.core.flows.FlowStateMachine
|
||||||
import net.corda.core.flows.StateMachineRunId
|
import net.corda.core.flows.StateMachineRunId
|
||||||
@ -220,7 +221,7 @@ class StateMachineManager(val serviceHub: ServiceHubInternal,
|
|||||||
// isn't required to be unique
|
// isn't required to be unique
|
||||||
// TODO For now have the doorman block signups with identical names, and names with characters that
|
// TODO For now have the doorman block signups with identical names, and names with characters that
|
||||||
// are used in X.500 name textual serialisation
|
// are used in X.500 name textual serialisation
|
||||||
val otherParty = serviceHub.networkMapCache.getNodeByLegalName(message.peerLegalName)?.legalIdentity
|
val otherParty = serviceHub.networkMapCache.getNodeByLegalName(message.peer.commonName)?.legalIdentity
|
||||||
if (otherParty != null) {
|
if (otherParty != null) {
|
||||||
onSessionInit(sessionMessage, otherParty)
|
onSessionInit(sessionMessage, otherParty)
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
package net.corda.node.utilities.certsigning
|
package net.corda.node.utilities.certsigning
|
||||||
|
|
||||||
|
import net.corda.core.crypto.CertificateStream
|
||||||
import org.apache.commons.io.IOUtils
|
import org.apache.commons.io.IOUtils
|
||||||
import org.bouncycastle.pkcs.PKCS10CertificationRequest
|
import org.bouncycastle.pkcs.PKCS10CertificationRequest
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.net.HttpURLConnection
|
import java.net.HttpURLConnection
|
||||||
|
import java.net.HttpURLConnection.*
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
import java.security.cert.Certificate
|
import java.security.cert.Certificate
|
||||||
import java.security.cert.CertificateFactory
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.zip.ZipInputStream
|
import java.util.zip.ZipInputStream
|
||||||
|
|
||||||
@ -24,18 +25,17 @@ class HTTPCertificateSigningService(val server: URL) : CertificateSigningService
|
|||||||
conn.requestMethod = "GET"
|
conn.requestMethod = "GET"
|
||||||
|
|
||||||
return when (conn.responseCode) {
|
return when (conn.responseCode) {
|
||||||
HttpURLConnection.HTTP_OK -> conn.inputStream.use {
|
HTTP_OK -> ZipInputStream(conn.inputStream).use {
|
||||||
ZipInputStream(it).use {
|
|
||||||
val certificates = ArrayList<Certificate>()
|
val certificates = ArrayList<Certificate>()
|
||||||
|
val stream = CertificateStream(it)
|
||||||
while (it.nextEntry != null) {
|
while (it.nextEntry != null) {
|
||||||
certificates.add(CertificateFactory.getInstance("X.509").generateCertificate(it))
|
certificates.add(stream.nextCertificate())
|
||||||
}
|
}
|
||||||
certificates.toTypedArray()
|
certificates.toTypedArray()
|
||||||
}
|
}
|
||||||
}
|
HTTP_NO_CONTENT -> null
|
||||||
HttpURLConnection.HTTP_NO_CONTENT -> null
|
HTTP_UNAUTHORIZED -> throw IOException("Certificate signing request has been rejected: ${conn.errorMessage}")
|
||||||
HttpURLConnection.HTTP_UNAUTHORIZED -> throw IOException("Certificate signing request has been rejected, please contact Corda network administrator for more information.")
|
else -> throwUnexpectedResponseCode(conn)
|
||||||
else -> throw IOException("Unexpected response code ${conn.responseCode} - ${IOUtils.toString(conn.errorStream)}")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,10 +49,15 @@ class HTTPCertificateSigningService(val server: URL) : CertificateSigningService
|
|||||||
conn.outputStream.write(request.encoded)
|
conn.outputStream.write(request.encoded)
|
||||||
|
|
||||||
return when (conn.responseCode) {
|
return when (conn.responseCode) {
|
||||||
HttpURLConnection.HTTP_OK -> IOUtils.toString(conn.inputStream)
|
HTTP_OK -> IOUtils.toString(conn.inputStream)
|
||||||
HttpURLConnection.HTTP_FORBIDDEN -> throw IOException("Client version $clientVersion is forbidden from accessing permissioning server, please upgrade to newer version.")
|
HTTP_FORBIDDEN -> throw IOException("Client version $clientVersion is forbidden from accessing permissioning server, please upgrade to newer version.")
|
||||||
else -> throw IOException("Unexpected response code ${conn.responseCode} - ${IOUtils.toString(conn.errorStream)}")
|
else -> throwUnexpectedResponseCode(conn)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun throwUnexpectedResponseCode(connection: HttpURLConnection): Nothing {
|
||||||
|
throw IOException("Unexpected response code ${connection.responseCode} - ${connection.errorMessage}")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val HttpURLConnection.errorMessage: String get() = IOUtils.toString(errorStream)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user