Skip to content

Commit

Permalink
Merge pull request #327 from Concordium/acceptable-request
Browse files Browse the repository at this point in the history
Acceptable request
  • Loading branch information
shjortConcordium authored Mar 18, 2024
2 parents 89ff4a1 + 5d7a91d commit 17eab40
Show file tree
Hide file tree
Showing 9 changed files with 654 additions and 36 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
- Added method `findAtLowestHeight` for finding the earliest block satisfying some condition.
- Added method `findAccountCreation` for finding the block in which an account was created.
- Fixed an issue where `ConcordiumHdWallet.fromSeedPhrase` always produced an invalid seed as hex.
- Added `AcceptableRequest` class with `acceptableRequest` and `acceptableAtomicStatement` to check if a request satisfies wallet rules.

## 7.0.0
- Make the `energy` parameter for invoking an instance `Optional`.
Expand Down
2 changes: 1 addition & 1 deletion concordium-base
Submodule concordium-base updated 54 files
+1 −1 .github/workflows/build-test-contracts-common.yaml
+1 −1 .github/workflows/build-test-smart-contracts.yaml
+3 −3 .github/workflows/build-test-sources.yaml
+10 −0 haskell-src/Concordium/Cost.hs
+0 −63 haskell-src/Concordium/Types/Accounts.hs
+0 −42 haskell-src/Concordium/Types/Migration.hs
+14 −0 haskell-src/Concordium/Types/ProtocolVersion.hs
+5 −0 haskell-src/Concordium/Wasm.hs
+73 −16 identity-provider-service/Cargo.lock
+2 −2 identity-provider-service/Cargo.toml
+71 −14 idiss/Cargo.lock
+1 −1 idiss/Cargo.toml
+72 −27 mobile_wallet/Cargo.lock
+1 −1 mobile_wallet/Cargo.toml
+63 −6 rust-bins/Cargo.lock
+222 −69 rust-src/Cargo.lock
+3 −0 rust-src/concordium_base/CHANGELOG.md
+3 −3 rust-src/concordium_base/Cargo.toml
+1 −4 rust-src/concordium_base/src/aggregate_sig/ffi.rs
+3 −3 rust-src/concordium_base/src/aggregate_sig/mod.rs
+18 −32 rust-src/concordium_base/src/cis2_types.rs
+13 −13 rust-src/concordium_base/src/cis4_types.rs
+1 −2 rust-src/concordium_base/src/common/impls.rs
+3 −0 rust-src/concordium_base/src/ffi_helpers/ffi_macros.rs
+1 −2 rust-src/concordium_base/src/id/ffi.rs
+13 −13 rust-src/concordium_base/src/id/id_proof_types.rs
+2 −2 rust-src/concordium_base/src/transactions.rs
+1 −6 rust-src/concordium_base/src/web3id/mod.rs
+1 −0 rust-src/wallet_library/CHANGELOG.md
+3 −1 rust-src/wallet_library/Cargo.toml
+85 −0 rust-src/wallet_library/src/default_wallet_config.rs
+2 −0 rust-src/wallet_library/src/lib.rs
+11 −0 rust-src/wallet_library/src/proofs.rs
+403 −0 rust-src/wallet_library/src/statement.rs
+5 −0 smart-contracts/contracts-common/concordium-contracts-common-derive/CHANGELOG.md
+2 −2 smart-contracts/contracts-common/concordium-contracts-common-derive/Cargo.toml
+19 −5 smart-contracts/contracts-common/concordium-contracts-common-derive/src/attribute.rs
+1 −1 smart-contracts/contracts-common/concordium-contracts-common-derive/src/derive.rs
+4 −0 smart-contracts/contracts-common/concordium-contracts-common/CHANGELOG.md
+3 −3 smart-contracts/contracts-common/concordium-contracts-common/Cargo.toml
+2 −2 smart-contracts/contracts-common/concordium-contracts-common/src/hashes.rs
+3 −12 smart-contracts/contracts-common/concordium-contracts-common/src/impls.rs
+1 −1 smart-contracts/contracts-common/concordium-contracts-common/src/schema.rs
+162 −4 smart-contracts/contracts-common/concordium-contracts-common/src/types.rs
+ smart-contracts/testdata/contracts/v1/queries-contract-inspection.wasm
+157 −0 smart-contracts/testdata/contracts/v1/queries-contract-inspection.wat
+ smart-contracts/testdata/contracts/v1/upgrading-inspect-module0.wasm
+199 −0 smart-contracts/testdata/contracts/v1/upgrading-inspect-module0.wat
+ smart-contracts/testdata/contracts/v1/upgrading-inspect-module1.wasm
+201 −0 smart-contracts/testdata/contracts/v1/upgrading-inspect-module1.wat
+6 −0 smart-contracts/wasm-chain-integration/CHANGELOG.md
+14 −71 smart-contracts/wasm-chain-integration/Cargo.lock
+12 −2 smart-contracts/wasm-chain-integration/src/v1/ffi.rs
+123 −36 smart-contracts/wasm-chain-integration/src/v1/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import com.concordium.sdk.crypto.wallet.UnsignedCredentialInput;
import com.concordium.sdk.crypto.wallet.credential.CredentialDeploymentDetails;
import com.concordium.sdk.crypto.wallet.credential.CredentialDeploymentSerializationContext;
import com.concordium.sdk.crypto.wallet.web3Id.AcceptableRequest;
import com.concordium.sdk.crypto.wallet.web3Id.AttributeCheck;
import com.concordium.sdk.exceptions.JNIError;
import com.concordium.sdk.transactions.InitName;
import com.concordium.sdk.transactions.ReceiveName;
Expand Down Expand Up @@ -316,4 +318,31 @@ public static String getVerifiableCredentialBackupEncryptionKey(String seedAsHex
* {@link Web3IdProof} as JSON.
*/
public static native String createWeb3IdProof(String input);

/**
* Check that a request is acceptable
*
* @param input {@link Request} serialized as JSON.
* @return JSON representing {@link VoidResult}. If successful the field
* 'result' is empty,
* but if not acceptable the reason will be contained in the error.
*/
public static native String isAcceptableRequest(String input);

/**
* Check that an atomic is acceptable, with the given restrictions
*
* @param input {@link Request} serialized as JSON.
* @param rangeTags the list of tags, which may be used for range statements,
* serialized as JSON.
* @param setTags the list of tags, which may be used for membership
* statements, serialized as JSON.
* @param check provides the function to check whether the statement value
* is acceptable.
* @return JSON representing {@link VoidResult}. If successful the field
* 'result' is empty,
* but if not acceptable the reason will be contained in the error.
*/
public static native String isAcceptableAtomicStatement(String input, String rangeTags, String setTags,
AcceptableRequest.RawAttributeCheck check);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.concordium.sdk.crypto.wallet;

import com.concordium.sdk.exceptions.JNIError;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

public class ErrorResult extends StringResult {

@JsonCreator
ErrorResult(
@JsonProperty("Ok") String ok,
@JsonProperty("Err") JNIError err
) {
super(ok, err);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package com.concordium.sdk.crypto.wallet.web3Id;

import java.util.List;
import com.concordium.sdk.crypto.CryptoJniNative;
import com.concordium.sdk.crypto.NativeResolver;
import com.concordium.sdk.crypto.wallet.ErrorResult;
import com.concordium.sdk.crypto.wallet.StringResult;
import com.concordium.sdk.crypto.wallet.web3Id.Statement.AtomicStatement;
import com.concordium.sdk.exceptions.CryptoJniException;
import com.concordium.sdk.serializing.JsonMapper;
import com.fasterxml.jackson.core.JsonProcessingException;

public class AcceptableRequest {
// Static block to load native library.
static {
NativeResolver.loadLib();
}

/**
* Check that a request is acceptable:
* That range statements are only on the attributes "dob", "idiDocIssuedAt" or
* "idDocExpiredAt"
* That membership statement are only on the attributes "Country of residence",
* "Nationality", "IdDocType" or "IdDocIssuer"
* That attribute tags are not reused within a credentialStatement
*
* @param input the request that should be checked
* @throws NotAcceptableException if the request is not acceptable
* @Throws CryptoJniException if there an error occurs duting the check
* @returns if the request is acceptable, otherwise throws a
* NotAcceptableException
*/
public static void acceptableRequest(QualifiedRequest request) throws NotAcceptableException {
ErrorResult result = null;
try {
String jsonStr = CryptoJniNative.isAcceptableRequest(JsonMapper.INSTANCE.writeValueAsString(request));
result = JsonMapper.INSTANCE.readValue(jsonStr, ErrorResult.class);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
if (!result.isSuccess()) {
throw CryptoJniException.from(result.getErr());
}
if (result.getResult() != null) {
throw new NotAcceptableException(result.getResult());
}
}

/**
* Check that a statement is acceptable
*
* @param statement the statement that should be checked
* @param rangeTag the attribute tags that may be used for range
* statements
* @param setTags the attribute tags that may be used for set statements
* @param attributeCheck custom check on the value of the statement.
* @throws NotAcceptableException if the request is not acceptable
* @Throws CryptoJniException if there an error occurs duting the check
* @returns if the request is acceptable, otherwise throws a
* NotAcceptableException
*/
public static void acceptableAtomicStatement(AtomicStatement statement, List<String> rangeTags,
List<String> setTags, AttributeCheck attributeCheck) throws NotAcceptableException {
StringResult result = null;
try {

String jsonStr = CryptoJniNative.isAcceptableAtomicStatement(
JsonMapper.INSTANCE.writeValueAsString(statement),
JsonMapper.INSTANCE.writeValueAsString(rangeTags),
JsonMapper.INSTANCE.writeValueAsString(setTags),
new RawAttributeCheck(attributeCheck));
result = JsonMapper.INSTANCE.readValue(jsonStr, StringResult.class);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
if (!result.isSuccess()) {
throw CryptoJniException.from(result.getErr());
}
if (result.getResult() != null) {
throw new NotAcceptableException(result.getResult());
}
}

public static class RawAttributeCheck {
AttributeCheck checker;

public RawAttributeCheck(AttributeCheck checker) {
this.checker = checker;
}

public void check_attribute(String tag, String value) throws Exception {
checker.checkAttribute(tag, JsonMapper.INSTANCE.readValue(value, CredentialAttribute.class));
}
}

public static class NotAcceptableException extends Exception {
public NotAcceptableException(String errorMessage) {
super(errorMessage);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.concordium.sdk.crypto.wallet.web3Id;


public interface AttributeCheck {
/**
* This check should throw an exception if the given attribute value is not valid.
* @param tag the attribute tag for the statement
* @param value the attribute value used in the statement
* @throws Exception to indicate the attribute is not valid.
*/
public void checkAttribute(String tag, CredentialAttribute value) throws Exception;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import static org.junit.Assert.assertTrue;

import java.nio.charset.Charset;
import java.util.Collections;
import java.util.List;

import org.junit.Test;
Expand All @@ -12,8 +13,11 @@
import com.concordium.sdk.crypto.wallet.FileHelpers;
import com.concordium.sdk.crypto.wallet.Network;
import com.concordium.sdk.crypto.wallet.identityobject.IdentityObject;
import com.concordium.sdk.crypto.wallet.web3Id.AcceptableRequest.NotAcceptableException;
import com.concordium.sdk.crypto.wallet.web3Id.CredentialAttribute.CredentialAttributeType;
import com.concordium.sdk.crypto.wallet.web3Id.Statement.AtomicStatement;
import com.concordium.sdk.crypto.wallet.web3Id.Statement.QualifiedRequestStatement;
import com.concordium.sdk.crypto.wallet.web3Id.Statement.RangeStatement;
import com.concordium.sdk.crypto.wallet.web3Id.Statement.RequestStatement;
import com.concordium.sdk.crypto.wallet.web3Id.Statement.StatementType;
import com.concordium.sdk.serializing.JsonMapper;
Expand Down Expand Up @@ -51,6 +55,49 @@ public void testGetsUnsatisfiedStatement() throws Exception {
assertEquals(requestStatement1.getStatement().get(0), unsatisfied.get(0));
}

@Test
public void testIsAcceptableRequest() throws Exception {
QualifiedRequest request = ProofTest.loadRequest("accountRequest.json");
AcceptableRequest.acceptableRequest(request);
}

@Test
public void testIsAcceptableAtomicStatement() throws NotAcceptableException {
AtomicStatement statement = RangeStatement.builder().attributeTag("dob")
.lower(CredentialAttribute.builder().type(CredentialAttributeType.STRING).value("20140112").build())
.upper(CredentialAttribute.builder().type(CredentialAttributeType.STRING).value("20150112").build())
.build();

AcceptableRequest.acceptableAtomicStatement(statement, Collections.singletonList("dob"), Collections.emptyList(), new AttributeCheck() {
@Override
public void checkAttribute(String tag, CredentialAttribute value) {}});
}

@Test(expected = AcceptableRequest.NotAcceptableException.class)
public void testIllegalTagStatementThrowsNotAcceptable() throws NotAcceptableException {
AtomicStatement statement = RangeStatement.builder().attributeTag("dob")
.lower(CredentialAttribute.builder().type(CredentialAttributeType.STRING).value("20140112").build())
.upper(CredentialAttribute.builder().type(CredentialAttributeType.STRING).value("20150112").build())
.build();

AcceptableRequest.acceptableAtomicStatement(statement, Collections.emptyList(), Collections.emptyList(), new AttributeCheck() {
@Override
public void checkAttribute(String tag, CredentialAttribute value) {}});
}

@Test(expected = AcceptableRequest.NotAcceptableException.class)
public void testAttributeCheckThrowingErrorReturnsNotAcceptable() throws NotAcceptableException {
AtomicStatement statement = RangeStatement.builder().attributeTag("dob")
.lower(CredentialAttribute.builder().type(CredentialAttributeType.STRING).value("20140112").build())
.upper(CredentialAttribute.builder().type(CredentialAttributeType.STRING).value("20150112").build())
.build();

AcceptableRequest.acceptableAtomicStatement(statement, Collections.emptyList(), Collections.emptyList(), new AttributeCheck() {
@Override
public void checkAttribute(String tag, CredentialAttribute value) throws Exception {
throw new Exception("Not okay");
}});
}
@Test
public void testCanQualifyStatement() throws Exception {
// Arrange
Expand All @@ -61,6 +108,7 @@ public void testCanQualifyStatement() throws Exception {
"8a3a87f3f38a7a507d1e85dc02a92b8bcaa859f5cf56accb3c1bc7c40e1789b4933875a38dd4c0646ca3e940a02c42d8");
ContractAddress contractAddress = ContractAddress.from(1232, 3);
ED25519PublicKey publicKey = ED25519PublicKey

.from("16afdb3cb3568b5ad8f9a0fa3c741b065642de8c53e58f7920bf449e63ff2bf9");

// Act
Expand Down
Loading

0 comments on commit 17eab40

Please sign in to comment.