Some checks failed
Code Formatting / Code Formatting (push) Has been cancelled
Tests / Rust + Java + Node (push) Has been cancelled
Tests / iOS (push) Has been cancelled
Release artifacts / Build Linux + Android (push) Has been cancelled
Release artifacts / Build Windows (push) Has been cancelled
Release artifacts / Build macOS (Node) (push) Has been cancelled
189 lines
9.5 KiB
Diff
189 lines
9.5 KiB
Diff
diff --git b/ffi/java/src/main/java/org/signal/zkgroup/auth/ServerZkAuthOperations.java a/ffi/java/src/main/java/org/signal/zkgroup/auth/ServerZkAuthOperations.java
|
|
index a2567a55ef32..57d99c13ed71 100644
|
|
--- b/ffi/java/src/main/java/org/signal/zkgroup/auth/ServerZkAuthOperations.java
|
|
+++ a/ffi/java/src/main/java/org/signal/zkgroup/auth/ServerZkAuthOperations.java
|
|
@@ -11,9 +11,11 @@ package org.signal.zkgroup.auth;
|
|
|
|
import java.security.SecureRandom;
|
|
import java.util.UUID;
|
|
+import java.util.concurrent.TimeUnit;
|
|
import org.signal.zkgroup.InvalidInputException;
|
|
import org.signal.zkgroup.ServerSecretParams;
|
|
import org.signal.zkgroup.VerificationFailedException;
|
|
+import org.signal.zkgroup.InvalidRedemptionTimeException;
|
|
import org.signal.zkgroup.ZkGroupError;
|
|
import org.signal.zkgroup.groups.GroupPublicParams;
|
|
import org.signal.zkgroup.internal.Native;
|
|
@@ -51,7 +53,18 @@ public class ServerZkAuthOperations {
|
|
|
|
}
|
|
|
|
- public void verifyAuthCredentialPresentation(GroupPublicParams groupPublicParams, AuthCredentialPresentation authCredentialPresentation) throws VerificationFailedException {
|
|
+ public void verifyAuthCredentialPresentation(GroupPublicParams groupPublicParams, AuthCredentialPresentation authCredentialPresentation) throws VerificationFailedException, InvalidRedemptionTimeException {
|
|
+ verifyAuthCredentialPresentation(groupPublicParams, authCredentialPresentation, System.currentTimeMillis());
|
|
+ }
|
|
+
|
|
+ public void verifyAuthCredentialPresentation(GroupPublicParams groupPublicParams, AuthCredentialPresentation authCredentialPresentation, long currentTimeMillis) throws VerificationFailedException, InvalidRedemptionTimeException {
|
|
+ long acceptableStartTime = TimeUnit.MILLISECONDS.convert(authCredentialPresentation.getRedemptionTime()-1, TimeUnit.DAYS);
|
|
+ long acceptableEndTime = TimeUnit.MILLISECONDS.convert(authCredentialPresentation.getRedemptionTime()+2, TimeUnit.DAYS);
|
|
+
|
|
+ if (currentTimeMillis < acceptableStartTime || currentTimeMillis > acceptableEndTime) {
|
|
+ throw new InvalidRedemptionTimeException();
|
|
+ }
|
|
+
|
|
int ffi_return = Native.serverSecretParamsVerifyAuthCredentialPresentationJNI(serverSecretParams.getInternalContentsForJNI(), groupPublicParams.getInternalContentsForJNI(), authCredentialPresentation.getInternalContentsForJNI());
|
|
if (ffi_return == Native.FFI_RETURN_INPUT_ERROR) {
|
|
throw new VerificationFailedException();
|
|
diff --git b/ffi/java/src/main/java/org/signal/zkgroup/groups/ClientZkGroupCipher.java a/ffi/java/src/main/java/org/signal/zkgroup/groups/ClientZkGroupCipher.java
|
|
index 464cf6d19ecc..5739505935b0 100644
|
|
--- b/ffi/java/src/main/java/org/signal/zkgroup/groups/ClientZkGroupCipher.java
|
|
+++ a/ffi/java/src/main/java/org/signal/zkgroup/groups/ClientZkGroupCipher.java
|
|
@@ -9,6 +9,7 @@
|
|
|
|
package org.signal.zkgroup.groups;
|
|
|
|
+import java.nio.ByteBuffer;
|
|
import java.security.SecureRandom;
|
|
import java.util.UUID;
|
|
import org.signal.zkgroup.InvalidInputException;
|
|
@@ -100,12 +101,16 @@ public class ClientZkGroupCipher {
|
|
}
|
|
|
|
public byte[] encryptBlob(SecureRandom secureRandom, byte[] plaintext) throws VerificationFailedException {
|
|
- byte[] newContents = new byte[plaintext.length + 29];
|
|
+
|
|
+ byte[] paddedPlaintext = new byte[plaintext.length + 4];
|
|
+ System.arraycopy(plaintext, 0, paddedPlaintext, 4, plaintext.length);
|
|
+
|
|
+ byte[] newContents = new byte[paddedPlaintext.length + 29];
|
|
byte[] random = new byte[Native.RANDOM_LENGTH];
|
|
|
|
secureRandom.nextBytes(random);
|
|
|
|
- int ffi_return = Native.groupSecretParamsEncryptBlobDeterministicJNI(groupSecretParams.getInternalContentsForJNI(), random, plaintext, newContents);
|
|
+ int ffi_return = Native.groupSecretParamsEncryptBlobDeterministicJNI(groupSecretParams.getInternalContentsForJNI(), random, paddedPlaintext, newContents);
|
|
if (ffi_return == Native.FFI_RETURN_INPUT_ERROR) {
|
|
throw new VerificationFailedException();
|
|
}
|
|
@@ -129,7 +134,21 @@ public class ClientZkGroupCipher {
|
|
throw new ZkGroupError("FFI_RETURN!=OK");
|
|
}
|
|
|
|
- return newContents;
|
|
+ if (newContents.length < 4) {
|
|
+ throw new VerificationFailedException();
|
|
+ }
|
|
+
|
|
+ byte[] padLenBytes = new byte[4];
|
|
+ System.arraycopy(newContents, 0, padLenBytes, 0, 4);
|
|
+ int padLen = ByteBuffer.wrap(newContents).getInt();
|
|
+ if (newContents.length < (4 + padLen)) {
|
|
+ throw new VerificationFailedException();
|
|
+ }
|
|
+
|
|
+ byte[] depaddedContents = new byte[newContents.length - (4 + padLen)];
|
|
+ System.arraycopy(newContents, 4, depaddedContents, 0, newContents.length - (4 + padLen));
|
|
+
|
|
+ return depaddedContents;
|
|
}
|
|
|
|
}
|
|
diff --git b/ffi/java/src/main/java/org/signal/zkgroup/profiles/ClientZkProfileOperations.java a/ffi/java/src/main/java/org/signal/zkgroup/profiles/ClientZkProfileOperations.java
|
|
index cbc73ac60bee..57a252f5886d 100644
|
|
--- b/ffi/java/src/main/java/org/signal/zkgroup/profiles/ClientZkProfileOperations.java
|
|
+++ a/ffi/java/src/main/java/org/signal/zkgroup/profiles/ClientZkProfileOperations.java
|
|
@@ -52,6 +52,10 @@ public class ClientZkProfileOperations {
|
|
}
|
|
|
|
public ProfileKeyCredential receiveProfileKeyCredential(ProfileKeyCredentialRequestContext profileKeyCredentialRequestContext, ProfileKeyCredentialResponse profileKeyCredentialResponse) throws VerificationFailedException {
|
|
+ if (profileKeyCredentialResponse == null) {
|
|
+ throw new VerificationFailedException();
|
|
+ }
|
|
+
|
|
byte[] newContents = new byte[ProfileKeyCredential.SIZE];
|
|
|
|
int ffi_return = Native.serverPublicParamsReceiveProfileKeyCredentialJNI(serverPublicParams.getInternalContentsForJNI(), profileKeyCredentialRequestContext.getInternalContentsForJNI(), profileKeyCredentialResponse.getInternalContentsForJNI(), newContents);
|
|
diff --git b/ffi/java/src/main/java/org/signal/zkgroup/profiles/ProfileKey.java a/ffi/java/src/main/java/org/signal/zkgroup/profiles/ProfileKey.java
|
|
index 2251da362b0e..9170b5fd9a5c 100644
|
|
--- b/ffi/java/src/main/java/org/signal/zkgroup/profiles/ProfileKey.java
|
|
+++ a/ffi/java/src/main/java/org/signal/zkgroup/profiles/ProfileKey.java
|
|
@@ -25,14 +25,10 @@ public final class ProfileKey extends ByteArray {
|
|
super(contents, SIZE);
|
|
}
|
|
|
|
- public ProfileKeyCommitment getCommitment(UUID uuid) throws VerificationFailedException {
|
|
+ public ProfileKeyCommitment getCommitment(UUID uuid) {
|
|
byte[] newContents = new byte[ProfileKeyCommitment.SIZE];
|
|
|
|
int ffi_return = Native.profileKeyGetCommitmentJNI(contents, UUIDUtil.serialize(uuid), newContents);
|
|
- if (ffi_return == Native.FFI_RETURN_INPUT_ERROR) {
|
|
- throw new VerificationFailedException();
|
|
- }
|
|
-
|
|
if (ffi_return != Native.FFI_RETURN_OK) {
|
|
throw new ZkGroupError("FFI_RETURN!=OK");
|
|
}
|
|
@@ -45,14 +41,10 @@ public final class ProfileKey extends ByteArray {
|
|
|
|
}
|
|
|
|
- public ProfileKeyVersion getProfileKeyVersion(UUID uuid) throws VerificationFailedException {
|
|
+ public ProfileKeyVersion getProfileKeyVersion(UUID uuid) {
|
|
byte[] newContents = new byte[ProfileKeyVersion.SIZE];
|
|
|
|
int ffi_return = Native.profileKeyGetProfileKeyVersionJNI(contents, UUIDUtil.serialize(uuid), newContents);
|
|
- if (ffi_return == Native.FFI_RETURN_INPUT_ERROR) {
|
|
- throw new VerificationFailedException();
|
|
- }
|
|
-
|
|
if (ffi_return != Native.FFI_RETURN_OK) {
|
|
throw new ZkGroupError("FFI_RETURN!=OK");
|
|
}
|
|
diff --git b/ffi/swift/Sources/ZKGroup/ClientZkGroupCipher.swift a/ffi/swift/Sources/ZKGroup/ClientZkGroupCipher.swift
|
|
index 4d36edb46acf..fa7f1b4aba5c 100644
|
|
--- b/ffi/swift/Sources/ZKGroup/ClientZkGroupCipher.swift
|
|
+++ a/ffi/swift/Sources/ZKGroup/ClientZkGroupCipher.swift
|
|
@@ -91,7 +91,7 @@ public class ClientZkGroupCipher {
|
|
|
|
}
|
|
|
|
- public func encryptBlob(plaintext: [UInt8]) throws -> BlobCiphertext {
|
|
+ public func encryptBlob(plaintext: [UInt8]) throws -> [UInt8] {
|
|
var randomness: [UInt8] = Array(repeating: 0, count: Int(32))
|
|
let result = SecRandomCopyBytes(kSecRandomDefault, randomness.count, &randomness)
|
|
guard result == errSecSuccess else {
|
|
@@ -102,9 +102,11 @@ public class ClientZkGroupCipher {
|
|
}
|
|
|
|
public func encryptBlob(randomness: [UInt8], plaintext: [UInt8]) throws -> [UInt8] {
|
|
- var newContents: [UInt8] = Array(repeating: 0, count: Int(plaintext.count + 29))
|
|
+ let paddedPlaintext = Array(repeating:0, count: 4) + plaintext
|
|
|
|
- let ffi_return = FFI_GroupSecretParams_encryptBlobDeterministic(groupSecretParams.getInternalContentsForFFI(), UInt32(groupSecretParams.getInternalContentsForFFI().count), randomness, UInt32(randomness.count), plaintext, UInt32(plaintext.count), &newContents, UInt32(newContents.count))
|
|
+ var newContents: [UInt8] = Array(repeating: 0, count: Int(paddedPlaintext.count + 29))
|
|
+
|
|
+ let ffi_return = FFI_GroupSecretParams_encryptBlobDeterministic(groupSecretParams.getInternalContentsForFFI(), UInt32(groupSecretParams.getInternalContentsForFFI().count), randomness, UInt32(randomness.count), paddedPlaintext, UInt32(paddedPlaintext.count), &newContents, UInt32(newContents.count))
|
|
if (ffi_return == Native.FFI_RETURN_INPUT_ERROR) {
|
|
throw ZkGroupException.VerificationFailed
|
|
}
|
|
@@ -128,7 +131,18 @@ public class ClientZkGroupCipher {
|
|
throw ZkGroupException.ZkGroupError
|
|
}
|
|
|
|
- return newContents
|
|
+ if newContents.count < 4 {
|
|
+ throw ZkGroupException.VerificationFailed
|
|
+ }
|
|
+
|
|
+ var paddingLen = newContents.withUnsafeBytes({ $0.load(fromByteOffset:0, as: UInt32.self) })
|
|
+ paddingLen = UInt32(bigEndian: paddingLen)
|
|
+
|
|
+ if (newContents.count < (4 + paddingLen)) {
|
|
+ throw ZkGroupException.VerificationFailed
|
|
+ }
|
|
+
|
|
+ return Array(newContents[4 ..< newContents.endIndex - Int(paddingLen)])
|
|
}
|
|
|
|
}
|