Merge remote-tracking branch 'origin/master' into aslemmer-merge-19-Feb

This commit is contained in:
Andras Slemmer
2018-02-23 11:18:16 +00:00
26 changed files with 706 additions and 194 deletions

View File

@ -6,6 +6,7 @@ import com.r3.corda.networkmanage.common.persistence.entity.CertificateSigningRe
import net.corda.core.crypto.Crypto
import net.corda.core.crypto.SecureHash
import net.corda.core.identity.CordaX500Name
import net.corda.core.internal.CertRole
import net.corda.nodeapi.internal.crypto.X509Utilities
import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.nodeapi.internal.persistence.DatabaseConfig
@ -40,7 +41,7 @@ class PersistentCertificateRequestStorageTest : TestBase() {
@Test
fun `valid request`() {
val request = createRequest("LegalName").first
val request = createRequest("LegalName", certRole = CertRole.NODE_CA).first
val requestId = storage.saveRequest(request)
assertNotNull(storage.getRequest(requestId)).apply {
assertEquals(request, this.request)
@ -48,9 +49,29 @@ class PersistentCertificateRequestStorageTest : TestBase() {
assertThat(storage.getRequests(RequestStatus.NEW).map { it.requestId }).containsOnly(requestId)
}
@Test
fun `valid service identity request`() {
val request = createRequest("LegalName", certRole = CertRole.SERVICE_IDENTITY).first
val requestId = storage.saveRequest(request)
assertNotNull(storage.getRequest(requestId)).apply {
assertEquals(request, this.request)
}
assertThat(storage.getRequests(RequestStatus.NEW).map { it.requestId }).containsOnly(requestId)
}
@Test
fun `invalid cert role request`() {
val request = createRequest("LegalName", certRole = CertRole.INTERMEDIATE_CA).first
val requestId = storage.saveRequest(request)
assertNotNull(storage.getRequest(requestId)).apply {
assertEquals(request, this.request)
}
assertThat(storage.getRequests(RequestStatus.REJECTED).map { it.requestId }).containsOnly(requestId)
}
@Test
fun `approve request`() {
val (request, _) = createRequest("LegalName")
val (request, _) = createRequest("LegalName", certRole = CertRole.NODE_CA)
// Add request to DB.
val requestId = storage.saveRequest(request)
// Pending request should equals to 1.
@ -69,7 +90,7 @@ class PersistentCertificateRequestStorageTest : TestBase() {
@Test
fun `sign request`() {
val (csr, nodeKeyPair) = createRequest("LegalName")
val (csr, nodeKeyPair) = createRequest("LegalName", certRole = CertRole.NODE_CA)
// Add request to DB.
val requestId = storage.saveRequest(csr)
// New request should equals to 1.
@ -95,7 +116,7 @@ class PersistentCertificateRequestStorageTest : TestBase() {
@Test
fun `sign request ignores subsequent sign requests`() {
val (csr, nodeKeyPair) = createRequest("LegalName")
val (csr, nodeKeyPair) = createRequest("LegalName", certRole = CertRole.NODE_CA)
// Add request to DB.
val requestId = storage.saveRequest(csr)
// Store certificate to DB.
@ -118,7 +139,7 @@ class PersistentCertificateRequestStorageTest : TestBase() {
@Test
fun `sign request rejects requests with the same public key`() {
val (csr, nodeKeyPair) = createRequest("LegalName")
val (csr, nodeKeyPair) = createRequest("LegalName", certRole = CertRole.NODE_CA)
// Add request to DB.
val requestId = storage.saveRequest(csr)
// Store certificate to DB.
@ -132,7 +153,7 @@ class PersistentCertificateRequestStorageTest : TestBase() {
)
// Sign certificate
// When request with the same public key is requested
val (newCsr, _) = createRequest("NewLegalName", nodeKeyPair)
val (newCsr, _) = createRequest("NewLegalName", nodeKeyPair, certRole = CertRole.NODE_CA)
val duplicateRequestId = storage.saveRequest(newCsr)
assertThat(storage.getRequests(RequestStatus.NEW)).isEmpty()
val duplicateRequest = storage.getRequest(duplicateRequestId)
@ -142,7 +163,7 @@ class PersistentCertificateRequestStorageTest : TestBase() {
@Test
fun `reject request`() {
val requestId = storage.saveRequest(createRequest("BankA").first)
val requestId = storage.saveRequest(createRequest("BankA", certRole = CertRole.NODE_CA).first)
storage.rejectRequest(requestId, DOORMAN_SIGNATURE, "Because I said so!")
assertThat(storage.getRequests(RequestStatus.NEW)).isEmpty()
assertThat(storage.getRequest(requestId)!!.remark).isEqualTo("Because I said so!")
@ -150,9 +171,9 @@ class PersistentCertificateRequestStorageTest : TestBase() {
@Test
fun `request with the same legal name as a pending request`() {
val requestId1 = storage.saveRequest(createRequest("BankA").first)
val requestId1 = storage.saveRequest(createRequest("BankA", certRole = CertRole.NODE_CA).first)
assertThat(storage.getRequests(RequestStatus.NEW).map { it.requestId }).containsOnly(requestId1)
val requestId2 = storage.saveRequest(createRequest("BankA").first)
val requestId2 = storage.saveRequest(createRequest("BankA", certRole = CertRole.NODE_CA).first)
assertThat(storage.getRequests(RequestStatus.NEW).map { it.requestId }).containsOnly(requestId1)
assertEquals(RequestStatus.REJECTED, storage.getRequest(requestId2)!!.status)
assertThat(storage.getRequest(requestId2)!!.remark).containsIgnoringCase("duplicate")
@ -164,16 +185,16 @@ class PersistentCertificateRequestStorageTest : TestBase() {
@Test
fun `request with the same legal name as a previously approved request`() {
val requestId1 = storage.saveRequest(createRequest("BankA").first)
val requestId1 = storage.saveRequest(createRequest("BankA", certRole = CertRole.NODE_CA).first)
storage.markRequestTicketCreated(requestId1)
storage.approveRequest(requestId1, DOORMAN_SIGNATURE)
val requestId2 = storage.saveRequest(createRequest("BankA").first)
val requestId2 = storage.saveRequest(createRequest("BankA", certRole = CertRole.NODE_CA).first)
assertThat(storage.getRequest(requestId2)!!.remark).containsIgnoringCase("duplicate")
}
@Test
fun `request with the same legal name as a previously signed request`() {
val (csr, nodeKeyPair) = createRequest("BankA")
val (csr, nodeKeyPair) = createRequest("BankA", certRole = CertRole.NODE_CA)
val requestId = storage.saveRequest(csr)
storage.markRequestTicketCreated(requestId)
storage.approveRequest(requestId, DOORMAN_SIGNATURE)
@ -183,15 +204,15 @@ class PersistentCertificateRequestStorageTest : TestBase() {
generateSignedCertPath(csr, nodeKeyPair),
listOf(DOORMAN_SIGNATURE)
)
val rejectedRequestId = storage.saveRequest(createRequest("BankA").first)
val rejectedRequestId = storage.saveRequest(createRequest("BankA", certRole = CertRole.NODE_CA).first)
assertThat(storage.getRequest(rejectedRequestId)!!.remark).containsIgnoringCase("duplicate")
}
@Test
fun `request with the same legal name as a previously rejected request`() {
val requestId1 = storage.saveRequest(createRequest("BankA").first)
val requestId1 = storage.saveRequest(createRequest("BankA", certRole = CertRole.NODE_CA).first)
storage.rejectRequest(requestId1, DOORMAN_SIGNATURE, "Because I said so!")
val requestId2 = storage.saveRequest(createRequest("BankA").first)
val requestId2 = storage.saveRequest(createRequest("BankA", certRole = CertRole.NODE_CA).first)
assertThat(storage.getRequests(RequestStatus.NEW).map { it.requestId }).containsOnly(requestId2)
storage.markRequestTicketCreated(requestId2)
storage.approveRequest(requestId2, DOORMAN_SIGNATURE)
@ -204,7 +225,7 @@ class PersistentCertificateRequestStorageTest : TestBase() {
val approver = "APPROVER"
// when
val requestId = storage.saveRequest(createRequest("BankA").first)
val requestId = storage.saveRequest(createRequest("BankA", certRole = CertRole.NODE_CA).first)
storage.markRequestTicketCreated(requestId)
storage.approveRequest(requestId, approver)
@ -242,7 +263,8 @@ class PersistentCertificateRequestStorageTest : TestBase() {
}
}
internal fun createRequest(organisation: String, keyPair: KeyPair = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)): Pair<PKCS10CertificationRequest, KeyPair> {
val request = X509Utilities.createCertificateSigningRequest(X500Principal("O=$organisation,L=London,C=GB"), "my@mail.com", keyPair)
return Pair(request, keyPair)
internal fun createRequest(organisation: String, keyPair: KeyPair = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME), certRole: CertRole): Pair<PKCS10CertificationRequest, KeyPair> {
val request = X509Utilities.createCertificateSigningRequest(X500Principal("O=$organisation,L=London,C=GB"), "my@mail.com", keyPair, certRole = certRole)
// encode and decode the request to make sure class information (CertRole) etc are not passed into the test.
return Pair(JcaPKCS10CertificationRequest(request.encoded), keyPair)
}

View File

@ -5,6 +5,7 @@ import com.r3.corda.networkmanage.common.utils.hashString
import net.corda.core.crypto.Crypto
import net.corda.core.crypto.SecureHash
import net.corda.core.identity.CordaX500Name
import net.corda.core.internal.CertRole
import net.corda.core.serialization.serialize
import net.corda.nodeapi.internal.crypto.CertificateAndKeyPair
import net.corda.nodeapi.internal.crypto.CertificateType
@ -132,7 +133,7 @@ class PersistentNodeInfoStorageTest : TestBase() {
internal fun createValidSignedNodeInfo(organisation: String,
storage: CertificationRequestStorage): Pair<NodeInfoWithSigned, PrivateKey> {
val (csr, nodeKeyPair) = createRequest(organisation)
val (csr, nodeKeyPair) = createRequest(organisation, certRole = CertRole.NODE_CA)
val requestId = storage.saveRequest(csr)
storage.markRequestTicketCreated(requestId)
storage.approveRequest(requestId, "TestUser")

View File

@ -8,7 +8,6 @@ import com.r3.corda.networkmanage.common.persistence.CertificationRequestStorage
import com.r3.corda.networkmanage.common.persistence.CertificationRequestStorage.Companion.DOORMAN_SIGNATURE
import com.r3.corda.networkmanage.common.persistence.RequestStatus
import com.r3.corda.networkmanage.common.utils.CertPathAndKey
import com.r3.corda.networkmanage.common.utils.buildCertPath
import net.corda.core.crypto.Crypto
import net.corda.core.internal.CertRole
import net.corda.nodeapi.internal.crypto.X509Utilities
@ -83,6 +82,49 @@ class DefaultCsrHandlerTest : TestBase() {
assertThat(CertRole.extract(this)).isEqualTo(CertRole.NODE_CA)
assertThat(publicKey).isEqualTo(Crypto.toSupportedPublicKey(requests[index].subjectPublicKeyInfo))
assertThat(subjectX500Principal).isEqualTo(X500Principal("O=Test${index + 1},L=London,C=GB"))
// Is CA
assertThat(basicConstraints != -1)
}
}
}
@Test
fun `process approved service identity request`() {
val requests = (1..3).map {
X509Utilities.createCertificateSigningRequest(
X500Principal("O=Test$it,L=London,C=GB"),
"my@email.com",
Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME), certRole = CertRole.SERVICE_IDENTITY)
}
val requestStorage: CertificationRequestStorage = mock {
on { getRequests(RequestStatus.APPROVED) }.thenReturn(listOf(
certificateSigningRequest(requestId = "1", request = requests[0], status = RequestStatus.APPROVED)
))
}
val (rootCa, csrCa) = createDevIntermediateCaCertPath()
val csrCertPathAndKey = CertPathAndKey(listOf(csrCa.certificate, rootCa.certificate), csrCa.keyPair.private)
val requestProcessor = DefaultCsrHandler(requestStorage, csrCertPathAndKey)
requestProcessor.processRequests()
val certPathCapture = argumentCaptor<CertPath>()
// Verify only the approved requests are taken
verify(requestStorage, times(1)).getRequests(RequestStatus.APPROVED)
verify(requestStorage, times(1)).putCertificatePath(eq("1"), certPathCapture.capture(), eq(listOf(DOORMAN_SIGNATURE)))
// Then make sure the generated node cert paths are correct
certPathCapture.allValues.forEachIndexed { index, certPath ->
X509Utilities.validateCertificateChain(rootCa.certificate, certPath.x509Certificates)
assertThat(certPath.certificates).hasSize(3).element(1).isEqualTo(csrCa.certificate)
(certPath.certificates[0] as X509Certificate).apply {
assertThat(CertRole.extract(this)).isEqualTo(CertRole.SERVICE_IDENTITY)
assertThat(publicKey).isEqualTo(Crypto.toSupportedPublicKey(requests[index].subjectPublicKeyInfo))
assertThat(subjectX500Principal).isEqualTo(X500Principal("O=Test${index + 1},L=London,C=GB"))
// Not a CA
assertThat(basicConstraints == -1)
}
}
}