mirror of
https://github.com/corda/corda.git
synced 2025-01-29 15:43:55 +00:00
CORDA-1661 Reverting DEV certificates (#3422)
* CORDA-1661 Reverting DEV certificates * Addressing review comments * Removed the intermediate certificate from the trust store and added some test cases for the revocation check
This commit is contained in:
parent
868763f82b
commit
e00c7706c3
Binary file not shown.
Binary file not shown.
@ -0,0 +1,41 @@
|
||||
package net.corda.nodeapi.internal.crypto
|
||||
|
||||
import net.corda.core.internal.validate
|
||||
import net.corda.nodeapi.internal.DEV_CA_TRUST_STORE_FILE
|
||||
import net.corda.nodeapi.internal.DEV_CA_TRUST_STORE_PASS
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TemporaryFolder
|
||||
import java.security.cert.TrustAnchor
|
||||
import java.security.cert.X509Certificate
|
||||
|
||||
class DevCertificatesTest {
|
||||
private companion object {
|
||||
const val OLD_DEV_KEYSTORE_PASS = "password"
|
||||
const val OLD_NODE_DEV_KEYSTORE_FILE_NAME = "nodekeystore.jks"
|
||||
}
|
||||
|
||||
@Rule
|
||||
@JvmField
|
||||
val tempFolder = TemporaryFolder()
|
||||
|
||||
@Test
|
||||
fun `create server certificate in keystore for SSL`() {
|
||||
// given
|
||||
val newTrustStore = loadKeyStore(javaClass.classLoader.getResourceAsStream("certificates/$DEV_CA_TRUST_STORE_FILE"), DEV_CA_TRUST_STORE_PASS)
|
||||
val newTrustRoot = newTrustStore.getX509Certificate(X509Utilities.CORDA_ROOT_CA)
|
||||
val newTrustAnchor = TrustAnchor(newTrustRoot, null)
|
||||
|
||||
val oldNodeCaKeyStore = loadKeyStore(javaClass.classLoader.getResourceAsStream("regression-test/$OLD_NODE_DEV_KEYSTORE_FILE_NAME"), OLD_DEV_KEYSTORE_PASS)
|
||||
val oldX509Certificates = oldNodeCaKeyStore.getCertificateChain(X509Utilities.CORDA_CLIENT_CA).map {
|
||||
it as X509Certificate
|
||||
}.toTypedArray()
|
||||
|
||||
val certPath = X509Utilities.buildCertPath(*oldX509Certificates)
|
||||
|
||||
// when
|
||||
certPath.validate(newTrustAnchor)
|
||||
|
||||
// then no exception is thrown
|
||||
}
|
||||
}
|
BIN
node-api/src/test/resources/regression-test/nodekeystore.jks
Normal file
BIN
node-api/src/test/resources/regression-test/nodekeystore.jks
Normal file
Binary file not shown.
BIN
node-api/src/test/resources/regression-test/sslkeystore.jks
Normal file
BIN
node-api/src/test/resources/regression-test/sslkeystore.jks
Normal file
Binary file not shown.
@ -94,7 +94,7 @@ class CertificateRevocationListNodeTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Simple AMPQ Client to Server connection works`() {
|
||||
fun `Simple AMPQ Client to Server connection works and soft fail is enabled`() {
|
||||
val crlCheckSoftFail = true
|
||||
val (amqpServer, _) = createServer(serverPort, crlCheckSoftFail = crlCheckSoftFail)
|
||||
amqpServer.use {
|
||||
@ -126,7 +126,39 @@ class CertificateRevocationListNodeTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `AMPQ Client to Server connection fails when client's certificate is revoked`() {
|
||||
fun `Simple AMPQ Client to Server connection works and soft fail is disabled`() {
|
||||
val crlCheckSoftFail = false
|
||||
val (amqpServer, _) = createServer(serverPort, crlCheckSoftFail = crlCheckSoftFail)
|
||||
amqpServer.use {
|
||||
amqpServer.start()
|
||||
val receiveSubs = amqpServer.onReceive.subscribe {
|
||||
assertEquals(BOB_NAME.toString(), it.sourceLegalName)
|
||||
assertEquals(P2P_PREFIX + "Test", it.topic)
|
||||
assertEquals("Test", String(it.payload))
|
||||
it.complete(true)
|
||||
}
|
||||
val (amqpClient, _) = createClient(serverPort, crlCheckSoftFail)
|
||||
amqpClient.use {
|
||||
val serverConnected = amqpServer.onConnection.toFuture()
|
||||
val clientConnected = amqpClient.onConnection.toFuture()
|
||||
amqpClient.start()
|
||||
val serverConnect = serverConnected.get()
|
||||
assertEquals(true, serverConnect.connected)
|
||||
val clientConnect = clientConnected.get()
|
||||
assertEquals(true, clientConnect.connected)
|
||||
val msg = amqpClient.createMessage("Test".toByteArray(),
|
||||
P2P_PREFIX + "Test",
|
||||
ALICE_NAME.toString(),
|
||||
emptyMap())
|
||||
amqpClient.write(msg)
|
||||
assertEquals(MessageStatus.Acknowledged, msg.onComplete.get())
|
||||
receiveSubs.unsubscribe()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `AMPQ Client to Server connection fails when client's certificate is revoked and soft fail is enabled`() {
|
||||
val crlCheckSoftFail = true
|
||||
val (amqpServer, _) = createServer(serverPort, crlCheckSoftFail = crlCheckSoftFail)
|
||||
amqpServer.use {
|
||||
@ -146,6 +178,27 @@ class CertificateRevocationListNodeTests {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `AMPQ Client to Server connection fails when client's certificate is revoked and soft fail is disabled`() {
|
||||
val crlCheckSoftFail = false
|
||||
val (amqpServer, _) = createServer(serverPort, crlCheckSoftFail = crlCheckSoftFail)
|
||||
amqpServer.use {
|
||||
amqpServer.start()
|
||||
amqpServer.onReceive.subscribe {
|
||||
it.complete(true)
|
||||
}
|
||||
val (amqpClient, clientCert) = createClient(serverPort, crlCheckSoftFail)
|
||||
revokedNodeCerts.add(clientCert.serialNumber)
|
||||
amqpClient.use {
|
||||
val serverConnected = amqpServer.onConnection.toFuture()
|
||||
amqpClient.onConnection.toFuture()
|
||||
amqpClient.start()
|
||||
val serverConnect = serverConnected.get()
|
||||
assertEquals(false, serverConnect.connected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `AMPQ Client to Server connection fails when servers's certificate is revoked`() {
|
||||
val crlCheckSoftFail = true
|
||||
|
@ -15,12 +15,10 @@ import net.corda.core.flows.FlowException
|
||||
import net.corda.core.identity.AbstractParty
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.internal.AbstractAttachment
|
||||
import net.corda.core.internal.x500Name
|
||||
import net.corda.core.serialization.*
|
||||
import net.corda.core.transactions.LedgerTransaction
|
||||
import net.corda.core.utilities.OpaqueBytes
|
||||
import net.corda.node.serialization.amqp.AMQPServerSerializationScheme
|
||||
import net.corda.nodeapi.internal.DEV_INTERMEDIATE_CA
|
||||
import net.corda.nodeapi.internal.crypto.ContentSignerBuilder
|
||||
import net.corda.serialization.internal.*
|
||||
import net.corda.serialization.internal.amqp.SerializerFactory.Companion.isPrimitive
|
||||
@ -35,6 +33,7 @@ import org.apache.qpid.proton.amqp.*
|
||||
import org.apache.qpid.proton.codec.DecoderImpl
|
||||
import org.apache.qpid.proton.codec.EncoderImpl
|
||||
import org.assertj.core.api.Assertions.*
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import org.bouncycastle.cert.X509v2CRLBuilder
|
||||
import org.bouncycastle.cert.jcajce.JcaX509CRLConverter
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider
|
||||
@ -657,8 +656,8 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
|
||||
val scheme = AMQPServerSerializationScheme(emptyList())
|
||||
val func = scheme::class.superclasses.single { it.simpleName == "AbstractAMQPSerializationScheme" }
|
||||
.java.getDeclaredMethod("registerCustomSerializers",
|
||||
SerializationContext::class.java,
|
||||
SerializerFactory::class.java)
|
||||
SerializationContext::class.java,
|
||||
SerializerFactory::class.java)
|
||||
func.isAccessible = true
|
||||
|
||||
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
|
||||
@ -1011,7 +1010,7 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
|
||||
}
|
||||
|
||||
private fun emptyCrl(): X509CRL {
|
||||
val builder = X509v2CRLBuilder(CordaX500Name.build(DEV_INTERMEDIATE_CA.certificate.issuerX500Principal).x500Name, Date())
|
||||
val builder = X509v2CRLBuilder(X500Name("CN=Corda Root CA, O=R3 HoldCo LLC, L=New York, C=US"), Date())
|
||||
val provider = BouncyCastleProvider()
|
||||
val crlHolder = builder.build(ContentSignerBuilder.build(Crypto.RSA_SHA256, Crypto.generateKeyPair(Crypto.RSA_SHA256).private, provider))
|
||||
return JcaX509CRLConverter().setProvider(provider).getCRL(crlHolder)
|
||||
@ -1320,12 +1319,12 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
|
||||
}
|
||||
|
||||
interface DataClassByInterface<V> {
|
||||
val v : V
|
||||
val v: V
|
||||
}
|
||||
|
||||
@Test
|
||||
fun dataClassBy() {
|
||||
data class C (val s: String) : DataClassByInterface<String> {
|
||||
data class C(val s: String) : DataClassByInterface<String> {
|
||||
override val v: String = "-- $s"
|
||||
}
|
||||
|
||||
@ -1339,8 +1338,8 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
|
||||
|
||||
try {
|
||||
val i2 = DeserializationInput(testDefaultFactory()).deserialize(bytes)
|
||||
} catch (e : NotSerializableException) {
|
||||
throw Error ("Deserializing serialized \$C should not throw")
|
||||
} catch (e: NotSerializableException) {
|
||||
throw Error("Deserializing serialized \$C should not throw")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user