Skip to content

Commit

Permalink
Merge pull request #11 from diggsweden/mdl-presentation
Browse files Browse the repository at this point in the history
MDL Presentation and updated API
  • Loading branch information
Razumain authored Feb 5, 2025
2 parents 8664b58 + 7a58024 commit 1f4e53c
Show file tree
Hide file tree
Showing 52 changed files with 2,238 additions and 433 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ SPDX-License-Identifier: EUPL-1.2

<groupId>se.digg.wallet</groupId>
<artifactId>eudiw-wallet-token-lib</artifactId>
<version>0.0.2-SNAPSHOT</version>
<version>0.1.0-SNAPSHOT</version>
<name>EUDI Wallet -- Token Library</name>
<description>Library for handling data types in the EUDI Wallet PoC project.</description>
<url>https://github.com/diggsweden/eudiw-wallet-token-lib</url>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package se.digg.wallet.datatypes.common;

import lombok.Getter;
import lombok.NoArgsConstructor;

import java.util.List;

@Getter
@NoArgsConstructor
public class PresentationInput<T extends Object> {

protected byte[] token;
protected String nonce;
protected TokenSigningAlgorithm algorithm;
protected T disclosures;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package se.digg.wallet.datatypes.common;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
* Input to presentation validation for mDoc and SD JWT
*/

@Data
@AllArgsConstructor
@NoArgsConstructor
public class PresentationValidationInput {
protected String requestNonce;
}



Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package se.digg.wallet.datatypes.common;

import java.util.List;

/**
* Defines an interface for validating verifiable presentations.
* <p>
* A verifiable presentation, which may include selective disclosures, can be validated using this interface.
* Validation is performed using a combination of the presented token, a set of validation input parameters,
* and a list of trusted signing keys.
* <p>
* Proving signing keys is optional. If keys are provided, validation verifies that a trusted key is used to sign the presentation.
* If no trusted keys are provided, then the result lists the used signing key/path.
* <p>
* The process ensures the integrity and authenticity of the token, while also verifying its structural correctness,
* optional expiration, and the presence of a valid nonce.
* <p>
* Methods in this interface may throw exceptions indicating issues with the token's integrity, parsing, or validation.
*/
public interface PresentationValidator {

/**
* Validates a verifiable presentation and ensures its integrity, authenticity, and adherence to the required structure.
* The validation process involves verifying the structural correctness of the presentation, checking the expiration time,
* ensuring the presence and validity of a nonce, and optionally validating it against a specified list of trusted keys.
*
* @param presentation the byte array representation of the verifiable presentation to be validated.
* @param presentationValidationInput input parameters needed for the validation process, such as a request nonce.
* @param trustedKeys an optional list of trusted keys used to verify the signing key of the presentation. If no trusted
* keys are provided, the result will include details of the signing key/path used for validation.
* @return an instance of {@code TokenValidationResult} containing validation details such as the validation key,
* issue time, expiration time, and nonce.
* @throws TokenValidationException if the presentation validation fails due to structural or cryptographic errors.
* @throws TokenParsingException if an error occurs during parsing of the presentation.
*/
TokenValidationResult validatePresentation(byte[] presentation, PresentationValidationInput presentationValidationInput,
List<TrustedKey> trustedKeys) throws TokenValidationException, TokenParsingException;

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,9 @@
@Builder
public class TokenAttribute {

/** The name of the attribute presented in the token */
private String name;
/** Optional nameSpace declaration (Required for mDL tokens) */
private String nameSpace;
/** The type of token attribute */
private TokenAttributeType type;
/** The attribute value. For most attributes, this is either a String, Integer or LocalDate object */
private Object value;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package se.digg.wallet.datatypes.common;

import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor
public enum TokenAttributeNameSpace {
EUDI_WALLET_PID("eu.europa.ec.eudi.pid.1"),
MDOC_MDL("org.iso.18013.5.1");

String id;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package se.digg.wallet.datatypes.common;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class TokenAttributeType {

private String nameSpace;
private String attributeName;

public TokenAttributeType(String attributeName) {
this.attributeName = attributeName;
this.nameSpace = null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package se.digg.wallet.datatypes.common;

import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import lombok.AllArgsConstructor;
import lombok.Getter;
Expand All @@ -15,21 +16,33 @@
@Getter
@AllArgsConstructor
public enum TokenDigestAlgorithm {
SHA_256("SHA-256", "SHA-256"),
SHA_384("SHA-384", "SHA-384"),
SHA_512("SHA-512", "SHA-512");
SHA_256("SHA-256", "SHA-256", "sha-256"),
SHA_384("SHA-384", "SHA-384", "sha-384"),
SHA_512("SHA-512", "SHA-512", "sha-512");

private final String mdlName;
private final String jdkName;
private final String sdJwtName;

public static TokenDigestAlgorithm fromMdlName(String mdlName)
throws IOException {
throws NoSuchAlgorithmException {
return Arrays.stream(values())
.filter(
tokenDigestAlgorithm ->
tokenDigestAlgorithm.getMdlName().equalsIgnoreCase(mdlName)
)
.findFirst()
.orElseThrow(() -> new IOException("Unsupported mDL hash algorithm"));
.orElseThrow(() -> new NoSuchAlgorithmException("Unsupported mDL hash algorithm"));
}

public static TokenDigestAlgorithm fromSdJwtName(String sdJwtName) throws NoSuchAlgorithmException {
return Arrays.stream(values())
.filter(
tokenDigestAlgorithm ->
tokenDigestAlgorithm.getSdJwtName().equalsIgnoreCase(sdJwtName)
)
.findFirst()
.orElseThrow(() -> new NoSuchAlgorithmException("Unsupported SD-JWT hash algorithm"));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
* Interface for a token issuer
*/
public interface TokenIssuer<T extends TokenInput> {

/**
* Generates a token based on the provided TokenInput.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package se.digg.wallet.datatypes.common;

import java.io.Serial;

public class TokenParsingException extends Exception {
@Serial
private static final long serialVersionUID = -150091799709439631L;


public TokenParsingException() {
}

public TokenParsingException(String message) {
super(message);
}

public TokenParsingException(String message, Throwable cause) {
super(message, cause);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package se.digg.wallet.datatypes.common;

import java.io.Serial;

public class TokenPresentationException extends Exception {
@Serial
private static final long serialVersionUID = 942635978985209161L;

public TokenPresentationException() {
}

public TokenPresentationException(String message) {
super(message);
}

public TokenPresentationException(String message, Throwable cause) {
super(message, cause);
}

public TokenPresentationException(Throwable cause) {
super(cause);
}
}
23 changes: 23 additions & 0 deletions src/main/java/se/digg/wallet/datatypes/common/TokenPresenter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package se.digg.wallet.datatypes.common;

import java.security.PrivateKey;

/**
* Represents an interface for creating verifiable presentation of a token with selective disclosures.
* It defines the contract for handling a token issued by a token issuer and generating a
* token with disclosures and cryptographic proof using a private key.
*
* @param <T> the type of PresentationInput, where the input contains the token,
* cryptographic settings, and disclosures.
*/
public interface TokenPresenter<T extends PresentationInput<?>> {

/**
* Creates a presentation token with selective disclosures
*
* @param presentationInput the verifiable presentation token input
* @return token with disclosures and device provided key proof
*/
byte[] presentToken(PresentationInput<?> presentationInput, PrivateKey privateKey) throws TokenPresentationException;

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,43 +6,25 @@

import java.security.PublicKey;
import java.security.cert.X509Certificate;
import java.time.Instant;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
* This is an abstract result class for token validation results. This may be extended by explicit token validators
*
* @param <T> Class Type for the Token as Java Object
* @param <P> Class Type for the signed Payload as Java Object
* This class holds base result data for token validation. This is extended by explicit token validators
*/
@Data
@NoArgsConstructor
public abstract class TokenValidationResult<
T extends Object, P extends Object
> {
public class TokenValidationResult{

protected PublicKey validationKey;

protected X509Certificate validationCertificate;

protected List<X509Certificate> validationChain;

protected PublicKey walletPublicKey;

/**
* Retrieves the validated token data.
*
* @return The token data.
*/
public abstract T getTokenData();

/**
* Retrieves the signed payload associated with the token.
*
* @return The signed payload data.
*/
public abstract P getTokenPayload();
protected Instant issueTime;
protected Instant expirationTime;
protected String presentationRequestNonce;
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public interface TokenValidator {
* @param trustedKeys optional list of trusted keys used for validation.
* @return An instance of TokenValidationResult containing information about the validation result.
*/
TokenValidationResult<?, ?> validateToken(
TokenValidationResult validateToken(
byte[] token,
List<TrustedKey> trustedKeys
) throws TokenValidationException;
Expand Down
Loading

0 comments on commit 1f4e53c

Please sign in to comment.