Step through cert path when registering (#2027)

Ensure when registering identities, we store the certificate closest to the trust root, with the same name. This ensures that looking up an identity by name produces the best match, not earliest registered identity (often but not necessarily the same).
This commit is contained in:
Ross Nicoll 2017-11-10 17:41:45 +00:00 committed by GitHub
parent 6a569fb3f1
commit 076a8ab937
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 31 additions and 0 deletions

View File

@ -16,6 +16,7 @@ import java.security.PublicKey
import java.security.cert.* import java.security.cert.*
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
import javax.annotation.concurrent.ThreadSafe import javax.annotation.concurrent.ThreadSafe
import javax.security.auth.x500.X500Principal
/** /**
* Simple identity service which caches parties and provides functionality for efficient lookup. * Simple identity service which caches parties and provides functionality for efficient lookup.
@ -68,6 +69,21 @@ class InMemoryIdentityService(identities: Iterable<PartyAndCertificate> = emptyS
} }
throw e throw e
} }
// Ensure we record the first identity of the same name, first
val identityPrincipal = identity.name.x500Principal
val firstCertWithThisName: Certificate = identity.certPath.certificates.last { it ->
val principal = (it as? X509Certificate)?.subjectX500Principal
principal == identityPrincipal
}
if (firstCertWithThisName != identity.certificate) {
val certificates = identity.certPath.certificates
val idx = certificates.lastIndexOf(firstCertWithThisName)
val certFactory = CertificateFactory.getInstance("X509")
val firstPath = certFactory.generateCertPath(certificates.slice(idx..certificates.size - 1))
verifyAndRegisterIdentity(PartyAndCertificate(firstPath))
}
log.trace { "Registering identity $identity" } log.trace { "Registering identity $identity" }
keyToParties[identity.owningKey] = identity keyToParties[identity.owningKey] = identity
// Always keep the first party we registered, as that's the well known identity // Always keep the first party we registered, as that's the well known identity

View File

@ -14,6 +14,7 @@ import net.corda.core.utilities.loggerFor
import net.corda.core.utilities.MAX_HASH_HEX_SIZE import net.corda.core.utilities.MAX_HASH_HEX_SIZE
import net.corda.node.utilities.AppendOnlyPersistentMap import net.corda.node.utilities.AppendOnlyPersistentMap
import net.corda.node.utilities.NODE_DATABASE_PREFIX import net.corda.node.utilities.NODE_DATABASE_PREFIX
import net.corda.node.utilities.X509Utilities
import org.bouncycastle.cert.X509CertificateHolder import org.bouncycastle.cert.X509CertificateHolder
import java.io.ByteArrayInputStream import java.io.ByteArrayInputStream
import java.security.InvalidAlgorithmParameterException import java.security.InvalidAlgorithmParameterException
@ -126,6 +127,20 @@ class PersistentIdentityService(identities: Iterable<PartyAndCertificate> = empt
throw e throw e
} }
// Ensure we record the first identity of the same name, first
val identityPrincipal = identity.name.x500Principal
val firstCertWithThisName: Certificate = identity.certPath.certificates.last { it ->
val principal = (it as? X509Certificate)?.subjectX500Principal
principal == identityPrincipal
}
if (firstCertWithThisName != identity.certificate) {
val certificates = identity.certPath.certificates
val idx = certificates.lastIndexOf(firstCertWithThisName)
val certFactory = CertificateFactory.getInstance("X509")
val firstPath = certFactory.generateCertPath(certificates.slice(idx..certificates.size - 1))
verifyAndRegisterIdentity(PartyAndCertificate(firstPath))
}
log.debug { "Registering identity $identity" } log.debug { "Registering identity $identity" }
val key = mapToKey(identity) val key = mapToKey(identity)
keyToParties.addWithDuplicatesAllowed(key, identity) keyToParties.addWithDuplicatesAllowed(key, identity)