You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@james.apache.org by rc...@apache.org on 2021/11/01 04:20:51 UTC

[james-project] 06/08: JAMES-3539 Allow web push encryption

This is an automated email from the ASF dual-hosted git repository.

rcordier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit 0ba0a6475c7ec7b65a4e7e2b0b75e4a769347d4f
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Thu Oct 28 14:28:17 2021 +0700

    JAMES-3539 Allow web push encryption
---
 pom.xml                                            | 11 +++++++++
 server/blob/blob-aes/pom.xml                       |  1 -
 server/data/data-jmap/pom.xml                      |  8 +++++++
 .../james/jmap/api/model/PushSubscription.scala    | 28 +++++++++++++++++++---
 4 files changed, 44 insertions(+), 4 deletions(-)

diff --git a/pom.xml b/pom.xml
index 04ec3a3..fe0c09b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -641,6 +641,7 @@
         <jasypt.version>1.9.3</jasypt.version>
         <guice.version>5.0.1</guice.version>
         <logback.version>1.2.5</logback.version>
+        <tink.version>1.6.1</tink.version>
 
         <bouncycastle.version>1.69</bouncycastle.version>
 
@@ -2077,6 +2078,16 @@
                 <version>1.2.0</version>
             </dependency>
             <dependency>
+                <groupId>com.google.crypto.tink</groupId>
+                <artifactId>apps-webpush</artifactId>
+                <version>${tink.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>com.google.crypto.tink</groupId>
+                <artifactId>tink</artifactId>
+                <version>${tink.version}</version>
+            </dependency>
+            <dependency>
                 <groupId>com.google.guava</groupId>
                 <artifactId>guava</artifactId>
                 <version>${guava.version}</version>
diff --git a/server/blob/blob-aes/pom.xml b/server/blob/blob-aes/pom.xml
index b84693a..b612894 100644
--- a/server/blob/blob-aes/pom.xml
+++ b/server/blob/blob-aes/pom.xml
@@ -59,7 +59,6 @@
         <dependency>
             <groupId>com.google.crypto.tink</groupId>
             <artifactId>tink</artifactId>
-            <version>1.6.1</version>
         </dependency>
         <dependency>
             <groupId>com.google.guava</groupId>
diff --git a/server/data/data-jmap/pom.xml b/server/data/data-jmap/pom.xml
index daec8fc..4048502 100644
--- a/server/data/data-jmap/pom.xml
+++ b/server/data/data-jmap/pom.xml
@@ -100,6 +100,14 @@
             <scope>test</scope>
         </dependency>
         <dependency>
+            <groupId>com.google.crypto.tink</groupId>
+            <artifactId>apps-webpush</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.crypto.tink</groupId>
+            <artifactId>tink</artifactId>
+        </dependency>
+        <dependency>
             <groupId>com.google.guava</groupId>
             <artifactId>guava</artifactId>
         </dependency>
diff --git a/server/data/data-jmap/src/main/scala/org/apache/james/jmap/api/model/PushSubscription.scala b/server/data/data-jmap/src/main/scala/org/apache/james/jmap/api/model/PushSubscription.scala
index 31080f7..a88a5f8 100644
--- a/server/data/data-jmap/src/main/scala/org/apache/james/jmap/api/model/PushSubscription.scala
+++ b/server/data/data-jmap/src/main/scala/org/apache/james/jmap/api/model/PushSubscription.scala
@@ -20,8 +20,14 @@
 package org.apache.james.jmap.api.model
 
 import java.net.URL
-import java.time.{Clock, ZonedDateTime}
-import java.util.UUID
+import java.security.interfaces.ECPublicKey
+import java.time.ZonedDateTime
+import java.util.{Base64, UUID}
+
+import com.google.crypto.tink.HybridEncrypt
+import com.google.crypto.tink.apps.webpush.WebPushHybridEncrypt
+import com.google.crypto.tink.subtle.EllipticCurves
+
 import scala.util.Try
 
 object PushSubscriptionId {
@@ -49,7 +55,23 @@ case class PushSubscriptionExpiredTime(value: ZonedDateTime) {
   def isBefore(date: ZonedDateTime): Boolean = value.isBefore(date)
 }
 
-case class PushSubscriptionKeys(p256dh: String, auth: String)
+object PushSubscriptionKeys {
+  def validate(keys: PushSubscriptionKeys): Try[PushSubscriptionKeys] = Try(keys.asHybridEncrypt()).map(_ => keys)
+}
+
+case class PushSubscriptionKeys(p256dh: String, auth: String) {
+  // Follows https://datatracker.ietf.org/doc/html/rfc8291
+  // Message Encryption for Web Push
+  def encrypt(payload: Array[Byte]): Array[Byte] = asHybridEncrypt()
+    .encrypt(payload, null)
+
+  private def asHybridEncrypt(): HybridEncrypt =  new WebPushHybridEncrypt.Builder()
+    .withAuthSecret(Base64.getDecoder().decode(auth))
+    .withRecipientPublicKey(asECPublicKey())
+    .build()
+
+  private def asECPublicKey(): ECPublicKey = EllipticCurves.getEcPublicKey(Base64.getDecoder.decode(p256dh))
+}
 
 case class PushSubscriptionCreationRequest(deviceClientId: DeviceClientId,
                                            url: PushSubscriptionServerURL,

---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org