CORDA-3021: Introduce SignOnlyCryptoService and use it whenever possible (#5239)

* CORDA-3021: Introduce `SignOnlyCryptoService` and use it whenever possible

Also modify `CryptoServiceFactory` to show how sign only implementation can be created.

* CORDA-3021: Undo some of my earlier changes

Which after discussion with @dimosr and @fowlerrr proven to be contradictory.
This commit is contained in:
Viktor Kolomeyko 2019-06-27 11:55:59 +01:00 committed by Anthony Keenan
parent 0083931eb7
commit 51f1e442a3
3 changed files with 27 additions and 19 deletions

View File

@ -7,19 +7,11 @@ import org.bouncycastle.operator.ContentSigner
import java.security.KeyPair
import java.security.PublicKey
/**
* Unlike [CryptoService] can only perform "read-only" operations but never create new key pairs.
*/
@DoNotImplement
interface CryptoService {
/**
* Generate and store a new [KeyPair].
* Note that schemeNumberID is Corda specific. Cross-check with the network operator for supported schemeNumberID
* and their corresponding signature schemes. The main reason for using schemeNumberID and not algorithm OIDs is
* because some schemes might not be standardised and thus an official OID might for this scheme not exist yet.
*
* Returns the [PublicKey] of the generated [KeyPair].
*/
fun generateKeyPair(alias: String, scheme: SignatureScheme): PublicKey
interface SignOnlyCryptoService {
/** Check if this [CryptoService] has a private key entry for the input alias. */
fun containsKey(alias: String): Boolean
@ -52,4 +44,21 @@ interface CryptoService {
fun defaultTLSSignatureScheme(): SignatureScheme = X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME
}
/**
* Fully-powered crypto service which can sign as well as create new key pairs.
*/
@DoNotImplement
interface CryptoService : SignOnlyCryptoService {
/**
* Generate and store a new [KeyPair].
* Note that schemeNumberID is Corda specific. Cross-check with the network operator for supported schemeNumberID
* and their corresponding signature schemes. The main reason for using schemeNumberID and not algorithm OIDs is
* because some schemes might not be standardised and thus an official OID might for this scheme not exist yet.
*
* Returns the [PublicKey] of the generated [KeyPair].
*/
fun generateKeyPair(alias: String, scheme: SignatureScheme): PublicKey
}
open class CryptoServiceException(message: String?, cause: Throwable? = null) : Exception(message, cause)

View File

@ -13,7 +13,7 @@ import net.corda.nodeapi.internal.config.FileBasedCertificateStoreSupplier
import net.corda.nodeapi.internal.config.MutualSslConfiguration
import net.corda.nodeapi.internal.config.toProperties
import net.corda.nodeapi.internal.crypto.X509KeyStore
import net.corda.nodeapi.internal.cryptoservice.CryptoService
import net.corda.nodeapi.internal.cryptoservice.SignOnlyCryptoService
import net.corda.nodeapi.internal.cryptoservice.bouncycastle.BCCryptoService
import net.corda.nodeapi.internal.installDevNodeCaCertPath
import net.corda.nodeapi.internal.loadDevCaTrustStore
@ -73,10 +73,10 @@ object ConfigHelper {
* the CA certs in Node resources. Then provision KeyStores into certificates folder under node path.
*/
// TODO Move this to KeyStoreConfigHelpers.
fun NodeConfiguration.configureWithDevSSLCertificate(cryptoService: CryptoService? = null) = p2pSslOptions.configureDevKeyAndTrustStores(myLegalName, signingCertificateStore, certificatesDirectory, cryptoService)
fun NodeConfiguration.configureWithDevSSLCertificate(cryptoService: SignOnlyCryptoService? = null) = p2pSslOptions.configureDevKeyAndTrustStores(myLegalName, signingCertificateStore, certificatesDirectory, cryptoService)
// TODO Move this to KeyStoreConfigHelpers.
fun MutualSslConfiguration.configureDevKeyAndTrustStores(myLegalName: CordaX500Name, signingCertificateStore: FileBasedCertificateStoreSupplier, certificatesDirectory: Path, cryptoService: CryptoService? = null) {
fun MutualSslConfiguration.configureDevKeyAndTrustStores(myLegalName: CordaX500Name, signingCertificateStore: FileBasedCertificateStoreSupplier, certificatesDirectory: Path, cryptoService: SignOnlyCryptoService? = null) {
val specifiedTrustStore = trustStore.getOptional()
val specifiedKeyStore = keyStore.getOptional()
@ -116,4 +116,4 @@ fun MutualSslConfiguration.configureDevKeyAndTrustStores(myLegalName: CordaX500N
else -> throw IllegalArgumentException("CryptoService not supported.")
}
}
}
}

View File

@ -9,12 +9,11 @@ import net.corda.core.serialization.serialize
import net.corda.core.utilities.MAX_HASH_HEX_SIZE
import net.corda.node.services.identity.PersistentIdentityService
import net.corda.node.utilities.AppendOnlyPersistentMap
import net.corda.nodeapi.internal.cryptoservice.CryptoService
import net.corda.nodeapi.internal.cryptoservice.SignOnlyCryptoService
import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.nodeapi.internal.persistence.NODE_DATABASE_PREFIX
import org.apache.commons.lang3.ArrayUtils.EMPTY_BYTE_ARRAY
import org.bouncycastle.operator.ContentSigner
import org.hibernate.annotations.Type
import java.security.KeyPair
import java.security.PrivateKey
import java.security.PublicKey
@ -30,7 +29,7 @@ import javax.persistence.*
* This class needs database transactions to be in-flight during method calls and init.
*/
class BasicHSMKeyManagementService(cacheFactory: NamedCacheFactory, val identityService: PersistentIdentityService,
private val database: CordaPersistence, private val cryptoService: CryptoService) : SingletonSerializeAsToken(), KeyManagementServiceInternal {
private val database: CordaPersistence, private val cryptoService: SignOnlyCryptoService) : SingletonSerializeAsToken(), KeyManagementServiceInternal {
@Entity
@Table(name = "${NODE_DATABASE_PREFIX}our_key_pairs")
class PersistentKey(