From 068a6edb8dcf29b44810b9e8a74e0ab610ef59d4 Mon Sep 17 00:00:00 2001 From: Markus Gylling Date: Mon, 20 Jun 2022 14:51:37 +0200 Subject: [PATCH] initial cut of ob3 verifier --- inspector-vc/pom.xml | 15 + .../org/oneedtech/inspect/vc/Credential.java | 107 +++ .../inspect/vc/EndorsementInspector.java | 69 ++ .../oneedtech/inspect/vc/OB30Inspector.java | 195 +++++ .../org/oneedtech/inspect/vc/VCInspector.java | 47 ++ .../inspect/vc/probe/CredentialTypeProbe.java | 165 ++++ .../vc/probe/ExpirationVerifierProbe.java | 47 ++ .../vc/probe/InlineJsonSchemaProbe.java | 71 ++ .../vc/probe/IssuanceVerifierProbe.java | 47 ++ .../inspect/vc/probe/Predicates.java | 51 ++ .../inspect/vc/probe/ProofVerifierProbe.java | 27 + .../inspect/vc/probe/RevocationListProbe.java | 79 ++ .../vc/probe/SignatureVerifierProbe.java | 28 + .../inspect/vc/util/JsonNodeUtil.java | 58 ++ .../org/oneedtech/inspect/vc/OB30Tests.java | 94 +++ .../org/oneedtech/inspect/vc/Samples.java | 25 + .../inspect/vc/util/JsonNodeUtilTests.java | 30 + .../src/test/resources/ob30/complete.json | 712 ++++++++++++++++++ .../src/test/resources/ob30/simple-json.png | Bin 0 -> 83758 bytes .../src/test/resources/ob30/simple-json.svg | 56 ++ .../src/test/resources/ob30/simple-jwt.png | Bin 0 -> 83939 bytes .../src/test/resources/ob30/simple-jwt.svg | 17 + .../resources/ob30/simple-unknown-type.json | 36 + .../src/test/resources/ob30/simple.json | 36 + .../src/test/resources/ob30/simple.jwt | 1 + 25 files changed, 2013 insertions(+) create mode 100644 inspector-vc/pom.xml create mode 100644 inspector-vc/src/main/java/org/oneedtech/inspect/vc/Credential.java create mode 100644 inspector-vc/src/main/java/org/oneedtech/inspect/vc/EndorsementInspector.java create mode 100644 inspector-vc/src/main/java/org/oneedtech/inspect/vc/OB30Inspector.java create mode 100644 inspector-vc/src/main/java/org/oneedtech/inspect/vc/VCInspector.java create mode 100644 inspector-vc/src/main/java/org/oneedtech/inspect/vc/probe/CredentialTypeProbe.java create mode 100644 inspector-vc/src/main/java/org/oneedtech/inspect/vc/probe/ExpirationVerifierProbe.java create mode 100644 inspector-vc/src/main/java/org/oneedtech/inspect/vc/probe/InlineJsonSchemaProbe.java create mode 100644 inspector-vc/src/main/java/org/oneedtech/inspect/vc/probe/IssuanceVerifierProbe.java create mode 100644 inspector-vc/src/main/java/org/oneedtech/inspect/vc/probe/Predicates.java create mode 100644 inspector-vc/src/main/java/org/oneedtech/inspect/vc/probe/ProofVerifierProbe.java create mode 100644 inspector-vc/src/main/java/org/oneedtech/inspect/vc/probe/RevocationListProbe.java create mode 100644 inspector-vc/src/main/java/org/oneedtech/inspect/vc/probe/SignatureVerifierProbe.java create mode 100644 inspector-vc/src/main/java/org/oneedtech/inspect/vc/util/JsonNodeUtil.java create mode 100644 inspector-vc/src/test/java/org/oneedtech/inspect/vc/OB30Tests.java create mode 100644 inspector-vc/src/test/java/org/oneedtech/inspect/vc/Samples.java create mode 100644 inspector-vc/src/test/java/org/oneedtech/inspect/vc/util/JsonNodeUtilTests.java create mode 100644 inspector-vc/src/test/resources/ob30/complete.json create mode 100644 inspector-vc/src/test/resources/ob30/simple-json.png create mode 100644 inspector-vc/src/test/resources/ob30/simple-json.svg create mode 100644 inspector-vc/src/test/resources/ob30/simple-jwt.png create mode 100644 inspector-vc/src/test/resources/ob30/simple-jwt.svg create mode 100644 inspector-vc/src/test/resources/ob30/simple-unknown-type.json create mode 100644 inspector-vc/src/test/resources/ob30/simple.json create mode 100644 inspector-vc/src/test/resources/ob30/simple.jwt diff --git a/inspector-vc/pom.xml b/inspector-vc/pom.xml new file mode 100644 index 0000000..6881751 --- /dev/null +++ b/inspector-vc/pom.xml @@ -0,0 +1,15 @@ + + 4.0.0 + + org.1edtech + inspector + 0.9.2 + + inspector-vc + + + org.1edtech + inspector-core + + + \ No newline at end of file diff --git a/inspector-vc/src/main/java/org/oneedtech/inspect/vc/Credential.java b/inspector-vc/src/main/java/org/oneedtech/inspect/vc/Credential.java new file mode 100644 index 0000000..63205c8 --- /dev/null +++ b/inspector-vc/src/main/java/org/oneedtech/inspect/vc/Credential.java @@ -0,0 +1,107 @@ +package org.oneedtech.inspect.vc; + +import static org.oneedtech.inspect.util.code.Defensives.*; +import static org.oneedtech.inspect.util.resource.ResourceType.*; + +import java.util.Iterator; +import java.util.Optional; + +import org.oneedtech.inspect.core.probe.GeneratedObject; +import org.oneedtech.inspect.schema.Catalog; +import org.oneedtech.inspect.schema.SchemaKey; +import org.oneedtech.inspect.util.resource.Resource; +import org.oneedtech.inspect.util.resource.ResourceType; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.google.common.base.MoreObjects; + +/** + * A wrapper object for a verifiable credential. This contains e.g. the origin resource + * and the extracted JSON data plus any other stuff Probes need. + * @author mgylling + */ +public class Credential extends GeneratedObject { + final Resource resource; + final JsonNode jsonData; + final Credential.Type credentialType; + + public Credential(Resource resource, JsonNode data) { + super(ID, GeneratedObject.Type.INTERNAL); + checkNotNull(resource, resource.getType(), data); + ResourceType type = resource.getType(); + checkTrue(type == SVG || type == PNG || type == JSON || type == JWT, + "Unrecognized payload type: " + type.getName()); + this.resource = resource; + this.jsonData = data; + + ArrayNode typeNode = (ArrayNode)jsonData.get("type"); + this.credentialType = Credential.Type.valueOf(typeNode); + + } + + public Resource getResource() { + return resource; + } + + public JsonNode asJson() { + return jsonData; + } + + public Credential.Type getCredentialType() { + return credentialType; + } + + /** + * Get the canonical schema for this credential if such exists. + */ + public Optional getSchemaKey() { + if(credentialType == Credential.Type.AchievementCredential) { + return Optional.of(Catalog.OB_30_ACHIEVEMENTCREDENTIAL_JSON); + } else if(credentialType == Credential.Type.VerifiablePresentation) { + return Optional.of(Catalog.OB_30_VERIFIABLEPRESENTATION_JSON); + } else if(credentialType == Credential.Type.EndorsementCredential) { + return Optional.of(Catalog.OB_30_ENDORSEMENTCREDENTIAL_JSON); + } + return Optional.empty(); + } + + public enum Type { + AchievementCredential, + OpenBadgeCredential, //treated as an alias of AchievementCredential + EndorsementCredential, + VerifiablePresentation, + VerifiableCredential, //this is an underspecifier in our context + Unknown; + + public static Credential.Type valueOf (ArrayNode typeArray) { + if(typeArray != null) { + Iterator iter = typeArray.iterator(); + while(iter.hasNext()) { + String value = iter.next().asText(); + if(value.equals("AchievementCredential") || value.equals("OpenBadgeCredential")) { + return AchievementCredential; + } else if(value.equals("VerifiablePresentation")) { + return VerifiablePresentation; + } else if(value.equals("EndorsementCredential")) { + return EndorsementCredential; + } + } + } + return Unknown; + } + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("resource", resource.getID()) + .add("resourceType", resource.getType()) + .add("credentialType", credentialType) + .add("json", jsonData) + .toString(); + } + + public static final String ID = Credential.class.getCanonicalName(); + +} diff --git a/inspector-vc/src/main/java/org/oneedtech/inspect/vc/EndorsementInspector.java b/inspector-vc/src/main/java/org/oneedtech/inspect/vc/EndorsementInspector.java new file mode 100644 index 0000000..a8af2c9 --- /dev/null +++ b/inspector-vc/src/main/java/org/oneedtech/inspect/vc/EndorsementInspector.java @@ -0,0 +1,69 @@ +package org.oneedtech.inspect.vc; + +import static org.oneedtech.inspect.core.probe.RunContext.Key.*; +import static org.oneedtech.inspect.util.json.ObjectMapperCache.Config.DEFAULT; + +import java.util.Map; + +import org.oneedtech.inspect.core.SubInspector; +import org.oneedtech.inspect.core.probe.GeneratedObject; +import org.oneedtech.inspect.core.probe.RunContext; +import org.oneedtech.inspect.core.probe.RunContext.Key; +import org.oneedtech.inspect.core.probe.json.JsonPathEvaluator; +import org.oneedtech.inspect.core.report.Report; +import org.oneedtech.inspect.core.report.ReportItems; +import org.oneedtech.inspect.util.json.ObjectMapperCache; +import org.oneedtech.inspect.util.resource.Resource; + +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * An inspector for EndersementCredential objects. + * @author mgylling + */ +public class EndorsementInspector extends VCInspector implements SubInspector { + + protected > EndorsementInspector(B builder) { + super(builder); + } + + @Override + public Report run(Resource resource, Map parentObjects) { + /* + * resource is the top-level credential that embeds the endorsement, we + * expect parentObjects to provide a pointer to the JsonNode we should check + */ + Credential endorsement = (Credential) parentObjects.get(ENDORSEMENT_KEY); + + ObjectMapper mapper = ObjectMapperCache.get(DEFAULT); + JsonPathEvaluator jsonPath = new JsonPathEvaluator(mapper); + + RunContext ctx = new RunContext.Builder() + .put(this) + .put(resource) + .put(JACKSON_OBJECTMAPPER, mapper) + .put(JSONPATH_EVALUATOR, jsonPath) + .put(ENDORSEMENT_KEY, endorsement) + .build(); + + System.err.println("TODO" + endorsement.toString()); + + return new Report(ctx, new ReportItems(), 1); //TODO + } + + @Override + public Report run(R resource) { + throw new IllegalStateException("must use #run(resource, map)"); + } + + public static class Builder extends VCInspector.Builder { + @SuppressWarnings("unchecked") + @Override + public EndorsementInspector build() { + return new EndorsementInspector(this); + } + } + + public static final String ENDORSEMENT_KEY = "ENDORSEMENT_KEY"; + +} diff --git a/inspector-vc/src/main/java/org/oneedtech/inspect/vc/OB30Inspector.java b/inspector-vc/src/main/java/org/oneedtech/inspect/vc/OB30Inspector.java new file mode 100644 index 0000000..8da0e1a --- /dev/null +++ b/inspector-vc/src/main/java/org/oneedtech/inspect/vc/OB30Inspector.java @@ -0,0 +1,195 @@ +package org.oneedtech.inspect.vc; + +import static java.lang.Boolean.TRUE; +import static org.oneedtech.inspect.core.Inspector.Behavior.RESET_CACHES_ON_RUN; +import static org.oneedtech.inspect.core.report.ReportUtil.onProbeException; +import static org.oneedtech.inspect.util.json.ObjectMapperCache.Config.DEFAULT; +import static org.oneedtech.inspect.vc.EndorsementInspector.ENDORSEMENT_KEY; +import static org.oneedtech.inspect.vc.util.JsonNodeUtil.getEndorsements; + +import java.net.URI; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import org.oneedtech.inspect.core.probe.Outcome; +import org.oneedtech.inspect.core.probe.Probe; +import org.oneedtech.inspect.core.probe.RunContext; +import org.oneedtech.inspect.core.probe.RunContext.Key; +import org.oneedtech.inspect.core.probe.json.JsonArrayProbe; +import org.oneedtech.inspect.core.probe.json.JsonPathEvaluator; +import org.oneedtech.inspect.core.probe.json.JsonPredicates.JsonPredicateProbeParams; +import org.oneedtech.inspect.core.probe.json.JsonSchemaProbe; +import org.oneedtech.inspect.core.report.Report; +import org.oneedtech.inspect.core.report.ReportItems; +import org.oneedtech.inspect.schema.JsonSchemaCache; +import org.oneedtech.inspect.schema.SchemaKey; +import org.oneedtech.inspect.util.json.ObjectMapperCache; +import org.oneedtech.inspect.util.resource.Resource; +import org.oneedtech.inspect.util.resource.ResourceType; +import org.oneedtech.inspect.util.resource.UriResource; +import org.oneedtech.inspect.util.resource.context.ResourceContext; +import org.oneedtech.inspect.util.spec.Specification; +import org.oneedtech.inspect.vc.probe.CredentialTypeProbe; +import org.oneedtech.inspect.vc.probe.ExpirationVerifierProbe; +import org.oneedtech.inspect.vc.probe.InlineJsonSchemaProbe; +import org.oneedtech.inspect.vc.probe.IssuanceVerifierProbe; +import org.oneedtech.inspect.vc.probe.Predicates; +import org.oneedtech.inspect.vc.probe.ProofVerifierProbe; +import org.oneedtech.inspect.vc.probe.RevocationListProbe; +import org.oneedtech.inspect.vc.probe.SignatureVerifierProbe; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.collect.ImmutableList; + +/** + * A verifier for Open Badges 3.0. + * @author mgylling + */ +public class OB30Inspector extends VCInspector { + protected final List> userProbes; + + protected OB30Inspector(OB30Inspector.Builder builder) { + super(builder); + this.userProbes = ImmutableList.copyOf(builder.probes); + } + + //https://docs.google.com/document/d/1_imUl2K-5tMib0AUxwA9CWb0Ap1b3qif0sXydih68J0/edit# + //https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#verificaton-and-validation + + @Override + public Report run(Resource resource) { + super.check(resource); + + if(getBehavior(RESET_CACHES_ON_RUN) == TRUE) JsonSchemaCache.reset(); + + ObjectMapper mapper = ObjectMapperCache.get(DEFAULT); + JsonPathEvaluator jsonPath = new JsonPathEvaluator(mapper); + + RunContext ctx = new RunContext.Builder() + .put(this) + .put(resource) + .put(Key.JACKSON_OBJECTMAPPER, mapper) + .put(Key.JSONPATH_EVALUATOR, jsonPath) + .build(); + + List accumulator = new ArrayList<>(); + int probeCount = 0; + + try { + //detect type (png, svg, json, jwt) and extract json data + probeCount++; + accumulator.add(new CredentialTypeProbe().run(resource, ctx)); + if(broken(accumulator)) return abort(ctx, accumulator, probeCount); + + //we expect the above to place a generated object in the context + Credential crd = ctx.getGeneratedObject(Credential.ID); + + //validate the value of the type property + probeCount++; + accumulator.add(new JsonArrayProbe(vcType).run(crd.asJson(), ctx)); + probeCount++; + accumulator.add(new JsonArrayProbe(obType).run(crd.asJson(), ctx)); + if(broken(accumulator)) return abort(ctx, accumulator, probeCount); + + //validate against the canonical schema + SchemaKey canonical = crd.getSchemaKey().orElseThrow(); + probeCount++; + accumulator.add(new JsonSchemaProbe(canonical).run(crd.asJson(), ctx)); + + //validate against any inline schemas + probeCount++; + accumulator.add(new InlineJsonSchemaProbe().run(crd, ctx)); + + //verify signatures TODO @Miles + probeCount++; + accumulator.add(new SignatureVerifierProbe().run(crd, ctx)); + if(broken(accumulator)) return abort(ctx, accumulator, probeCount); + + //verify proofs TODO @Miles + probeCount++; + accumulator.add(new ProofVerifierProbe().run(crd, ctx)); + if(broken(accumulator)) return abort(ctx, accumulator, probeCount); + + //check refresh service if we are not already refreshed + probeCount++; + if(resource.getContext().get(REFRESHED) != TRUE) { + Optional newID = checkRefreshService(crd, ctx); //TODO fail = invalid + if(newID.isPresent()) { + return this.run( + new UriResource(new URI(newID.get())) + .setContext(new ResourceContext(REFRESHED, TRUE))); + } + } + + //check revocation status + probeCount++; + accumulator.add(new RevocationListProbe().run(crd, ctx)); + if(broken(accumulator)) return abort(ctx, accumulator, probeCount); + + //check expiration + probeCount++; + accumulator.add(new ExpirationVerifierProbe().run(crd, ctx)); + if(broken(accumulator)) return abort(ctx, accumulator, probeCount); + + //check issuance + probeCount++; + accumulator.add(new IssuanceVerifierProbe().run(crd, ctx)); + if(broken(accumulator)) return abort(ctx, accumulator, probeCount); + + //embedded endorsements + List endorsements = getEndorsements(crd.asJson(), jsonPath); + if(endorsements.size() > 0) { + EndorsementInspector subInspector = new EndorsementInspector.Builder().build(); + for(JsonNode endorsementNode : endorsements) { + probeCount++; + Credential endorsement = new Credential(resource, endorsementNode); + accumulator.add(subInspector.run(resource, Map.of(ENDORSEMENT_KEY, endorsement))); + } + } + + //finally, run any user-added probes + for(Probe probe : userProbes) { + probeCount++; + accumulator.add(probe.run(crd, ctx)); + } + + } catch (Exception e) { + accumulator.add(onProbeException(Probe.ID.NO_UNCAUGHT_EXCEPTIONS, resource, e)); + } + + return new Report(ctx, new ReportItems(accumulator), probeCount); + } + + /** + * If the AchievementCredential or EndorsementCredential has a “refreshService” property and the type of the + * RefreshService object is “1EdTechCredentialRefresh”, you should fetch the refreshed credential from the URL + * provided, then start the verification process over using the response as input. If the request fails, + * the credential is invalid. + */ + private Optional checkRefreshService(Credential crd, RunContext ctx) { + //TODO + return Optional.empty(); + } + + private static final String REFRESHED = "is.refreshed.credential"; + + private static final JsonPredicateProbeParams obType = JsonPredicateProbeParams.of( + "$.type", Predicates.OB30.TypeProperty.value, Predicates.OB30.TypeProperty.msg, Outcome.FATAL); + + private static final JsonPredicateProbeParams vcType = JsonPredicateProbeParams.of( + "$.type", Predicates.VC.TypeProperty.value, Predicates.VC.TypeProperty.msg, Outcome.FATAL); + + public static class Builder extends VCInspector.Builder { + @SuppressWarnings("unchecked") + @Override + public OB30Inspector build() { + set(Specification.OB30); + set(ResourceType.OPENBADGE); + return new OB30Inspector(this); + } + } + +} \ No newline at end of file diff --git a/inspector-vc/src/main/java/org/oneedtech/inspect/vc/VCInspector.java b/inspector-vc/src/main/java/org/oneedtech/inspect/vc/VCInspector.java new file mode 100644 index 0000000..a07157d --- /dev/null +++ b/inspector-vc/src/main/java/org/oneedtech/inspect/vc/VCInspector.java @@ -0,0 +1,47 @@ +package org.oneedtech.inspect.vc; + +import java.util.ArrayList; +import java.util.List; + +import org.oneedtech.inspect.core.Inspector; +import org.oneedtech.inspect.core.probe.Outcome; +import org.oneedtech.inspect.core.probe.Probe; +import org.oneedtech.inspect.core.probe.RunContext; +import org.oneedtech.inspect.core.report.Report; +import org.oneedtech.inspect.core.report.ReportItems; + +/** + * Abstract base for verifiable credentials inspectors/verifiers. + * @author mgylling + */ +public abstract class VCInspector extends Inspector { + + protected > VCInspector(B builder) { + super(builder); + } + + protected Report abort(RunContext ctx, List accumulator, int probeCount) { + return new Report(ctx, new ReportItems(accumulator), probeCount); + } + + protected boolean broken(List accumulator) { + for(ReportItems items : accumulator) { + if(items.contains(Outcome.FATAL, Outcome.EXCEPTION, Outcome.NOT_RUN)) return true; + } + return false; + } + + public abstract static class Builder> extends Inspector.Builder { + final List> probes; + + public Builder() { + super(); + this.probes = new ArrayList<>(); + } + + public VCInspector.Builder add(Probe probe) { + probes.add(probe); + return this; + } + } +} \ No newline at end of file diff --git a/inspector-vc/src/main/java/org/oneedtech/inspect/vc/probe/CredentialTypeProbe.java b/inspector-vc/src/main/java/org/oneedtech/inspect/vc/probe/CredentialTypeProbe.java new file mode 100644 index 0000000..0017cbe --- /dev/null +++ b/inspector-vc/src/main/java/org/oneedtech/inspect/vc/probe/CredentialTypeProbe.java @@ -0,0 +1,165 @@ +package org.oneedtech.inspect.vc.probe; + +import static java.nio.charset.StandardCharsets.UTF_8; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Base64; +import java.util.Base64.Decoder; +import java.util.List; +import java.util.Optional; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLEventReader; +import javax.xml.stream.events.Attribute; +import javax.xml.stream.events.Characters; +import javax.xml.stream.events.XMLEvent; + +import org.oneedtech.inspect.core.probe.Probe; +import org.oneedtech.inspect.core.probe.RunContext; +import org.oneedtech.inspect.core.report.ReportItems; +import org.oneedtech.inspect.util.resource.Resource; +import org.oneedtech.inspect.util.resource.ResourceType; +import org.oneedtech.inspect.util.resource.detect.TypeDetector; +import org.oneedtech.inspect.util.xml.XMLInputFactoryCache; +import org.oneedtech.inspect.vc.Credential; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.base.Splitter; + +/** + * A probe that verifies that the incoming credential resource is of a recognized type, + * and if so extracts and stores the VC json data (a 'Credential' instance) in the RunContext. + * @author mgylling + */ +public class CredentialTypeProbe extends Probe { + + @Override + public ReportItems run(Resource resource, RunContext context) throws Exception { + + Credential crd = null; + try { + Optional type = TypeDetector.detect(resource, true); + + if(type.isPresent()) { + resource.setType(type.get()); + if(type.get() == ResourceType.PNG) { + crd = new Credential(resource, fromPNG(resource, context)); + } else if(type.get() == ResourceType.SVG) { + crd = new Credential(resource, fromSVG(resource, context)); + } else if(type.get() == ResourceType.JSON) { + crd = new Credential(resource, fromJson(resource, context)); + } else if(type.get() == ResourceType.JWT) { + crd = new Credential(resource, fromJWT(resource, context)); + } + } + + if(crd != null) { + context.addGeneratedObject(crd); + return success(this, context); + } else { + return fatal("Could not detect credential type", context); + } + + } catch (Exception e) { + return fatal("Error while detecting credential type: " + e.getMessage(), context); + } + } + + /** + * Extract the JSON data from a baked PNG credential. + * @param context + * @throws Exception + */ + private JsonNode fromPNG(Resource resource, RunContext context) throws Exception { + //TODO @Miles - note: iTxt chunk is either plain json or jwt + try(InputStream is = resource.asByteSource().openStream()) { + + } + return null; + } + + /** + * Extract the JSON data from a baked SVG credential. + * @param context + * @throws Exception + */ + private JsonNode fromSVG(Resource resource, RunContext context) throws Exception { + String json = null; + try(InputStream is = resource.asByteSource().openStream()) { + XMLEventReader reader = XMLInputFactoryCache.getInstance().createXMLEventReader(is); + while(reader.hasNext()) { + XMLEvent ev = reader.nextEvent(); + if(ev.isStartElement() && ev.asStartElement().getName().equals(OB_CRED_ELEM)) { + Attribute verifyAttr = ev.asStartElement().getAttributeByName(OB_CRED_VERIFY_ATTR); + if(verifyAttr != null) { + json = decodeJWT(verifyAttr.getValue()); + break; + } else { + while(reader.hasNext()) { + ev = reader.nextEvent(); + if(ev.isEndElement() && ev.asEndElement().getName().equals(OB_CRED_ELEM)) { + break; + } + if(ev.getEventType() == XMLEvent.CHARACTERS) { + Characters chars = ev.asCharacters(); + if(!chars.isWhiteSpace()) { + json = chars.getData(); + break; + } + } + } + } + } + if(json!=null) break; + } + } + if(json == null) throw new IllegalArgumentException("No credential inside SVG"); + return fromString(json, context); + } + + /** + * Create a JsonNode object from a raw JSON resource. + * @param context + */ + private JsonNode fromJson(Resource resource, RunContext context) throws Exception { + return fromString(resource.asByteSource().asCharSource(UTF_8).read(), context); + } + + /** + * Create a JsonNode object from a String. + */ + private JsonNode fromString(String json, RunContext context) throws Exception { + return ((ObjectMapper)context.get(RunContext.Key.JACKSON_OBJECTMAPPER)).readTree(json); + } + + /** + * Create a JsonNode object from a JWT resource. + * @param context + */ + private JsonNode fromJWT(Resource resource, RunContext context) throws Exception { + return fromString(decodeJWT(resource.asByteSource().asCharSource(UTF_8).read()), context); + } + + /** + * Decode as per https://www.imsglobal.org/spec/ob/v3p0/#jwt-proof + * @return The decoded JSON String + */ + private String decodeJWT(String jwt) { + List parts = Splitter.on('.').splitToList(jwt); + if(parts.size() != 3) throw new IllegalArgumentException("invalid jwt"); + + final Decoder decoder = Base64.getUrlDecoder(); + String joseHeader = new String(decoder.decode(parts.get(0))); + String jwtPayload = new String(decoder.decode(parts.get(1))); + String jwsSignature = new String(decoder.decode(parts.get(2))); + + //TODO @Miles + + return null; + } + + private static final QName OB_CRED_ELEM = new QName("https://purl.imsglobal.org/ob/v3p0", "credential"); + private static final QName OB_CRED_VERIFY_ATTR = new QName("verify"); +} diff --git a/inspector-vc/src/main/java/org/oneedtech/inspect/vc/probe/ExpirationVerifierProbe.java b/inspector-vc/src/main/java/org/oneedtech/inspect/vc/probe/ExpirationVerifierProbe.java new file mode 100644 index 0000000..d2d5715 --- /dev/null +++ b/inspector-vc/src/main/java/org/oneedtech/inspect/vc/probe/ExpirationVerifierProbe.java @@ -0,0 +1,47 @@ +package org.oneedtech.inspect.vc.probe; + +import java.time.ZonedDateTime; + +import org.oneedtech.inspect.core.probe.Probe; +import org.oneedtech.inspect.core.probe.RunContext; +import org.oneedtech.inspect.core.report.ReportItems; +import org.oneedtech.inspect.vc.Credential; + +import com.fasterxml.jackson.databind.JsonNode; + +/** + * A Probe that verifies a credential's expiration status + * @author mgylling + */ +public class ExpirationVerifierProbe extends Probe { + + public ExpirationVerifierProbe() { + super(ID); + } + + @Override + public ReportItems run(Credential crd, RunContext ctx) throws Exception { + + /* + * If the AchievementCredential or EndorsementCredential has an “expirationDate” property + * and the expiration date is prior to the current date, the credential has expired. + */ + + ZonedDateTime now = ZonedDateTime.now(); + JsonNode node = crd.asJson().get("expirationDate"); + if(node != null) { + ZonedDateTime expirationDate = null; + try { + expirationDate = ZonedDateTime.parse(node.textValue()); + if (now.isAfter(expirationDate)) { + return fatal("The credential has expired (expiration date was " + node.asText() + ").", ctx); + } + } catch (Exception e) { + return exception("Error while checking expirationDate: " + e.getMessage(), ctx.getResource()); + } + } + return success(ctx); + } + + public static final String ID = ExpirationVerifierProbe.class.getSimpleName(); +} diff --git a/inspector-vc/src/main/java/org/oneedtech/inspect/vc/probe/InlineJsonSchemaProbe.java b/inspector-vc/src/main/java/org/oneedtech/inspect/vc/probe/InlineJsonSchemaProbe.java new file mode 100644 index 0000000..01a0e26 --- /dev/null +++ b/inspector-vc/src/main/java/org/oneedtech/inspect/vc/probe/InlineJsonSchemaProbe.java @@ -0,0 +1,71 @@ +package org.oneedtech.inspect.vc.probe; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Optional; +import java.util.Set; + +import org.oneedtech.inspect.core.probe.Probe; +import org.oneedtech.inspect.core.probe.RunContext; +import org.oneedtech.inspect.core.probe.json.JsonSchemaProbe; +import org.oneedtech.inspect.core.report.ReportItems; +import org.oneedtech.inspect.schema.SchemaKey; +import org.oneedtech.inspect.vc.Credential; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; + +/** + * Detect inline schemas in a credential and run them. + * @author mgylling + */ +public class InlineJsonSchemaProbe extends Probe { + private static final Set types = Set.of("1EdTechJsonSchemaValidator2019"); + private final boolean skipCanonical = true; + + public InlineJsonSchemaProbe() { + super(ID); + } + + @Override + public ReportItems run(Credential crd, RunContext ctx) throws Exception { + List accumulator = new ArrayList<>(); + Set ioErrors = new HashSet<>(); + +// JsonPathEvaluator jsonPath = ctx.get(RunContext.Key.JSONPATH_EVALUATOR); +// ArrayNode nodes = jsonPath.eval("$..*[?(@.credentialSchema)]", crd.getJson()); +// note - we dont get deep nested ones in e.g. EndorsementCredential + + JsonNode credentialSchemaNode = crd.asJson().get("credentialSchema"); + if(credentialSchemaNode == null) return success(ctx); + + ArrayNode schemas = (ArrayNode) credentialSchemaNode; //TODO guard this cast + + for(JsonNode schemaNode : schemas) { + JsonNode typeNode = schemaNode.get("type"); + if(typeNode == null || !types.contains(typeNode.asText())) continue; + JsonNode idNode = schemaNode.get("id"); + if(idNode == null) continue; + String id = idNode.asText().strip(); + if(ioErrors.contains(id)) continue; + if(skipCanonical && equals(crd.getSchemaKey(), id)) continue; + try { + accumulator.add(new JsonSchemaProbe(id).run(crd.asJson(), ctx)); + } catch (Exception e) { + if(!ioErrors.contains(id)) { + ioErrors.add(id); + accumulator.add(error("Could not read schema resource " + id, ctx)); + } + } + } + + return new ReportItems(accumulator); + } + + private boolean equals(Optional key, String id) { + return key.isPresent() && key.get().getCanonicalURI().equals(id); + } + + public static final String ID = InlineJsonSchemaProbe.class.getSimpleName(); +} diff --git a/inspector-vc/src/main/java/org/oneedtech/inspect/vc/probe/IssuanceVerifierProbe.java b/inspector-vc/src/main/java/org/oneedtech/inspect/vc/probe/IssuanceVerifierProbe.java new file mode 100644 index 0000000..53875db --- /dev/null +++ b/inspector-vc/src/main/java/org/oneedtech/inspect/vc/probe/IssuanceVerifierProbe.java @@ -0,0 +1,47 @@ +package org.oneedtech.inspect.vc.probe; + +import java.time.ZonedDateTime; + +import org.oneedtech.inspect.core.probe.Probe; +import org.oneedtech.inspect.core.probe.RunContext; +import org.oneedtech.inspect.core.report.ReportItems; +import org.oneedtech.inspect.vc.Credential; + +import com.fasterxml.jackson.databind.JsonNode; + +/** + * A Probe that verifies a credential's issuance status + * @author mgylling + */ +public class IssuanceVerifierProbe extends Probe { + + public IssuanceVerifierProbe() { + super(ID); + } + + @Override + public ReportItems run(Credential crd, RunContext ctx) throws Exception { + + /* + * If the AchievementCredential or EndorsementCredential “issuanceDate” property after + * the current date, the credential is not yet valid. + */ + + ZonedDateTime now = ZonedDateTime.now(); + JsonNode node = crd.asJson().get("issuanceDate"); + if(node != null) { + ZonedDateTime issuanceDate = null; + try { + issuanceDate = ZonedDateTime.parse(node.textValue()); + if (issuanceDate.isAfter(now)) { + return fatal("The credential is not yet valid (issuance date is " + node.asText() + ").", ctx); + } + } catch (Exception e) { + return exception("Error while checking issuanceDate: " + e.getMessage(), ctx.getResource()); + } + } + return success(ctx); + } + + public static final String ID = IssuanceVerifierProbe.class.getSimpleName(); +} diff --git a/inspector-vc/src/main/java/org/oneedtech/inspect/vc/probe/Predicates.java b/inspector-vc/src/main/java/org/oneedtech/inspect/vc/probe/Predicates.java new file mode 100644 index 0000000..e954e36 --- /dev/null +++ b/inspector-vc/src/main/java/org/oneedtech/inspect/vc/probe/Predicates.java @@ -0,0 +1,51 @@ +package org.oneedtech.inspect.vc.probe; + +import static org.oneedtech.inspect.vc.Credential.Type.*; +import static org.oneedtech.inspect.vc.util.JsonNodeUtil.asStringList; + +import java.util.List; +import java.util.function.Predicate; + +import com.fasterxml.jackson.databind.JsonNode; +import com.google.common.base.Joiner; + +//TODO refactor +public class Predicates { + + public static class OB30 { + public static class TypeProperty { + public static final Predicate value = new Predicate<>() { + @Override + public boolean test(JsonNode node) { + List values = asStringList(node); + for(String exp : exp) { + if(values.contains(exp)) return true; + } + return false; + } + }; + private static final List exp = List.of(OpenBadgeCredential.name(), AchievementCredential.name(), VerifiablePresentation.name()); + public static final String msg = "The type property does not contain one of " + Joiner.on(", ").join(exp); + } + } + + public static class VC { + public static class TypeProperty { + public static final Predicate value = new Predicate<>() { + @Override + public boolean test(JsonNode node) { + List values = asStringList(node); + if(values.contains(exp)) return true; + return false; + } + }; + private static final String exp = VerifiableCredential.name(); + public static final String msg = "The type property does not contain " + exp; + } + } + + + + +} + diff --git a/inspector-vc/src/main/java/org/oneedtech/inspect/vc/probe/ProofVerifierProbe.java b/inspector-vc/src/main/java/org/oneedtech/inspect/vc/probe/ProofVerifierProbe.java new file mode 100644 index 0000000..e506aec --- /dev/null +++ b/inspector-vc/src/main/java/org/oneedtech/inspect/vc/probe/ProofVerifierProbe.java @@ -0,0 +1,27 @@ +package org.oneedtech.inspect.vc.probe; + +import org.oneedtech.inspect.core.probe.Probe; +import org.oneedtech.inspect.core.probe.RunContext; +import org.oneedtech.inspect.core.report.ReportItems; +import org.oneedtech.inspect.vc.Credential; + +/** + * A Probe that verifies credential proofs + * @author mlyon + */ +public class ProofVerifierProbe extends Probe { + + public ProofVerifierProbe() { + super(ID); + } + + @Override + public ReportItems run(Credential crd, RunContext ctx) throws Exception { + + //TODO @Miles -- if proofs fail, report OutCome.Fatal + + return success(ctx); + } + + public static final String ID = ProofVerifierProbe.class.getSimpleName(); +} diff --git a/inspector-vc/src/main/java/org/oneedtech/inspect/vc/probe/RevocationListProbe.java b/inspector-vc/src/main/java/org/oneedtech/inspect/vc/probe/RevocationListProbe.java new file mode 100644 index 0000000..d491dc6 --- /dev/null +++ b/inspector-vc/src/main/java/org/oneedtech/inspect/vc/probe/RevocationListProbe.java @@ -0,0 +1,79 @@ +package org.oneedtech.inspect.vc.probe; + +import static org.oneedtech.inspect.core.probe.RunContext.Key.JACKSON_OBJECTMAPPER; + +import java.io.InputStream; +import java.net.URI; +import java.net.URL; +import java.util.List; + +import org.oneedtech.inspect.core.probe.Probe; +import org.oneedtech.inspect.core.probe.RunContext; +import org.oneedtech.inspect.core.report.ReportItems; +import org.oneedtech.inspect.vc.Credential; +import org.oneedtech.inspect.vc.util.JsonNodeUtil; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * A Probe that verifies a credential's revocation status. + * @author mgylling + */ +public class RevocationListProbe extends Probe { + + public RevocationListProbe() { + super(ID); + } + + @Override + public ReportItems run(Credential crd, RunContext ctx) throws Exception { + + /* + * If the AchievementCredential or EndorsementCredential has a “credentialStatus” property + * and the type of the CredentialStatus object is “1EdTechRevocationList”, fetch the + * credential status from the URL provided. If the request is unsuccessful, + * report a warning, not an error. + */ + + JsonNode credentialStatus = crd.asJson().get("credentialStatus"); + if(credentialStatus != null) { + JsonNode type = credentialStatus.get("type"); + if(type != null && type.asText().strip().equals("1EdTechRevocationList")) { + JsonNode listID = credentialStatus.get("id"); + if(listID != null) { + try { + URL url = new URI(listID.asText().strip()).toURL(); + try (InputStream is = url.openStream()) { + JsonNode revocList = ((ObjectMapper)ctx.get(JACKSON_OBJECTMAPPER)).readTree(is.readAllBytes()); + + /* To check if a credential has been revoked, the verifier issues a GET request + * to the URL of the issuer's 1EdTech Revocation List Status Method. If the + * credential's id is in the list of revokedCredentials and the value of + * revoked is true or ommitted, the issuer has revoked the credential. */ + + JsonNode crdID = crd.asJson().get("id"); + if(crdID != null) { + List list = JsonNodeUtil.asNodeList(revocList.get("revokedCredentials")); + if(list != null) { + for(JsonNode item : list) { + JsonNode revID = item.get("id"); + JsonNode revoked = item.get("revoked"); + if(revID != null && revID.equals(crdID) && (revoked == null || revoked.asBoolean())) { + return fatal("Credential has been revoked", ctx); + } + } + } + } + } + } catch (Exception e) { + return warning("Error when fetching credentialStatus resource " + e.getMessage(), ctx); + } + } + } + } + return success(ctx); + } + + public static final String ID = RevocationListProbe.class.getSimpleName(); +} diff --git a/inspector-vc/src/main/java/org/oneedtech/inspect/vc/probe/SignatureVerifierProbe.java b/inspector-vc/src/main/java/org/oneedtech/inspect/vc/probe/SignatureVerifierProbe.java new file mode 100644 index 0000000..d9961fa --- /dev/null +++ b/inspector-vc/src/main/java/org/oneedtech/inspect/vc/probe/SignatureVerifierProbe.java @@ -0,0 +1,28 @@ +package org.oneedtech.inspect.vc.probe; + +import org.oneedtech.inspect.core.probe.Probe; +import org.oneedtech.inspect.core.probe.RunContext; +import org.oneedtech.inspect.core.report.ReportItems; +import org.oneedtech.inspect.vc.Credential; + +/** + * A Probe that verifies credential signatures + * @author mlyon + */ +public class SignatureVerifierProbe extends Probe { + + public SignatureVerifierProbe() { + super(ID); + } + + @Override + public ReportItems run(Credential crd, RunContext ctx) throws Exception { + + //TODO @Miles -- if sigs fail, report OutCome.Fatal + + return success(ctx); + } + + public static final String ID = SignatureVerifierProbe.class.getSimpleName(); + +} \ No newline at end of file diff --git a/inspector-vc/src/main/java/org/oneedtech/inspect/vc/util/JsonNodeUtil.java b/inspector-vc/src/main/java/org/oneedtech/inspect/vc/util/JsonNodeUtil.java new file mode 100644 index 0000000..1d71ed7 --- /dev/null +++ b/inspector-vc/src/main/java/org/oneedtech/inspect/vc/util/JsonNodeUtil.java @@ -0,0 +1,58 @@ +package org.oneedtech.inspect.vc.util; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; + +import org.oneedtech.inspect.core.probe.json.JsonPathEvaluator; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; + +/** + * Node access utilities. + * @author mgylling + */ +public class JsonNodeUtil { + + /** + * Get all embedded endorsement objects as a flat list. + * @return a List that is never null but may be empty. + */ + public static List getEndorsements(JsonNode root, JsonPathEvaluator jsonPath) { + List list = new ArrayList<>(); + ArrayNode endorsements = jsonPath.eval("$..endorsement", root); + for(JsonNode endorsement : endorsements) { + ArrayNode values = (ArrayNode) endorsement; + for(JsonNode value : values) { + list.add(value); + } + } + return list; + } + + public static List asStringList(JsonNode node) { + if(!(node instanceof ArrayNode)) { + return List.of(node.asText()); + } else { + ArrayNode arrayNode = (ArrayNode)node; + return StreamSupport + .stream(arrayNode.spliterator(), false) + .map(n->n.asText().strip()) + .collect(Collectors.toList()); + } + } + + public static List asNodeList(JsonNode node) { + if(node == null) return null; + if(!(node instanceof ArrayNode)) { + return List.of(node); + } else { + ArrayNode arrayNode = (ArrayNode)node; + return StreamSupport + .stream(arrayNode.spliterator(), false) + .collect(Collectors.toList()); + } + } +} diff --git a/inspector-vc/src/test/java/org/oneedtech/inspect/vc/OB30Tests.java b/inspector-vc/src/test/java/org/oneedtech/inspect/vc/OB30Tests.java new file mode 100644 index 0000000..1083aed --- /dev/null +++ b/inspector-vc/src/test/java/org/oneedtech/inspect/vc/OB30Tests.java @@ -0,0 +1,94 @@ +package org.oneedtech.inspect.vc; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.oneedtech.inspect.test.Assertions.*; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.oneedtech.inspect.core.Inspector.Behavior; +import org.oneedtech.inspect.core.report.Report; +import org.oneedtech.inspect.test.PrintHelper; +import org.oneedtech.inspect.vc.probe.InlineJsonSchemaProbe; + + +public class OB30Tests { + private static OB30Inspector validator; + private static boolean verbose = true; + + @BeforeAll + static void setup() { + validator = new OB30Inspector.Builder() + .set(Behavior.TEST_INCLUDE_SUCCESS, true) + .build(); + } + + @Test + void testSimpleJsonValid() { + assertDoesNotThrow(()->{ + Report report = validator.run(Samples.OB30.JSON.SIMPLE_JSON.asFileResource()); + if(verbose) PrintHelper.print(report, true); + assertValid(report); + }); + } + + @Disabled + @Test + void testSimplePNGPlainValid() { + assertDoesNotThrow(()->{ + Report report = validator.run(Samples.OB30.PNG.SIMPLE_JSON_PNG.asFileResource()); + if(verbose) PrintHelper.print(report, true); + assertValid(report); + }); + } + + @Disabled + @Test + void testSimplePNGJWTValid() { + assertDoesNotThrow(()->{ + Report report = validator.run(Samples.OB30.PNG.SIMPLE_JWT_PNG.asFileResource()); + if(verbose) PrintHelper.print(report, true); + assertValid(report); + }); + } + + @Test + void testSimpleJsonSVGPlainValid() { + assertDoesNotThrow(()->{ + Report report = validator.run(Samples.OB30.SVG.SIMPLE_JSON_SVG.asFileResource()); + if(verbose) PrintHelper.print(report, true); + assertValid(report); + }); + } + + @Disabled + @Test + void testSimpleJsonSVGJWTValid() { + assertDoesNotThrow(()->{ + Report report = validator.run(Samples.OB30.SVG.SIMPLE_JWT_SVG.asFileResource()); + if(verbose) PrintHelper.print(report, true); + assertValid(report); + }); + } + + @Test + void testSimpleJsonInvalidUnknownType() { + assertDoesNotThrow(()->{ + Report report = validator.run(Samples.OB30.JSON.SIMPLE_JSON_UNKNOWN_TYPE.asFileResource()); + if(verbose) PrintHelper.print(report, true); + assertInvalid(report); + }); + } + + @Test + void testCompleteJsonInvalidInlineSchemaRef() throws Exception { + assertDoesNotThrow(()->{ + Report report = validator.run(Samples.OB30.JSON.COMPLETE_JSON.asFileResource()); + if(verbose) PrintHelper.print(report, true); + assertInvalid(report); + assertErrorCount(report, 1); + assertHasProbeID(report, InlineJsonSchemaProbe.ID, true); + }); + } + +} diff --git a/inspector-vc/src/test/java/org/oneedtech/inspect/vc/Samples.java b/inspector-vc/src/test/java/org/oneedtech/inspect/vc/Samples.java new file mode 100644 index 0000000..2356c2e --- /dev/null +++ b/inspector-vc/src/test/java/org/oneedtech/inspect/vc/Samples.java @@ -0,0 +1,25 @@ +package org.oneedtech.inspect.vc; + +import org.oneedtech.inspect.test.Sample; + +public class Samples { + + public static final class OB30 { + public static final class SVG { + public final static Sample SIMPLE_JSON_SVG = new Sample("ob30/simple-json.svg", true); + public final static Sample SIMPLE_JWT_SVG = new Sample("ob30/simple-jwt.svg", true); + } + public static final class JSON { + public final static Sample COMPLETE_JSON = new Sample("ob30/complete.json", false); + public final static Sample SIMPLE_JSON = new Sample("ob30/simple.json", true); + public final static Sample SIMPLE_JSON_UNKNOWN_TYPE = new Sample("ob30/simple-unknown-type.json", false); + } + public static final class PNG { + public final static Sample SIMPLE_JWT_PNG = new Sample("ob30/simple-jwt.png", true); + public final static Sample SIMPLE_JSON_PNG = new Sample("ob30/simple-json.png", true); + } + public static final class JWT { + public final static Sample SIMPLE_JWT = new Sample("ob30/simple.jwt", true); + } + } +} diff --git a/inspector-vc/src/test/java/org/oneedtech/inspect/vc/util/JsonNodeUtilTests.java b/inspector-vc/src/test/java/org/oneedtech/inspect/vc/util/JsonNodeUtilTests.java new file mode 100644 index 0000000..909cf89 --- /dev/null +++ b/inspector-vc/src/test/java/org/oneedtech/inspect/vc/util/JsonNodeUtilTests.java @@ -0,0 +1,30 @@ +package org.oneedtech.inspect.vc.util; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.oneedtech.inspect.util.json.ObjectMapperCache.Config.DEFAULT; + +import java.util.List; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.oneedtech.inspect.core.probe.json.JsonPathEvaluator; +import org.oneedtech.inspect.util.json.ObjectMapperCache; +import org.oneedtech.inspect.vc.Samples; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class JsonNodeUtilTests { + static final ObjectMapper mapper = ObjectMapperCache.get(DEFAULT); + static final JsonPathEvaluator jsonPath = new JsonPathEvaluator(mapper); + + + @Test + void getEndorsementsTest() throws Exception { + assertDoesNotThrow(()->{ + JsonNode root = mapper.readTree(Samples.OB30.JSON.COMPLETE_JSON.asBytes()); + List list = JsonNodeUtil.getEndorsements(root, jsonPath); + Assertions.assertEquals(5, list.size()); + }); + } +} diff --git a/inspector-vc/src/test/resources/ob30/complete.json b/inspector-vc/src/test/resources/ob30/complete.json new file mode 100644 index 0000000..92a16e8 --- /dev/null +++ b/inspector-vc/src/test/resources/ob30/complete.json @@ -0,0 +1,712 @@ +{ + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://imsglobal.github.io/openbadges-specification/context.json", + "https://w3id.org/security/suites/ed25519-2020/v1" + ], + "id": "http://1edtech.edu/credentials/3732", + "type": [ + "VerifiableCredential", + "OpenBadgeCredential" + ], + "name": "1EdTech University Degree for Example Student", + "description": "1EdTech University Degree Description", + "image": { + "id": "https://1edtech.edu/credentials/3732/image", + "type": "Image", + "caption": "1EdTech University Degree for Example Student" + }, + "credentialSubject": { + "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", + "type": [ + "AchievementSubject" + ], + "activityEndDate": "2010-01-02T00:00:00Z", + "activityStartDate": "2010-01-01T00:00:00Z", + "creditsEarned": 42, + "licenseNumber": "A-9320041", + "role": "Major Domo", + "source": { + "id": "https://school.edu/issuers/201234", + "type": [ + "Profile" + ], + "name": "1EdTech College of Arts" + }, + "term": "Fall", + "identifier": [ + { + "type": "IdentityObject", + "identityHash": "student@1edtech.edu", + "identityType": "email", + "hashed": false, + "salt": "not-used" + }, + { + "type": "IdentityObject", + "identityHash": "somebody@gmail.com", + "identityType": "email", + "hashed": false, + "salt": "not-used" + } + ], + "achievement": { + "id": "https://1edtech.edu/achievements/degree", + "type": [ + "Achievement" + ], + "alignment": [ + { + "type": [ + "Alignment" + ], + "targetCode": "degree", + "targetDescription": "1EdTech University Degree programs.", + "targetName": "1EdTech University Degree", + "targetFramework": "1EdTech University Program and Course Catalog", + "targetType": "CFItem", + "targetUrl": "https://1edtech.edu/catalog/degree" + }, + { + "type": [ + "Alignment" + ], + "targetCode": "degree", + "targetDescription": "1EdTech University Degree programs.", + "targetName": "1EdTech University Degree", + "targetFramework": "1EdTech University Program and Course Catalog", + "targetType": "CTDL", + "targetUrl": "https://credentialengineregistry.org/resources/ce-98cb027b-95ef-4494-908d-6f7790ec6b6b" + } + ], + "achievementType": "Degree", + "creator": { + "id": "https://1edtech.edu/issuers/565049", + "type": [ + "Profile" + ], + "name": "1EdTech University", + "url": "https://1edtech.edu", + "phone": "1-222-333-4444", + "description": "1EdTech University provides online degree programs.", + "endorsement": [ + { + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://imsglobal.github.io/openbadges-specification/context.json", + "https://w3id.org/security/suites/ed25519-2020/v1" + ], + "type": [ + "VerifiableCredential", + "EndorsementCredential" + ], + "issuer": { + "id": "https://accrediter.edu/issuers/565049", + "type": [ + "Profile" + ], + "name": "Example Accrediting Agency" + }, + "issuanceDate": "2010-01-01T00:00:00Z", + "expirationDate": "2020-01-01T00:00:00Z", + "credentialSubject": { + "id": "https://1edtech.edu/issuers/565049", + "type": [ + "EndorsementSubject" + ], + "endorsementComment": "1EdTech University is in good standing" + }, + "credentialSchema": [ + { + "id": "https://purl.imsglobal.org/spec/ob/v3p0/schema/endorsementcredential.json", + "type": "1EdTechJsonSchemaValidator2019" + }, + { + "id": "https://accrediter.edu/schema/endorsementcredential.json", + "type": "JsonSchemaValidator2018" + } + ], + "credentialStatus": { + "id": "https://1edtech.edu/credentials/3732/revocations", + "type": "1EdTechRevocationList" + }, + "refreshService": { + "id": "http://1edtech.edu/credentials/3732", + "type": "1EdTechCredentialRefresh" + }, + "proof": [ + { + "type": "Ed25519Signature2020", + "created": "2022-05-26T18:17:08Z", + "verificationMethod": "https://accrediter.edu/issuers/565049#key-1", + "proofPurpose": "assertionMethod", + "proofValue": "zvPkQiUFfJrgnCRhyPkTSkgrGXbnLR15pHH5HZVYNdM4TCAwQHqG7fMeMPLtYNRnEgoV1aJdR5E61eWu5sWRYgtA" + } + ] + }, + { + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://imsglobal.github.io/openbadges-specification/context.json", + "https://w3id.org/security/suites/ed25519-2020/v1" + ], + "type": [ + "VerifiableCredential", + "EndorsementCredential" + ], + "issuer": { + "id": "https://state.gov/issuers/565049", + "type": [ + "Profile" + ], + "name": "State Department of Education" + }, + "issuanceDate": "2010-01-01T00:00:00Z", + "expirationDate": "2020-01-01T00:00:00Z", + "credentialSubject": { + "id": "https://1edtech.edu/issuers/565049", + "type": [ + "EndorsementSubject" + ], + "endorsementComment": "1EdTech University is in good standing" + }, + "credentialSchema": [ + { + "id": "https://purl.imsglobal.org/spec/ob/v3p0/schema/endorsementcredential.json", + "type": "1EdTechJsonSchemaValidator2019" + }, + { + "id": "https://state.gov/schema/endorsementcredential.json", + "type": "JsonSchemaValidator2018" + } + ], + "credentialStatus": { + "id": "https://state.gov/credentials/3732/revocations", + "type": "1EdTechRevocationList" + }, + "refreshService": { + "id": "http://state.gov/credentials/3732", + "type": "1EdTechCredentialRefresh" + }, + "proof": [ + { + "type": "Ed25519Signature2020", + "created": "2022-05-26T18:25:59Z", + "verificationMethod": "https://accrediter.edu/issuers/565049#key-1", + "proofPurpose": "assertionMethod", + "proofValue": "z5bDnmSgDczXwZGya6ZjxKaxkdKxzsCMiVSsgEVWxnaWK7ZqbKnzcCd7mUKE9DQaAL2QMXP5AquPeW6W2CWrZ7jNC" + } + ] + } + ], + "image": { + "id": "https://1edtech.edu/logo.png", + "type": "Image", + "caption": "1EdTech University logo" + }, + "email": "registrar@1edtech.edu", + "address": { + "type": [ + "Address" + ], + "addressCountry": "USA", + "addressCountryCode": "US", + "addressRegion": "TX", + "addressLocality": "Austin", + "streetAddress": "123 First St", + "postOfficeBoxNumber": "1", + "postalCode": "12345", + "geo": { + "type": "GeoCoordinates", + "latitude": 1, + "longitude": 1 + } + }, + "otherIdentifier": [ + { + "type": "IdentifierEntry", + "identifier": "12345", + "identifierType": "sourcedId" + }, + { + "type": "IdentifierEntry", + "identifier": "67890", + "identifierType": "nationalIdentityNumber" + } + ], + "official": "Horace Mann", + "parentOrg": { + "id": "did:example:123456789", + "type": [ + "Profile" + ], + "name": "Universal Universities" + } + }, + "creditsAvailable": 36, + "criteria": { + "id": "https://1edtech.edu/achievements/degree", + "narrative": "# Degree Requirements\nStudents must complete..." + }, + "description": "1EdTech University Degree Description", + "endorsement": [ + { + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://imsglobal.github.io/openbadges-specification/context.json", + "https://w3id.org/security/suites/ed25519-2020/v1" + ], + "type": [ + "VerifiableCredential", + "EndorsementCredential" + ], + "issuer": { + "id": "https://accrediter.edu/issuers/565049", + "type": [ + "Profile" + ], + "name": "Example Accrediting Agency" + }, + "issuanceDate": "2010-01-01T00:00:00Z", + "expirationDate": "2020-01-01T00:00:00Z", + "credentialSubject": { + "id": "https://1edtech.edu/issuers/565049", + "type": [ + "EndorsementSubject" + ], + "endorsementComment": "1EdTech University is in good standing" + }, + "credentialSchema": [ + { + "id": "https://purl.imsglobal.org/spec/ob/v3p0/schema/endorsementcredential.json", + "type": "1EdTechJsonSchemaValidator2019" + }, + { + "id": "https://accrediter.edu/schema/endorsementcredential.json", + "type": "JsonSchemaValidator2018" + } + ], + "credentialStatus": { + "id": "https://1edtech.edu/credentials/3732/revocations", + "type": "1EdTechRevocationList" + }, + "refreshService": { + "id": "http://1edtech.edu/credentials/3732", + "type": "1EdTechCredentialRefresh" + }, + "proof": [ + { + "type": "Ed25519Signature2020", + "created": "2022-05-26T18:17:08Z", + "verificationMethod": "https://accrediter.edu/issuers/565049#key-1", + "proofPurpose": "assertionMethod", + "proofValue": "zvPkQiUFfJrgnCRhyPkTSkgrGXbnLR15pHH5HZVYNdM4TCAwQHqG7fMeMPLtYNRnEgoV1aJdR5E61eWu5sWRYgtA" + } + ] + } + ], + "fieldOfStudy": "Research", + "humanCode": "R1", + "image": { + "id": "https://1edtech.edu/achievements/degree/image", + "type": "Image", + "caption": "1EdTech University Degree" + }, + "name": "1EdTech University Degree", + "otherIdentifier": [ + { + "type": "IdentifierEntry", + "identifier": "abde", + "identifierType": "identifier" + } + ], + "resultDescription": [ + { + "id": "urn:uuid:f6ab24cd-86e8-4eaf-b8c6-ded74e8fd41c", + "type": [ + "ResultDescription" + ], + "alignment": [ + { + "type": [ + "Alignment" + ], + "targetCode": "project", + "targetDescription": "Project description", + "targetName": "Final Project", + "targetFramework": "1EdTech University Program and Course Catalog", + "targetType": "CFItem", + "targetUrl": "https://1edtech.edu/catalog/degree/project" + } + ], + "allowedValue": [ + "D", + "C", + "B", + "A" + ], + "name": "Final Project Grade", + "requiredValue": "C", + "resultType": "LetterGrade" + }, + { + "id": "urn:uuid:a70ddc6a-4c4a-4bd8-8277-cb97c79f40c5", + "type": [ + "ResultDescription" + ], + "alignment": [ + { + "type": [ + "Alignment" + ], + "targetCode": "project", + "targetDescription": "Project description", + "targetName": "Final Project", + "targetFramework": "1EdTech University Program and Course Catalog", + "targetType": "CFItem", + "targetUrl": "https://1edtech.edu/catalog/degree/project" + } + ], + "allowedValue": [ + "D", + "C", + "B", + "A" + ], + "name": "Final Project Grade", + "requiredLevel": "urn:uuid:d05a0867-d0ad-4b03-bdb5-28fb5d2aab7a", + "resultType": "RubricCriterionLevel", + "rubricCriterionLevel": [ + { + "id": "urn:uuid:d05a0867-d0ad-4b03-bdb5-28fb5d2aab7a", + "type": [ + "RubricCriterionLevel" + ], + "alignment": [ + { + "type": [ + "Alignment" + ], + "targetCode": "project", + "targetDescription": "Project description", + "targetName": "Final Project", + "targetFramework": "1EdTech University Program and Course Catalog", + "targetType": "CFRubricCriterionLevel", + "targetUrl": "https://1edtech.edu/catalog/degree/project/rubric/levels/mastered" + } + ], + "description": "The author demonstrated...", + "level": "Mastered", + "name": "Mastery", + "points": "4" + }, + { + "id": "urn:uuid:6b84b429-31ee-4dac-9d20-e5c55881f80e", + "type": [ + "RubricCriterionLevel" + ], + "alignment": [ + { + "type": [ + "Alignment" + ], + "targetCode": "project", + "targetDescription": "Project description", + "targetName": "Final Project", + "targetFramework": "1EdTech University Program and Course Catalog", + "targetType": "CFRubricCriterionLevel", + "targetUrl": "https://1edtech.edu/catalog/degree/project/rubric/levels/basic" + } + ], + "description": "The author demonstrated...", + "level": "Basic", + "name": "Basic", + "points": "4" + } + ] + }, + { + "id": "urn:uuid:b07c0387-f2d6-4b65-a3f4-f4e4302ea8f7", + "type": [ + "ResultDescription" + ], + "name": "Project Status", + "resultType": "Status" + } + ], + "specialization": "Computer Science Research", + "tag": [ + "research", + "computer science" + ] + }, + "image": { + "id": "https://1edtech.edu/credentials/3732/image", + "type": "Image", + "caption": "1EdTech University Degree for Example Student" + }, + "narrative": "There is a final project report and source code evidence.", + "result": [ + { + "type": [ + "Result" + ], + "alignment": [ + { + "type": [ + "Alignment" + ], + "targetCode": "project", + "targetDescription": "Project description", + "targetName": "Final Project", + "targetFramework": "1EdTech University Program and Course Catalog", + "targetType": "CFItem", + "targetUrl": "https://1edtech.edu/catalog/degree/project/result/1" + } + ], + "resultDescription": "urn:uuid:f6ab24cd-86e8-4eaf-b8c6-ded74e8fd41c", + "value": "A" + }, + { + "type": [ + "Result" + ], + "achievedLevel": "urn:uuid:d05a0867-d0ad-4b03-bdb5-28fb5d2aab7a", + "alignment": [ + { + "type": [ + "Alignment" + ], + "targetCode": "project", + "targetDescription": "Project description", + "targetName": "Final Project", + "targetFramework": "1EdTech University Program and Course Catalog", + "targetType": "CFItem", + "targetUrl": "https://1edtech.edu/catalog/degree/project/result/1" + } + ], + "resultDescription": "urn:uuid:f6ab24cd-86e8-4eaf-b8c6-ded74e8fd41c" + }, + { + "type": [ + "Result" + ], + "resultDescription": "urn:uuid:f6ab24cd-86e8-4eaf-b8c6-ded74e8fd41c", + "status": "Completed" + } + ] + }, + "endorsement": [ + { + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://imsglobal.github.io/openbadges-specification/context.json", + "https://w3id.org/security/suites/ed25519-2020/v1" + ], + "type": [ + "VerifiableCredential", + "EndorsementCredential" + ], + "issuer": { + "id": "https://accrediter.edu/issuers/565049", + "type": [ + "Profile" + ], + "name": "Example Accrediting Agency" + }, + "issuanceDate": "2010-01-01T00:00:00Z", + "expirationDate": "2020-01-01T00:00:00Z", + "credentialSubject": { + "id": "https://1edtech.edu/issuers/565049", + "type": [ + "EndorsementSubject" + ], + "endorsementComment": "1EdTech University is in good standing" + }, + "credentialSchema": [ + { + "id": "https://purl.imsglobal.org/spec/ob/v3p0/schema/endorsementcredential.json", + "type": "1EdTechJsonSchemaValidator2019" + }, + { + "id": "https://accrediter.edu/schema/endorsementcredential.json", + "type": "JsonSchemaValidator2018" + } + ], + "credentialStatus": { + "id": "https://1edtech.edu/credentials/3732/revocations", + "type": "1EdTechRevocationList" + }, + "refreshService": { + "id": "http://1edtech.edu/credentials/3732", + "type": "1EdTechCredentialRefresh" + }, + "proof": [ + { + "type": "Ed25519Signature2020", + "created": "2022-05-26T18:17:08Z", + "verificationMethod": "https://accrediter.edu/issuers/565049#key-1", + "proofPurpose": "assertionMethod", + "proofValue": "zvPkQiUFfJrgnCRhyPkTSkgrGXbnLR15pHH5HZVYNdM4TCAwQHqG7fMeMPLtYNRnEgoV1aJdR5E61eWu5sWRYgtA" + } + ] + } + ], + "evidence": [ + { + "id": "https://1edtech.edu/credentials/3732/evidence/1", + "type": [ + "Evidence" + ], + "narrative": "# Final Project Report \n This project was ...", + "name": "Final Project Report", + "description": "This is the final project report.", + "genre": "Research", + "audience": "Department" + }, + { + "id": "https://github.com/somebody/project", + "type": [ + "Evidence" + ], + "name": "Final Project Code", + "description": "This is the source code for the final project app.", + "genre": "Research", + "audience": "Department" + } + ], + "issuer": { + "id": "https://1edtech.edu/issuers/565049", + "type": [ + "Profile" + ], + "name": "1EdTech University", + "url": "https://1edtech.edu", + "phone": "1-222-333-4444", + "description": "1EdTech University provides online degree programs.", + "endorsement": [ + { + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://imsglobal.github.io/openbadges-specification/context.json", + "https://w3id.org/security/suites/ed25519-2020/v1" + ], + "type": [ + "VerifiableCredential", + "EndorsementCredential" + ], + "issuer": { + "id": "https://accrediter.edu/issuers/565049", + "type": [ + "Profile" + ], + "name": "Example Accrediting Agency" + }, + "issuanceDate": "2010-01-01T00:00:00Z", + "expirationDate": "2020-01-01T00:00:00Z", + "credentialSubject": { + "id": "https://1edtech.edu/issuers/565049", + "type": [ + "EndorsementSubject" + ], + "endorsementComment": "1EdTech University is in good standing" + }, + "credentialSchema": [ + { + "id": "https://purl.imsglobal.org/spec/ob/v3p0/schema/endorsementcredential.json", + "type": "1EdTechJsonSchemaValidator2019" + }, + { + "id": "https://accrediter.edu/schema/endorsementcredential.json", + "type": "JsonSchemaValidator2018" + } + ], + "credentialStatus": { + "id": "https://1edtech.edu/credentials/3732/revocations", + "type": "1EdTechRevocationList" + }, + "refreshService": { + "id": "http://1edtech.edu/credentials/3732", + "type": "1EdTechCredentialRefresh" + }, + "proof": [ + { + "type": "Ed25519Signature2020", + "created": "2022-05-26T18:17:08Z", + "verificationMethod": "https://accrediter.edu/issuers/565049#key-1", + "proofPurpose": "assertionMethod", + "proofValue": "zvPkQiUFfJrgnCRhyPkTSkgrGXbnLR15pHH5HZVYNdM4TCAwQHqG7fMeMPLtYNRnEgoV1aJdR5E61eWu5sWRYgtA" + } + ] + } + ], + "image": { + "id": "https://1edtech.edu/logo.png", + "type": "Image", + "caption": "1EdTech University logo" + }, + "email": "registrar@1edtech.edu", + "address": { + "type": [ + "Address" + ], + "addressCountry": "USA", + "addressCountryCode": "US", + "addressRegion": "TX", + "addressLocality": "Austin", + "streetAddress": "123 First St", + "postOfficeBoxNumber": "1", + "postalCode": "12345", + "geo": { + "type": "GeoCoordinates", + "latitude": 1, + "longitude": 1 + } + }, + "otherIdentifier": [ + { + "type": "IdentifierEntry", + "identifier": "12345", + "identifierType": "sourcedId" + }, + { + "type": "IdentifierEntry", + "identifier": "67890", + "identifierType": "nationalIdentityNumber" + } + ], + "official": "Horace Mann", + "parentOrg": { + "id": "did:example:123456789", + "type": [ + "Profile" + ], + "name": "Universal Universities" + } + }, + "issuanceDate": "2010-01-01T00:00:00Z", + "expirationDate": "2020-01-01T00:00:00Z", + "credentialSchema": [ + { + "id": "https://purl.imsglobal.org/spec/ob/v3p0/schema/achievementcredential.json", + "type": "1EdTechJsonSchemaValidator2019" + } + ], + "credentialStatus": { + "id": "https://1edtech.edu/credentials/3732/revocations", + "type": "1EdTechRevocationList" + }, + "refreshService": { + "id": "http://1edtech.edu/credentials/3732", + "type": "1EdTechCredentialRefresh" + }, + "proof": [ + { + "type": "Ed25519Signature2020", + "created": "2022-06-09T22:56:28Z", + "verificationMethod": "https://1edtech.edu/issuers/565049#key-1", + "proofPurpose": "assertionMethod", + "proofValue": "zPpg92pBBEqRMxAqHMFQJ6Kmwf1thF9GdzqCofyWTLE6AhuahQixBNuG9BLgk6vb8K3NoqzanajYYYJbEcEhvQtM" + } + ] +} \ No newline at end of file diff --git a/inspector-vc/src/test/resources/ob30/simple-json.png b/inspector-vc/src/test/resources/ob30/simple-json.png new file mode 100644 index 0000000000000000000000000000000000000000..b424db95afd9a5d935c8b9a128c7f78b2b88dd75 GIT binary patch literal 83758 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 + + + + + { + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://imsglobal.github.io/openbadges-specification/context.json", + "https://w3id.org/security/suites/ed25519-2020/v1" + ], + "id": "http://example.edu/credentials/3732", + "type": [ + "VerifiableCredential", + "OpenBadgeCredential" + ], + "issuer": { + "id": "https://example.edu/issuers/565049", + "type": [ + "Profile" + ], + "name": "Example University" + }, + "issuanceDate": "2010-01-01T00:00:00Z", + "name": "Example University Degree", + "credentialSubject": { + "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", + "type": [ + "AchievementSubject" + ] + }, + "proof": [ + { + "type": "Ed25519Signature2020", + "created": "2022-06-09T22:56:28Z", + "verificationMethod": "https://example.edu/issuers/565049#key-1", + "proofPurpose": "assertionMethod", + "proofValue": "z58ieJCh4kN6eE2Vq4TyYURKSC4hWWEK7b75NNUL2taZMhKqwTteuByG1wRoGDdCqqNLW5Gq1diUi4qyZ63tQRtyN" + } + ] + } + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/inspector-vc/src/test/resources/ob30/simple-jwt.png b/inspector-vc/src/test/resources/ob30/simple-jwt.png new file mode 100644 index 0000000000000000000000000000000000000000..47e5afc81c95f18cdf6c6f99dcb22a541e147c9b GIT binary patch literal 83939 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 literal 0 HcmV?d00001 diff --git a/inspector-vc/src/test/resources/ob30/simple-jwt.svg b/inspector-vc/src/test/resources/ob30/simple-jwt.svg new file mode 100644 index 0000000..8fb9094 --- /dev/null +++ b/inspector-vc/src/test/resources/ob30/simple-jwt.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/inspector-vc/src/test/resources/ob30/simple-unknown-type.json b/inspector-vc/src/test/resources/ob30/simple-unknown-type.json new file mode 100644 index 0000000..a54f5c1 --- /dev/null +++ b/inspector-vc/src/test/resources/ob30/simple-unknown-type.json @@ -0,0 +1,36 @@ +{ + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://imsglobal.github.io/openbadges-specification/context.json", + "https://w3id.org/security/suites/ed25519-2020/v1" + ], + "id": "http://example.edu/credentials/3732", + "type": [ + "VerifiableCredential", + "OtherCredential" + ], + "issuer": { + "id": "https://example.edu/issuers/565049", + "type": [ + "Profile" + ], + "name": "Example University" + }, + "issuanceDate": "2010-01-01T00:00:00Z", + "name": "Example University Degree", + "credentialSubject": { + "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", + "type": [ + "AchievementSubject" + ] + }, + "proof": [ + { + "type": "Ed25519Signature2020", + "created": "2022-06-09T22:56:28Z", + "verificationMethod": "https://example.edu/issuers/565049#key-1", + "proofPurpose": "assertionMethod", + "proofValue": "z58ieJCh4kN6eE2Vq4TyYURKSC4hWWEK7b75NNUL2taZMhKqwTteuByG1wRoGDdCqqNLW5Gq1diUi4qyZ63tQRtyN" + } + ] + } \ No newline at end of file diff --git a/inspector-vc/src/test/resources/ob30/simple.json b/inspector-vc/src/test/resources/ob30/simple.json new file mode 100644 index 0000000..cdfffdb --- /dev/null +++ b/inspector-vc/src/test/resources/ob30/simple.json @@ -0,0 +1,36 @@ +{ + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://imsglobal.github.io/openbadges-specification/context.json", + "https://w3id.org/security/suites/ed25519-2020/v1" + ], + "id": "http://example.edu/credentials/3732", + "type": [ + "VerifiableCredential", + "OpenBadgeCredential" + ], + "issuer": { + "id": "https://example.edu/issuers/565049", + "type": [ + "Profile" + ], + "name": "Example University" + }, + "issuanceDate": "2010-01-01T00:00:00Z", + "name": "Example University Degree", + "credentialSubject": { + "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", + "type": [ + "AchievementSubject" + ] + }, + "proof": [ + { + "type": "Ed25519Signature2020", + "created": "2022-06-09T22:56:28Z", + "verificationMethod": "https://example.edu/issuers/565049#key-1", + "proofPurpose": "assertionMethod", + "proofValue": "z58ieJCh4kN6eE2Vq4TyYURKSC4hWWEK7b75NNUL2taZMhKqwTteuByG1wRoGDdCqqNLW5Gq1diUi4qyZ63tQRtyN" + } + ] + } \ No newline at end of file diff --git a/inspector-vc/src/test/resources/ob30/simple.jwt b/inspector-vc/src/test/resources/ob30/simple.jwt new file mode 100644 index 0000000..6f64aad --- /dev/null +++ b/inspector-vc/src/test/resources/ob30/simple.jwt @@ -0,0 +1 @@ +eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vaW1zZ2xvYmFsLmdpdGh1Yi5pby9vcGVuYmFkZ2VzLXNwZWNpZmljYXRpb24vY29udGV4dC5qc29uIl0sImlkIjoiaHR0cDovL2V4YW1wbGUuZWR1L2NyZWRlbnRpYWxzLzM3MzIiLCJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIiwiT3BlbkJhZGdlQ3JlZGVudGlhbCJdLCJpc3N1ZXIiOnsiaWQiOiJodHRwczovL2V4YW1wbGUuZWR1L2lzc3VlcnMvNTY1MDQ5IiwidHlwZSI6WyJQcm9maWxlIl0sIm5hbWUiOiJFeGFtcGxlIFVuaXZlcnNpdHkifSwiaXNzdWFuY2VEYXRlIjoiMjAxMC0wMS0wMVQwMDowMDowMFoiLCJuYW1lIjoiRXhhbXBsZSBVbml2ZXJzaXR5IERlZ3JlZSIsImNyZWRlbnRpYWxTdWJqZWN0Ijp7ImlkIjoiZGlkOmV4YW1wbGU6ZWJmZWIxZjcxMmViYzZmMWMyNzZlMTJlYzIxIiwidHlwZSI6WyJBY2hpZXZlbWVudFN1YmplY3QiXX19LCJpc3MiOiJodHRwczovL2V4YW1wbGUuZWR1L2lzc3VlcnMvNTY1MDQ5IiwibmJmIjoxMjYyMzA0MDAwLCJqdGkiOiJodHRwOi8vZXhhbXBsZS5lZHUvY3JlZGVudGlhbHMvMzczMiIsInN1YiI6ImRpZDpleGFtcGxlOmViZmViMWY3MTJlYmM2ZjFjMjc2ZTEyZWMyMSJ9.G7W8od9rSZRsVyk26rXjg_fH2CyUihwNpepd6tWgLt_UHC1vUU0Clox8IicnOSkMyYEqAuNZAdCC9_35i1oUcyj1c076Aa0dsVQ2fFVuQPqXBlyZWcBmo5jqOK6R9NHzRAYXwLRXgrB8gz3lSK55cnHTnMtkpXXcUcHkS5ylWbXCLeOWKoygOCuxRN3N6kP-0HOyuk15PWlnkJ2zEKz2pBtVPaNEydcT0kEtoHFMEWVwqo6rnGV-Ea3M7ssDt3145mcl-DVYLXmBVdT8KoO47QAOBaVMR6k-hgrHNBcdhpI-o6IvLIFsGLgrNvWN67i8Z7Baum1mP-HBpsAigdmIpA \ No newline at end of file