commit bbcbfba4d21f97f3ef5b450f45d01bec6d06ebd1
parent 56c184c2481fddd98144424b7bd43f2ecd41013e
Author: Antoine A <>
Date: Tue, 12 Nov 2024 16:25:37 +0100
nexus: check bank keys during setup
Diffstat:
1 file changed, 66 insertions(+), 48 deletions(-)
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/cli/EbicsSetup.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/cli/EbicsSetup.kt
@@ -66,61 +66,53 @@ private fun askUserToAcceptKeys(bankKeys: BankPublicKeysFile): Boolean {
return userResponse == "yes, accept"
}
-/**
- * Perform an EBICS key management [order] using [client] and update on disk
- * keys
- */
-suspend fun doKeysRequestAndUpdateState(
+/** Perform an EBICS public key management [order] using [client] and update on disk state */
+private suspend fun submitClientKeys(
cfg: NexusEbicsConfig,
privs: ClientPrivateKeysFile,
client: HttpClient,
ebicsLogger: EbicsLogger,
order: EbicsKeyMng.Order
) {
+ if (order == HPB) throw IllegalArgumentException("Only INI & HIA are supported for client keys")
val resp = keyManagement(cfg, privs, client, ebicsLogger, order)
-
- when (order) {
- INI, HIA -> {
- if (resp.technicalCode == EbicsReturnCode.EBICS_INVALID_USER_OR_USER_STATE) {
- throw Exception("$order status code ${resp.technicalCode}: either your IDs are incorrect, or you already have keys registered with this bank")
- }
- }
- HPB -> {
- if (resp.technicalCode == EbicsReturnCode.EBICS_AUTHENTICATION_FAILED) {
- throw Exception("$order status code ${resp.technicalCode}: could not download bank keys, send client keys (and/or related PDF document with --generate-registration-pdf) to the bank")
- }
- }
+ if (resp.technicalCode == EbicsReturnCode.EBICS_INVALID_USER_OR_USER_STATE) {
+ throw Exception("$order status code ${resp.technicalCode}: either your IDs are incorrect, or you already have keys registered with this bank")
}
-
val orderData = resp.okOrFail(order.name)
when (order) {
INI -> privs.submitted_ini = true
HIA -> privs.submitted_hia = true
- HPB -> {
- val orderData = requireNotNull(orderData) {
- "HPB: missing order data"
- }
- val (authPub, encPub) = EbicsKeyMng.parseHpbOrder(orderData)
- val bankKeys = BankPublicKeysFile(
- bank_authentication_public_key = authPub,
- bank_encryption_public_key = encPub,
- accepted = false
- )
- try {
- persistBankKeys(bankKeys, cfg.bankPublicKeysPath)
- } catch (e: Exception) {
- throw Exception("Could not update the $order state on disk", e)
- }
- }
+ HPB -> {}
}
- if (order != HPB) {
- try {
- persistClientKeys(privs, cfg.clientPrivateKeysPath)
- } catch (e: Exception) {
- throw Exception("Could not update the $order state on disk", e)
- }
+ try {
+ persistClientKeys(privs, cfg.clientPrivateKeysPath)
+ } catch (e: Exception) {
+ throw Exception("Could not update the $order state on disk", e)
+ }
+}
+
+/** Perform an EBICS private key management HPB using [client] */
+private suspend fun fetchPrivateKeys(
+ cfg: NexusEbicsConfig,
+ privs: ClientPrivateKeysFile,
+ client: HttpClient,
+ ebicsLogger: EbicsLogger
+): BankPublicKeysFile {
+ val order = HPB
+ val resp = keyManagement(cfg, privs, client, ebicsLogger, order)
+ if (resp.technicalCode == EbicsReturnCode.EBICS_AUTHENTICATION_FAILED) {
+ throw Exception("$order status code ${resp.technicalCode}: could not download bank keys, send client keys (and/or related PDF document with --generate-registration-pdf) to the bank")
}
-
+ val orderData = requireNotNull(resp.okOrFail(order.name)) {
+ "$order: missing order data"
+ }
+ val (authPub, encPub) = EbicsKeyMng.parseHpbOrder(orderData)
+ return BankPublicKeysFile(
+ bank_authentication_public_key = authPub,
+ bank_encryption_public_key = encPub,
+ accepted = false
+ )
}
/**
@@ -180,18 +172,44 @@ class EbicsSetup: CliktCommand() {
// Privs exist. Upload their pubs
val keysNotSub = !clientKeys.submitted_ini
- if ((!clientKeys.submitted_ini) || forceKeysResubmission)
- doKeysRequestAndUpdateState(cfg.ebics, clientKeys, client, ebicsLogger, INI)
+ if (!clientKeys.submitted_ini || forceKeysResubmission)
+ submitClientKeys(cfg.ebics, clientKeys, client, ebicsLogger, INI)
// Eject PDF if the keys were submitted for the first time, or the user asked.
if (keysNotSub || generateRegistrationPdf) makePdf(clientKeys, cfg.ebics)
- if ((!clientKeys.submitted_hia) || forceKeysResubmission)
- doKeysRequestAndUpdateState(cfg.ebics, clientKeys, client, ebicsLogger, HIA)
+ if (!clientKeys.submitted_hia || forceKeysResubmission)
+ submitClientKeys(cfg.ebics, clientKeys, client, ebicsLogger, HIA)
- // Checking if the bank keys exist on disk
+ val fetchedBankKeys = fetchPrivateKeys(cfg.ebics, clientKeys, client, ebicsLogger)
if (bankKeys == null) {
- doKeysRequestAndUpdateState(cfg.ebics, clientKeys, client, ebicsLogger, HPB)
+ // Accept bank keys
logger.info("Bank keys stored at ${cfg.ebics.bankPublicKeysPath}")
- bankKeys = loadBankKeys(cfg.ebics.bankPublicKeysPath)!!
+ try {
+ persistBankKeys(fetchedBankKeys, cfg.ebics.bankPublicKeysPath)
+ } catch (e: Exception) {
+ throw Exception("Could not store bank keys on disk", e)
+ }
+ bankKeys = fetchedBankKeys
+ } else {
+ // Check current bank keys
+ if (bankKeys.bank_encryption_public_key != fetchedBankKeys.bank_encryption_public_key) {
+ throw Exception(buildString {
+ append("On disk bank encryption key stored at ")
+ append(cfg.ebics.bankPublicKeysPath)
+ append(" doesn't match server key\nDisk: ")
+ append(CryptoUtil.getEbicsPublicKeyHash(bankKeys.bank_encryption_public_key).encodeUpHex().fmtChunkByTwo())
+ append("\nServer: ")
+ append(CryptoUtil.getEbicsPublicKeyHash(fetchedBankKeys.bank_encryption_public_key).encodeUpHex().fmtChunkByTwo())
+ })
+ } else if (bankKeys.bank_authentication_public_key != fetchedBankKeys.bank_authentication_public_key) {
+ throw Exception(buildString {
+ append("On disk bank authentication key stored at ")
+ append(cfg.ebics.bankPublicKeysPath)
+ append(" doesn't match server key\nDisk: ")
+ append(CryptoUtil.getEbicsPublicKeyHash(bankKeys.bank_authentication_public_key).encodeUpHex().fmtChunkByTwo())
+ append("\nServer: ")
+ append(CryptoUtil.getEbicsPublicKeyHash(fetchedBankKeys.bank_authentication_public_key).encodeUpHex().fmtChunkByTwo())
+ })
+ }
}
if (!bankKeys.accepted) {