gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[libeufin] branch master updated: Importing passphrase protection into t


From: gnunet
Subject: [libeufin] branch master updated: Importing passphrase protection into the Web server.
Date: Thu, 21 Nov 2019 04:50:31 +0100

This is an automated email from the git hooks/post-receive script.

marcello pushed a commit to branch master
in repository libeufin.

The following commit(s) were added to refs/heads/master by this push:
     new 0e3fc33  Importing passphrase protection into the Web server.
0e3fc33 is described below

commit 0e3fc336694f42c2844b940015ec8e43b42f851c
Author: Marcello Stanisci <address@hidden>
AuthorDate: Thu Nov 21 04:50:06 2019 +0100

    Importing passphrase protection into the Web server.
---
 nexus/src/main/kotlin/JSON.kt                      | 12 ++++-
 nexus/src/main/kotlin/Main.kt                      | 62 ++++++++++++++++++----
 .../kotlin/tech/libeufin/sandbox/CryptoUtil.kt     |  4 +-
 sandbox/src/test/kotlin/CryptoUtilTest.kt          |  6 +--
 4 files changed, 68 insertions(+), 16 deletions(-)

diff --git a/nexus/src/main/kotlin/JSON.kt b/nexus/src/main/kotlin/JSON.kt
index 5691f58..7dcb0a6 100644
--- a/nexus/src/main/kotlin/JSON.kt
+++ b/nexus/src/main/kotlin/JSON.kt
@@ -4,8 +4,18 @@ import com.google.gson.annotations.JsonAdapter
 import com.squareup.moshi.JsonClass
 
 
-data class EbicsKeysBackup(
 
+data class EbicsBackupRequest(
+    val passphrase: String
+)
+
+/**
+ * This object is used twice: as a response to the backup request,
+ * and as a request to the backup restore.  Note: in the second case
+ * the client must provide the passphrase.
+ */
+data class EbicsKeysBackup(
+    val passphrase: String? = null,
     val authBlob: ByteArray,
     val encBlob: ByteArray,
     val sigBlob: ByteArray
diff --git a/nexus/src/main/kotlin/Main.kt b/nexus/src/main/kotlin/Main.kt
index 9bda6d7..26efa7c 100644
--- a/nexus/src/main/kotlin/Main.kt
+++ b/nexus/src/main/kotlin/Main.kt
@@ -30,14 +30,13 @@ import io.ktor.features.ContentNegotiation
 import io.ktor.features.StatusPages
 import io.ktor.gson.gson
 import io.ktor.http.ContentType
+import io.ktor.http.HttpMethod
 import io.ktor.http.HttpStatusCode
 import io.ktor.request.receive
 import io.ktor.request.uri
 import io.ktor.response.respond
 import io.ktor.response.respondText
-import io.ktor.routing.get
-import io.ktor.routing.post
-import io.ktor.routing.routing
+import io.ktor.routing.*
 import io.ktor.server.engine.embeddedServer
 import io.ktor.server.netty.Netty
 import org.apache.commons.codec.digest.Crypt
@@ -63,6 +62,7 @@ import java.time.Instant.now
 import java.util.*
 import java.util.zip.DeflaterInputStream
 import java.util.zip.InflaterInputStream
+import javax.crypto.EncryptedPrivateKeyInfo
 import javax.xml.datatype.DatatypeFactory
 import javax.xml.datatype.XMLGregorianCalendar
 
@@ -241,6 +241,7 @@ data class UnreachableBankError(val statusCode: 
HttpStatusCode) : Exception("Cou
 data class UnparsableResponse(val statusCode: HttpStatusCode, val rawResponse: 
String) : Exception("bank responded: ${rawResponse}")
 data class EbicsError(val codeError: String) : Exception("Bank did not 
accepted EBICS request, error is: ${codeError}")
 data class BadSignature(val statusCode: HttpStatusCode) : Exception("Signature 
verification unsuccessful")
+data class BadBackup(val statusCode: HttpStatusCode) : Exception("Could not 
restore backed up keys")
 
 
 
@@ -282,6 +283,11 @@ fun main() {
                 call.respondText("Bad request\n", ContentType.Text.Plain, 
HttpStatusCode.BadRequest)
             }
 
+            exception<BadBackup> { cause ->
+                logger.error("Exception while handling '${call.request.uri}'", 
cause)
+                call.respondText("Bad backup, or passphrase incorrect\n", 
ContentType.Text.Plain, HttpStatusCode.BadRequest)
+            }
+
 
             exception<UnparsableResponse> { cause ->
                 logger.error("Exception while handling '${call.request.uri}'", 
cause)
@@ -743,11 +749,32 @@ fun main() {
                 val body = call.receive<EbicsKeysBackup>()
                 val id = expectId(call.parameters["id"])
 
+                val (authKey, encKey, sigKey) = try {
+
+                    val authKey = CryptoUtil.decryptKey(
+                        EncryptedPrivateKeyInfo(body.authBlob), 
body.passphrase!!
+                    )
+
+                    val encKey = CryptoUtil.decryptKey(
+                        EncryptedPrivateKeyInfo(body.encBlob), body.passphrase
+                    )
+
+                    val sigKey = CryptoUtil.decryptKey(
+                        EncryptedPrivateKeyInfo(body.sigBlob), body.passphrase
+                    )
+
+                    Triple(authKey, encKey, sigKey)
+
+                } catch (e: Exception) {
+                    throw BadBackup(HttpStatusCode.BadRequest)
+                }
+
                 transaction {
                     val subscriber = EbicsSubscriberEntity.findById(id) ?: 
throw SubscriberNotFoundError(HttpStatusCode.NotFound)
-                    subscriber.encryptionPrivateKey = SerialBlob(body.encBlob)
-                    subscriber.authenticationPrivateKey = 
SerialBlob(body.authBlob)
-                    subscriber.signaturePrivateKey = SerialBlob(body.sigBlob)
+
+                    subscriber.encryptionPrivateKey = 
SerialBlob(authKey.encoded)
+                    subscriber.authenticationPrivateKey = 
SerialBlob(encKey.encoded)
+                    subscriber.signaturePrivateKey = SerialBlob(sigKey.encoded)
                 }
 
                 call.respondText(
@@ -758,15 +785,30 @@ fun main() {
 
             }
 
-            get("/ebics/subscribers/{id}/backup") {
+            put("/ebics/subscribers/{id}/backup") {
 
                 val id = expectId(call.parameters["id"])
+                val body = call.receive<EbicsBackupRequest>()
+
                 val content = transaction {
                     val subscriber = EbicsSubscriberEntity.findById(id) ?: 
throw SubscriberNotFoundError(HttpStatusCode.NotFound)
+
+
                     EbicsKeysBackup(
-                        authBlob = 
subscriber.authenticationPrivateKey.toByteArray(),
-                        encBlob = 
subscriber.encryptionPrivateKey.toByteArray(),
-                        sigBlob = subscriber.signaturePrivateKey.toByteArray()
+
+                        authBlob = CryptoUtil.encryptKey(
+                            subscriber.authenticationPrivateKey.toByteArray(),
+                            body.passphrase
+                        ),
+
+                        encBlob = CryptoUtil.encryptKey(
+                            subscriber.encryptionPrivateKey.toByteArray(),
+                            body.passphrase),
+
+                        sigBlob = CryptoUtil.encryptKey(
+                            subscriber.signaturePrivateKey.toByteArray(),
+                            body.passphrase
+                        )
                     )
                 }
 
diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/CryptoUtil.kt 
b/sandbox/src/main/kotlin/tech/libeufin/sandbox/CryptoUtil.kt
index fdd0233..4bf0c7a 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/CryptoUtil.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/CryptoUtil.kt
@@ -213,7 +213,7 @@ object CryptoUtil {
     }
 
 
-    fun decryptSecret(data: EncryptedPrivateKeyInfo, passphrase: String): 
RSAPrivateCrtKey {
+    fun decryptKey(data: EncryptedPrivateKeyInfo, passphrase: String): 
RSAPrivateCrtKey {
 
         /* make key out of passphrase */
         val pbeKeySpec = PBEKeySpec(passphrase.toCharArray())
@@ -236,7 +236,7 @@ object CryptoUtil {
         return priv
     }
 
-    fun encryptSecret(data: ByteArray, passphrase: String): ByteArray {
+    fun encryptKey(data: ByteArray, passphrase: String): ByteArray {
 
         /* Cipher parameters: salt and hash count */
         val hashIterations = 30
diff --git a/sandbox/src/test/kotlin/CryptoUtilTest.kt 
b/sandbox/src/test/kotlin/CryptoUtilTest.kt
index bee8d0c..229e067 100644
--- a/sandbox/src/test/kotlin/CryptoUtilTest.kt
+++ b/sandbox/src/test/kotlin/CryptoUtilTest.kt
@@ -85,12 +85,12 @@ class CryptoUtilTest {
         val secret = CryptoUtil.encryptEbicsE002(data, keyPair.public)
 
         /* encrypt and decrypt private key */
-        val encPriv = CryptoUtil.encryptSecret(keyPair.private.encoded, 
"secret")
-        val plainPriv = 
CryptoUtil.decryptSecret(EncryptedPrivateKeyInfo(encPriv),"secret")
+        val encPriv = CryptoUtil.encryptKey(keyPair.private.encoded, "secret")
+        val plainPriv = 
CryptoUtil.decryptKey(EncryptedPrivateKeyInfo(encPriv),"secret")
 
         /* decrypt with decrypted private key */
         val revealed = CryptoUtil.decryptEbicsE002(secret, plainPriv)
-        
+
         assertEquals(
             String(revealed, charset = Charsets.UTF_8),
             String(data, charset = Charsets.UTF_8)

-- 
To stop receiving notification emails like this one, please contact
address@hidden.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]