mirror of
https://github.com/corda/corda.git
synced 2025-01-20 11:39:09 +00:00
Legal name validation for X500Name (#983)
* * Legal name validation for X500Name while loading from config file. * * Removed unintended changes.
This commit is contained in:
parent
d52b0e5db9
commit
7e8de79848
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
package net.corda.core.utilities
|
package net.corda.core.utilities
|
||||||
|
|
||||||
|
import net.corda.core.crypto.commonName
|
||||||
|
import org.bouncycastle.asn1.x500.X500Name
|
||||||
import java.lang.Character.UnicodeScript.*
|
import java.lang.Character.UnicodeScript.*
|
||||||
import java.text.Normalizer
|
import java.text.Normalizer
|
||||||
import java.util.regex.Pattern
|
import java.util.regex.Pattern
|
||||||
@ -19,9 +21,13 @@ import javax.security.auth.x500.X500Principal
|
|||||||
*
|
*
|
||||||
* @throws IllegalArgumentException if the name does not meet the required rules. The message indicates why not.
|
* @throws IllegalArgumentException if the name does not meet the required rules. The message indicates why not.
|
||||||
*/
|
*/
|
||||||
@Throws(IllegalArgumentException::class)
|
|
||||||
fun validateLegalName(normalizedLegalName: String) {
|
fun validateLegalName(normalizedLegalName: String) {
|
||||||
rules.forEach { it.validate(normalizedLegalName) }
|
legalNameRules.forEach { it.validate(normalizedLegalName) }
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Implement X500 attribute validation once the specification has been finalised.
|
||||||
|
fun validateX500Name(x500Name: X500Name) {
|
||||||
|
validateLegalName(x500Name.commonName)
|
||||||
}
|
}
|
||||||
|
|
||||||
val WHITESPACE = "\\s++".toRegex()
|
val WHITESPACE = "\\s++".toRegex()
|
||||||
@ -35,7 +41,7 @@ fun normaliseLegalName(legalName: String): String {
|
|||||||
return Normalizer.normalize(trimmedLegalName, Normalizer.Form.NFKC)
|
return Normalizer.normalize(trimmedLegalName, Normalizer.Form.NFKC)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val rules: List<Rule<String>> = listOf(
|
private val legalNameRules: List<Rule<String>> = listOf(
|
||||||
UnicodeNormalizationRule(),
|
UnicodeNormalizationRule(),
|
||||||
CharacterRule(',', '=', '$', '"', '\'', '\\'),
|
CharacterRule(',', '=', '$', '"', '\'', '\\'),
|
||||||
WordRule("node", "server"),
|
WordRule("node", "server"),
|
||||||
@ -107,7 +113,7 @@ private class X500NameRule : Rule<String> {
|
|||||||
private class MustHaveAtLeastTwoLettersRule : Rule<String> {
|
private class MustHaveAtLeastTwoLettersRule : Rule<String> {
|
||||||
override fun validate(legalName: String) {
|
override fun validate(legalName: String) {
|
||||||
// Try to exclude names like "/", "£", "X" etc.
|
// Try to exclude names like "/", "£", "X" etc.
|
||||||
require(legalName.count { it.isLetter() } >= 3) { "Must have at least two letters" }
|
require(legalName.count { it.isLetter() } >= 3) { "Illegal input legal name '$legalName'. Legal name must have at least two letters" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ package net.corda.nodeapi.config
|
|||||||
import com.typesafe.config.Config
|
import com.typesafe.config.Config
|
||||||
import com.typesafe.config.ConfigUtil
|
import com.typesafe.config.ConfigUtil
|
||||||
import net.corda.core.noneOrSingle
|
import net.corda.core.noneOrSingle
|
||||||
|
import net.corda.core.utilities.validateX500Name
|
||||||
import net.corda.core.utilities.NetworkHostAndPort
|
import net.corda.core.utilities.NetworkHostAndPort
|
||||||
import net.corda.core.utilities.parseNetworkHostAndPort
|
import net.corda.core.utilities.parseNetworkHostAndPort
|
||||||
import org.bouncycastle.asn1.x500.X500Name
|
import org.bouncycastle.asn1.x500.X500Name
|
||||||
@ -72,7 +73,7 @@ private fun Config.getSingleValue(path: String, type: KType): Any? {
|
|||||||
Path::class -> Paths.get(getString(path))
|
Path::class -> Paths.get(getString(path))
|
||||||
URL::class -> URL(getString(path))
|
URL::class -> URL(getString(path))
|
||||||
Properties::class -> getConfig(path).toProperties()
|
Properties::class -> getConfig(path).toProperties()
|
||||||
X500Name::class -> X500Name(getString(path))
|
X500Name::class -> X500Name(getString(path)).apply(::validateX500Name)
|
||||||
else -> if (typeClass.java.isEnum) {
|
else -> if (typeClass.java.isEnum) {
|
||||||
parseEnum(typeClass.java, getString(path))
|
parseEnum(typeClass.java, getString(path))
|
||||||
} else {
|
} else {
|
||||||
|
@ -112,7 +112,7 @@ class ConfigParsingTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun x500Name() {
|
fun x500Name() {
|
||||||
testPropertyType<X500NameData, X500NameListData, X500Name>(getTestX509Name("Mock Node"), getTestX509Name("Mock Node 2"), valuesToString = true)
|
testPropertyType<X500NameData, X500NameListData, X500Name>(getTestX509Name("Mock Party"), getTestX509Name("Mock Party 2"), valuesToString = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -30,7 +30,7 @@ import java.util.concurrent.atomic.AtomicInteger
|
|||||||
class P2PMessagingTest : NodeBasedTest() {
|
class P2PMessagingTest : NodeBasedTest() {
|
||||||
private companion object {
|
private companion object {
|
||||||
val DISTRIBUTED_SERVICE_NAME = getTestX509Name("DistributedService")
|
val DISTRIBUTED_SERVICE_NAME = getTestX509Name("DistributedService")
|
||||||
val SERVICE_2_NAME = getTestX509Name("Service Node 2")
|
val SERVICE_2_NAME = getTestX509Name("Service 2")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -30,7 +30,7 @@ class P2PSecurityTest : NodeBasedTest() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `incorrect legal name for the network map service config`() {
|
fun `incorrect legal name for the network map service config`() {
|
||||||
val incorrectNetworkMapName = X509Utilities.getDevX509Name(random63BitValue().toString())
|
val incorrectNetworkMapName = X509Utilities.getDevX509Name("NetworkMap-${random63BitValue()}")
|
||||||
val node = startNode(BOB.name, configOverrides = mapOf(
|
val node = startNode(BOB.name, configOverrides = mapOf(
|
||||||
"networkMapService" to mapOf(
|
"networkMapService" to mapOf(
|
||||||
"address" to networkMapNode.configuration.p2pAddress.toString(),
|
"address" to networkMapNode.configuration.p2pAddress.toString(),
|
||||||
|
Loading…
Reference in New Issue
Block a user