Skip to content

Commit

Permalink
Add Clock Skew Tolerance for Verifiable Presentations (#377)
Browse files Browse the repository at this point in the history
  • Loading branch information
CharlesShuller committed Oct 25, 2023
1 parent 7227624 commit 8da3a09
Show file tree
Hide file tree
Showing 11 changed files with 505 additions and 49 deletions.
43 changes: 36 additions & 7 deletions examples/java-springboot/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.1</version>
<version>2.7.17</version>
<relativePath/>
</parent>
<groupId>com.spruceid</groupId>
Expand Down Expand Up @@ -43,6 +43,12 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>

<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
Expand All @@ -63,14 +69,15 @@
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
<version>8.0.33</version>
</dependency>

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
<version>1.18.20</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>com.google.zxing</groupId>
Expand Down Expand Up @@ -103,6 +110,17 @@
<version>2.21.0</version>
</dependency>

<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.6.0</version>
</dependency>

<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20231013</version>
</dependency>

</dependencies>

Expand All @@ -115,4 +133,15 @@
</plugins>
</build>


<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-report-plugin</artifactId>
<version>2.22.0</version>
</plugin>
</plugins>
</reporting>

</project>
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@
import com.spruceid.didkitexample.util.Resources;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;

import java.nio.file.Paths;
import com.spruceid.didkitexample.config.DIDKitConfig;

@SpringBootApplication
@ConfigurationPropertiesScan("com.spruceid.didkitexample.config")
public class DIDKitExampleApplication {

public static void main(String[] args) throws Throwable {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,26 @@
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
import org.springframework.beans.factory.annotation.Autowired;

import java.nio.file.Files;

import com.spruceid.didkitexample.config.DIDKitConfig;

import java.util.Optional;
import java.util.Map;

import java.nio.file.Files;


@Component
@AllArgsConstructor
public class VPAuthenticationProvider implements AuthenticationProvider {
private final UserService userService;

@Autowired
private final DIDKitConfig didkitConfig;


@Override
public Authentication authenticate(Authentication auth) {
final VPAuthenticationToken token = (VPAuthenticationToken) auth;
Expand All @@ -37,7 +48,13 @@ public Authentication authenticate(Authentication auth) {

final Map<String, Object> vc;
try {
vc = VerifiablePresentation.verifyPresentation(key, presentation, null);
vc = VerifiablePresentation.verifyPresentation(
key,
presentation,
Optional.empty(),
Optional.empty(),
Optional.of(didkitConfig.maxClockSkew)
);
} catch (Exception e) {
throw new BadCredentialsException("Failed to verify presentation");
}
Expand All @@ -55,4 +72,3 @@ public boolean supports(Class<?> authentication) {
return VPAuthenticationToken.class.isAssignableFrom(authentication);
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.spruceid.didkitexample.config;

import java.time.Duration;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
import org.springframework.boot.context.properties.ConstructorBinding;

@Getter
@ConfigurationProperties(prefix = "didkit")
@ConfigurationPropertiesScan
public class DIDKitConfig {
public Duration maxClockSkew;


@ConstructorBinding
DIDKitConfig(Duration maxClockSkew) {
this.maxClockSkew = maxClockSkew;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import com.spruceid.didkitexample.config.DIDKitConfig;


@EnableWebSecurity
@AllArgsConstructor
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
Expand All @@ -24,8 +27,12 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private final StringRedisTemplate redisTemplate;

@Autowired
private final DIDKitConfig didkitConfig;


public AuthenticationProvider customAuthenticationProvider() {
return new VPAuthenticationProvider(userService);
return new VPAuthenticationProvider(userService, didkitConfig);
}

public VPAuthenticationFilter authenticationFilter() throws Exception {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.Optional;

import com.spruceid.didkitexample.config.DIDKitConfig;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

Expand All @@ -43,6 +47,9 @@ public class VerifiablePresentationRequestController {
@Autowired
private final ConcurrentHashMap<String, WebSocketSession> sessionMap;

@Autowired
private final DIDKitConfig didkitConfig;

@GetMapping(value = "/verifiable-presentation-request/{challenge}", produces = MediaType.APPLICATION_JSON_VALUE)
public VerifiablePresentationRequest vpRequestGet(
@PathVariable("challenge") String challenge
Expand Down Expand Up @@ -85,7 +92,14 @@ public void vpRequestPost(
}

logger.info("VerifiablePresentation.verifyPresentation");
final Map<String, Object> vc = VerifiablePresentation.verifyPresentation(key, presentation, challenge);
final Map<String, Object> vc =
VerifiablePresentation.verifyPresentation(
key,
presentation,
Optional.of(challenge),
Optional.empty(),
Optional.of(didkitConfig.maxClockSkew)
);
final Map<String, Object> credentialSubject = (Map<String, Object>) vc.get("credentialSubject");

final String username = credentialSubject.get("alumniOf").toString();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,13 @@ public String issueCredential(String id, User user) throws DIDKitException, IOEx
final String verificationMethod = DIDKit.keyToVerificationMethod("key", key);

final UserCredential credential = new UserCredential(didKey, id, user.getUsername());
final DIDKitOptions options = new DIDKitOptions("assertionMethod", verificationMethod, null, null);
final DIDKitOptions options = new DIDKitOptions(
"assertionMethod", // proofPurpose
verificationMethod, // verificationMethos
Optional.empty(), // challenge
null, // domain
Optional.empty() // created
);

final ObjectMapper mapper = new ObjectMapper();
final String credentialJson = mapper.writeValueAsString(credential);
Expand All @@ -57,4 +63,3 @@ public String issueCredential(String id, User user) throws DIDKitException, IOEx
return DIDKit.issueCredential(credentialJson, optionsJson, key);
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import lombok.NonNull;
import java.util.Optional;
import java.time.Instant;
import java.time.format.DateTimeFormatter;


@Getter
@Setter
Expand All @@ -14,4 +19,25 @@ public class DIDKitOptions {
private String verificationMethod;
private String challenge;
private String domain;

// This will be the "system time" for when something is processed
// not the time the VP is created.
private String created;

public DIDKitOptions(
String proofPurpose,
String verificationMethod,
@NonNull Optional<String> challenge,
String domain,
@NonNull Optional<Instant> created
) {
this.proofPurpose = proofPurpose;
this.verificationMethod = verificationMethod;
this.challenge = challenge.orElse(null);
this.domain = domain;
this.created =
created
.map(i -> DateTimeFormatter.ISO_INSTANT.format(i))
.orElse(DateTimeFormatter.ISO_INSTANT.format(Instant.now()));
}
}

0 comments on commit 8da3a09

Please sign in to comment.