Merge pull request #3 from 1EdTech/feature/vcdm-2.0

Feature/vcdm 2.0
This commit is contained in:
Xavi Aracil 2024-03-22 09:49:43 +01:00 committed by GitHub
commit 08d74d287d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
48 changed files with 1794 additions and 1262 deletions

View File

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>org.1edtech</groupId> <groupId>org.1edtech</groupId>
<artifactId>vc-public-validator</artifactId> <artifactId>vc-public-validator</artifactId>
<version>1.0.4</version> <version>1.0.5</version>
</parent> </parent>
<artifactId>inspector-vc-web</artifactId> <artifactId>inspector-vc-web</artifactId>
<properties> <properties>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>org.1edtech</groupId> <groupId>org.1edtech</groupId>
<artifactId>vc-public-validator</artifactId> <artifactId>vc-public-validator</artifactId>
<version>1.0.4</version> <version>1.0.5</version>
</parent> </parent>
<artifactId>inspector-vc</artifactId> <artifactId>inspector-vc</artifactId>
<dependencies> <dependencies>

View File

@ -5,34 +5,42 @@ import static org.oneedtech.inspect.vc.VerifiableCredential.Type.ClrCredential;
import static org.oneedtech.inspect.vc.VerifiableCredential.Type.EndorsementCredential; import static org.oneedtech.inspect.vc.VerifiableCredential.Type.EndorsementCredential;
import static org.oneedtech.inspect.vc.VerifiableCredential.Type.VerifiablePresentation; import static org.oneedtech.inspect.vc.VerifiableCredential.Type.VerifiablePresentation;
import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableMap;
import java.net.URI;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import org.oneedtech.inspect.schema.Catalog; import org.oneedtech.inspect.schema.Catalog;
import org.oneedtech.inspect.schema.SchemaKey; import org.oneedtech.inspect.schema.SchemaKey;
import org.oneedtech.inspect.util.resource.MimeType; import org.oneedtech.inspect.util.resource.MimeType;
import org.oneedtech.inspect.util.resource.Resource; import org.oneedtech.inspect.util.resource.Resource;
import org.oneedtech.inspect.vc.util.JsonNodeUtil; import org.oneedtech.inspect.vc.util.JsonNodeUtil;
import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableMap;
/** /**
* A wrapper object for a verifiable credential. This contains e.g. the origin resource * A wrapper object for a verifiable credential. This contains e.g. the origin resource and the
* and the extracted JSON data plus any other stuff Probes need. * extracted JSON data plus any other stuff Probes need.
*
* @author mgylling * @author mgylling
*/ */
public class VerifiableCredential extends Credential { public class VerifiableCredential extends Credential {
final VerifiableCredential.Type credentialType; final VerifiableCredential.Type credentialType;
final VCVersion version;
protected VerifiableCredential(Resource resource, JsonNode data, String jwt, Map<CredentialEnum, SchemaKey> schemas, String issuedOnPropertyName, String expiresAtPropertyName) { protected VerifiableCredential(
super(ID, resource, data, jwt, schemas, issuedOnPropertyName, expiresAtPropertyName); Resource resource,
JsonNode data,
String jwt,
Map<CredentialEnum, SchemaKey> schemas,
VCVersion version) {
super(ID, resource, data, jwt, schemas, version.issuanceDateField, version.expirationDateField);
JsonNode typeNode = jsonData.get("type"); JsonNode typeNode = jsonData.get("type");
this.credentialType = VerifiableCredential.Type.valueOf(typeNode); this.credentialType = VerifiableCredential.Type.valueOf(typeNode);
this.version = version;
} }
public CredentialEnum getCredentialType() { public CredentialEnum getCredentialType() {
@ -43,43 +51,73 @@ public class VerifiableCredential extends Credential {
return jwt == null ? ProofType.EMBEDDED : ProofType.EXTERNAL; return jwt == null ? ProofType.EMBEDDED : ProofType.EXTERNAL;
} }
private static final Map<CredentialEnum, SchemaKey> schemas = new ImmutableMap.Builder<CredentialEnum, SchemaKey>() public VCVersion getVersion() {
.put(AchievementCredential, Catalog.OB_30_ACHIEVEMENTCREDENTIAL_JSON) return version;
.put(ClrCredential, Catalog.CLR_20_CLRCREDENTIAL_JSON) }
.put(VerifiablePresentation, Catalog.CLR_20_CLRCREDENTIAL_JSON)
.put(EndorsementCredential, Catalog.OB_30_ENDORSEMENTCREDENTIAL_JSON) private static final Map<CredentialEnum, SchemaKey> schemas =
new ImmutableMap.Builder<CredentialEnum, SchemaKey>()
.put(AchievementCredential, Catalog.OB_30_ANY_ACHIEVEMENTCREDENTIAL_JSON)
.put(ClrCredential, Catalog.CLR_20_ANY_CLRCREDENTIAL_JSON)
.put(VerifiablePresentation, Catalog.CLR_20_ANY_CLRCREDENTIAL_JSON)
.put(EndorsementCredential, Catalog.OB_30_ANY_ENDORSEMENTCREDENTIAL_JSON)
.build(); .build();
private static final Map<Set<VerifiableCredential.Type>, List<String>> contextMap = new ImmutableMap.Builder<Set<VerifiableCredential.Type>, List<String>>() public static final String JSONLD_CONTEXT_W3C_CREDENTIALS_V2 = "https://www.w3.org/ns/credentials/v2";
.put(Set.of(Type.OpenBadgeCredential, AchievementCredential, EndorsementCredential),
List.of("https://www.w3.org/2018/credentials/v1", private static final Map<Set<VerifiableCredential.Type>, List<String>> contextMap =
new ImmutableMap.Builder<Set<VerifiableCredential.Type>, List<String>>()
.put(
Set.of(Type.OpenBadgeCredential, AchievementCredential, EndorsementCredential),
List.of(
JSONLD_CONTEXT_W3C_CREDENTIALS_V2,
"https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json"))
.put(
Set.of(ClrCredential),
List.of(
JSONLD_CONTEXT_W3C_CREDENTIALS_V2,
"https://purl.imsglobal.org/spec/clr/v2p0/context-2.0.1.json",
"https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json"))
.build();
private static final Map<String, List<String>> contextAliasesMap =
new ImmutableMap.Builder<String, List<String>>()
.put(
"https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json",
List.of(
"https://purl.imsglobal.org/spec/ob/v3p0/context/ob_v3p0.jsonld",
"https://purl.imsglobal.org/spec/ob/v3p0/context.json")) "https://purl.imsglobal.org/spec/ob/v3p0/context.json"))
.put(Set.of(ClrCredential), .put(
List.of("https://www.w3.org/2018/credentials/v1", "https://purl.imsglobal.org/spec/clr/v2p0/context-2.0.1.json",
"https://purl.imsglobal.org/spec/clr/v2p0/context.json", List.of("https://purl.imsglobal.org/spec/clr/v2p0/context.json"))
"https://purl.imsglobal.org/spec/ob/v3p0/context.json")) .put(
JSONLD_CONTEXT_W3C_CREDENTIALS_V2,
List.of("https://www.w3.org/2018/credentials/v1"))
.build(); .build();
private static final Map<String, List<String>> contextAliasesMap = new ImmutableMap.Builder<String, List<String>>() private static final Map<String, List<String>> contextVersioningPatternMap =
.put("https://purl.imsglobal.org/spec/ob/v3p0/context.json", new ImmutableMap.Builder<String, List<String>>()
List.of("https://purl.imsglobal.org/spec/ob/v3p0/context/ob_v3p0.jsonld")) .put(
.build(); "https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json",
List.of(
private static final Map<String, List<String>> contextVersioningPatternMap = new ImmutableMap.Builder<String, List<String>>() "https:\\/\\/purl\\.imsglobal\\.org\\/spec\\/ob\\/v3p0\\/context(-\\d+\\.\\d+\\.\\d+)*\\.json"))
.put("https://purl.imsglobal.org/spec/ob/v3p0/context.json", .put(
List.of("https:\\/\\/purl\\.imsglobal\\.org\\/spec\\/ob\\/v3p0\\/context(-\\d+\\.\\d+\\.\\d+)*\\.json")) "https://purl.imsglobal.org/spec/clr/v2p0/context-2.0.1.json",
.put("https://purl.imsglobal.org/spec/clr/v2p0/context.json", List.of(
List.of("https:\\/\\/purl\\.imsglobal\\.org\\/spec\\/clr\\/v2p0\\/context(-\\d+\\.\\d+\\.\\d+)*\\.json")) "https:\\/\\/purl\\.imsglobal\\.org\\/spec\\/clr\\/v2p0\\/context(-\\d+\\.\\d+\\.\\d+)*\\.json"))
.build(); .build();
public enum Type implements CredentialEnum { public enum Type implements CredentialEnum {
AchievementCredential(Collections.emptyList()), AchievementCredential(Collections.emptyList()),
OpenBadgeCredential(List.of("OpenBadgeCredential", "AchievementCredential")), //treated as an alias of AchievementCredential OpenBadgeCredential(
List.of(
"OpenBadgeCredential",
"AchievementCredential")), // treated as an alias of AchievementCredential
ClrCredential(List.of("ClrCredential")), ClrCredential(List.of("ClrCredential")),
EndorsementCredential(List.of("EndorsementCredential")), EndorsementCredential(List.of("EndorsementCredential")),
VerifiablePresentation(Collections.emptyList()), VerifiablePresentation(Collections.emptyList()),
VerifiableCredential(List.of("VerifiableCredential")), //this is an underspecifier in our context VerifiableCredential(
List.of("VerifiableCredential")), // this is an underspecifier in our context
Unknown(Collections.emptyList()); Unknown(Collections.emptyList());
private final List<String> allowedTypeValues; private final List<String> allowedTypeValues;
@ -88,17 +126,17 @@ public class VerifiableCredential extends Credential {
this.allowedTypeValues = allowedTypeValues; this.allowedTypeValues = allowedTypeValues;
} }
public static VerifiableCredential.Type valueOf (JsonNode typeNode) { public static VerifiableCredential.Type valueOf(JsonNode typeNode) {
if(typeNode != null) { if (typeNode != null) {
List<String> values = JsonNodeUtil.asStringList(typeNode); List<String> values = JsonNodeUtil.asStringList(typeNode);
for (String value : values) { for (String value : values) {
if(value.equals("AchievementCredential") || value.equals("OpenBadgeCredential")) { if (value.equals("AchievementCredential") || value.equals("OpenBadgeCredential")) {
return AchievementCredential; return AchievementCredential;
} else if(value.equals("ClrCredential")) { } else if (value.equals("ClrCredential")) {
return ClrCredential; return ClrCredential;
} else if(value.equals("VerifiablePresentation")) { } else if (value.equals("VerifiablePresentation")) {
return VerifiablePresentation; return VerifiablePresentation;
} else if(value.equals("EndorsementCredential")) { } else if (value.equals("EndorsementCredential")) {
return EndorsementCredential; return EndorsementCredential;
} }
} }
@ -120,18 +158,21 @@ public class VerifiableCredential extends Credential {
public boolean isAllowedTypeValuesRequired() { public boolean isAllowedTypeValuesRequired() {
return true; return true;
} }
@Override @Override
public List<String> getContextUris() { public List<String> getContextUris() {
return contextMap.get(contextMap.keySet() return contextMap.get(
.stream() contextMap.keySet().stream()
.filter(s->s.contains(this)) .filter(s -> s.contains(this))
.findFirst() .findFirst()
.orElseThrow(()-> new IllegalArgumentException(this.name() + " not recognized"))); .orElseThrow(() -> new IllegalArgumentException(this.name() + " not recognized")));
} }
@Override @Override
public Map<String, List<String>> getContextAliases() { public Map<String, List<String>> getContextAliases() {
return contextAliasesMap; return contextAliasesMap;
} }
@Override @Override
public Map<String, List<String>> getContextVersionPatterns() { public Map<String, List<String>> getContextVersionPatterns() {
return contextVersioningPatternMap; return contextVersioningPatternMap;
@ -151,16 +192,48 @@ public class VerifiableCredential extends Credential {
.toString(); .toString();
} }
public static enum VCVersion {
VCDMv2p0(ISSUED_ON_PROPERTY_NAME_V20, EXPIRES_AT_PROPERTY_NAME_V20),
VCDMv1p1(ISSUED_ON_PROPERTY_NAME_V11, EXPIRES_AT_PROPERTY_NAME_V11);
final String issuanceDateField;
final String expirationDateField;
VCVersion(String issuanceDateField, String expirationDateField) {
this.issuanceDateField = issuanceDateField;
this.expirationDateField = expirationDateField;
}
static VCVersion of(JsonNode context) {
if (JsonNodeUtil.asNodeList(context)
.stream()
.anyMatch(node -> node.isTextual() && node.asText().equals(JSONLD_CONTEXT_W3C_CREDENTIALS_V2)) )
return VCDMv2p0;
return VCDMv1p1;
}
}
public static class Builder extends Credential.Builder<VerifiableCredential> { public static class Builder extends Credential.Builder<VerifiableCredential> {
@Override @Override
public VerifiableCredential build() { public VerifiableCredential build() {
return new VerifiableCredential(getResource(), getJsonData(), getJwt(), schemas, ISSUED_ON_PROPERTY_NAME, EXPIRES_AT_PROPERTY_NAME); VCVersion version = VCVersion.of(getJsonData().get("@context"));
return new VerifiableCredential(
getResource(),
getJsonData(),
getJwt(),
schemas,
version);
} }
} }
public static final String ID = VerifiableCredential.class.getCanonicalName(); public static final String ID = VerifiableCredential.class.getCanonicalName();
private static final String ISSUED_ON_PROPERTY_NAME = "issuanceDate"; private static final String ISSUED_ON_PROPERTY_NAME_V11 = "issuanceDate";
private static final String EXPIRES_AT_PROPERTY_NAME = "expirationDate"; private static final String ISSUED_ON_PROPERTY_NAME_V20 = "validFrom";
private static final String EXPIRES_AT_PROPERTY_NAME_V11 = "expirationDate";
private static final String EXPIRES_AT_PROPERTY_NAME_V20 = "validUntil";
public static final String JWT_NODE_NAME = "vc"; public static final String JWT_NODE_NAME = "vc";
public static final List<MimeType> REFRESH_SERVICE_MIME_TYPES = List.of(MimeType.JSON, MimeType.JSON_LD, MimeType.TEXT_PLAIN); public static final List<MimeType> REFRESH_SERVICE_MIME_TYPES =
List.of(MimeType.JSON, MimeType.JSON_LD, MimeType.TEXT_PLAIN);
} }

View File

@ -1,23 +1,33 @@
package org.oneedtech.inspect.vc; package org.oneedtech.inspect.vc;
import java.io.StringReader;
import java.util.List; import java.util.List;
import org.oneedtech.inspect.vc.jsonld.JsonLDObjectUtils; import org.oneedtech.inspect.vc.jsonld.JsonLDObjectUtils;
import org.oneedtech.inspect.vc.util.CachingDocumentLoader; import org.oneedtech.inspect.vc.util.CachingDocumentLoader;
import com.danubetech.verifiablecredentials.VerifiableCredential;
import info.weboftrust.ldsignatures.LdProof; import info.weboftrust.ldsignatures.LdProof;
/** /**
* Holder for W3C's Verifiable Credential * Holder for W3C's Verifiable Credential
*/ */
public class W3CVCHolder { public class W3CVCHolder {
private VerifiableCredential credential; private com.danubetech.verifiablecredentials.VerifiableCredential credential;
public W3CVCHolder(VerifiableCredential credential) { public W3CVCHolder(VerifiableCredential credential) {
this.credential = credential; switch (credential.version) {
credential.setDocumentLoader(new CachingDocumentLoader()); case VCDMv1p1:
this.credential = com.danubetech.verifiablecredentials.VerifiableCredential
.fromJson(new StringReader(credential.getJson().toString()));
break;
case VCDMv2p0:
this.credential = W3CVerifiableCredentialDM2
.fromJson(new StringReader(credential.getJson().toString()));
break;
default:
throw new IllegalArgumentException("Unsupported version: " + credential.version);
}
this.credential.setDocumentLoader(new CachingDocumentLoader());
} }
/** /**
@ -30,7 +40,7 @@ public class W3CVCHolder {
return JsonLDObjectUtils.getListFromJsonLDObject(LdProof.class, credential); return JsonLDObjectUtils.getListFromJsonLDObject(LdProof.class, credential);
} }
public VerifiableCredential getCredential() { public com.danubetech.verifiablecredentials.VerifiableCredential getCredential() {
return credential; return credential;
} }
} }

View File

@ -0,0 +1,22 @@
package org.oneedtech.inspect.vc;
import java.net.URI;
import java.util.Date;
import foundation.identity.jsonld.JsonLDUtils;
public class W3CVerifiableCredentialDM2 extends com.danubetech.verifiablecredentials.VerifiableCredential {
public static final URI[] DEFAULT_JSONLD_CONTEXTS = { URI.create(VerifiableCredential.JSONLD_CONTEXT_W3C_CREDENTIALS_V2) };
public Date getValidFrom() {
return JsonLDUtils.stringToDate(JsonLDUtils.jsonLdGetString(this.getJsonObject(), JSONLD_TERM_VALIDFROM));
}
public Date getValidUntil() {
return JsonLDUtils.stringToDate(JsonLDUtils.jsonLdGetString(this.getJsonObject(), JSONLD_TERM_VALIDUNTIL));
}
private static final String JSONLD_TERM_VALIDFROM = "validFrom";
private static final String JSONLD_TERM_VALIDUNTIL = "validUntil";
}

View File

@ -2,6 +2,7 @@ package org.oneedtech.inspect.vc.probe;
import static org.oneedtech.inspect.util.code.Defensives.checkNotNull; import static org.oneedtech.inspect.util.code.Defensives.checkNotNull;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.oneedtech.inspect.core.probe.RunContext; import org.oneedtech.inspect.core.probe.RunContext;
@ -35,12 +36,20 @@ public class ContextPropertyProbe extends StringValuePropertyProbe {
checkNotNull(contextUris); checkNotNull(contextUris);
int pos = 0; int pos = 0;
List<ReportItems> warnings = new ArrayList<>();
for (String uri : contextUris) { for (String uri : contextUris) {
if ((nodeValues.size() < pos + 1) || !contains(uri, nodeValues.get(pos))) { if ((nodeValues.size() < pos + 1) || !contains(uri, nodeValues.get(pos))) {
return error("missing required @context uri " + uri + " at position " + (pos + 1), ctx); return error("missing required @context uri " + uri + " at position " + (pos + 1), ctx);
} }
if (!nodeValues.get(pos).equals(uri)) {
warnings.add(warning("expected @context uri " + uri + " at position " + (pos + 1) + ", gotten " + nodeValues.get(pos).toString() + " instead", ctx));
}
pos++; pos++;
} }
if (!warnings.isEmpty()) {
return new ReportItems(warnings);
}
} }
return success(ctx); return success(ctx);

View File

@ -1,34 +1,30 @@
package org.oneedtech.inspect.vc.probe; package org.oneedtech.inspect.vc.probe;
import java.io.StringReader;
import java.net.URI;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Optional;
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.VerifiableCredential;
import org.oneedtech.inspect.vc.W3CVCHolder;
import org.oneedtech.inspect.vc.verification.Ed25519Signature2022LdVerifier;
import com.apicatalog.jsonld.StringUtils; import com.apicatalog.jsonld.StringUtils;
import com.apicatalog.jsonld.document.Document; import com.apicatalog.jsonld.document.Document;
import com.apicatalog.jsonld.loader.DocumentLoaderOptions; import com.apicatalog.jsonld.loader.DocumentLoaderOptions;
import com.apicatalog.multibase.Multibase; import com.apicatalog.multibase.Multibase;
import com.apicatalog.multicodec.Multicodec; import com.apicatalog.multicodec.Multicodec;
import com.apicatalog.multicodec.Multicodec.Codec; import com.apicatalog.multicodec.Multicodec.Codec;
import info.weboftrust.ldsignatures.LdProof; import info.weboftrust.ldsignatures.LdProof;
import info.weboftrust.ldsignatures.verifier.Ed25519Signature2020LdVerifier; import info.weboftrust.ldsignatures.verifier.Ed25519Signature2020LdVerifier;
import info.weboftrust.ldsignatures.verifier.LdVerifier; import info.weboftrust.ldsignatures.verifier.LdVerifier;
import jakarta.json.JsonArray; import jakarta.json.JsonArray;
import jakarta.json.JsonObject; import jakarta.json.JsonObject;
import jakarta.json.JsonString;
import jakarta.json.JsonStructure; import jakarta.json.JsonStructure;
import jakarta.json.JsonValue; import jakarta.json.JsonValue;
import java.net.URI;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Optional;
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.VerifiableCredential;
import org.oneedtech.inspect.vc.W3CVCHolder;
import org.oneedtech.inspect.vc.verification.Ed25519Signature2022LdVerifier;
import org.oneedtech.inspect.vc.verification.Ed25519Signature2022VCDM20LdVerifier;
/** /**
* A Probe that verifies a credential's embedded proof. * A Probe that verifies a credential's embedded proof.
@ -37,7 +33,7 @@ import jakarta.json.JsonValue;
*/ */
public class EmbeddedProofProbe extends Probe<VerifiableCredential> { public class EmbeddedProofProbe extends Probe<VerifiableCredential> {
private final static List<String> ALLOWED_CRYPTOSUITES = List.of("eddsa-2022", "eddsa-rdfc-2022"); private static final List<String> ALLOWED_CRYPTOSUITES = List.of("eddsa-2022", "eddsa-rdfc-2022");
public EmbeddedProofProbe() { public EmbeddedProofProbe() {
super(ID); super(ID);
@ -50,8 +46,7 @@ public class EmbeddedProofProbe extends Probe<VerifiableCredential> {
@Override @Override
public ReportItems run(VerifiableCredential crd, RunContext ctx) throws Exception { public ReportItems run(VerifiableCredential crd, RunContext ctx) throws Exception {
W3CVCHolder credentialHolder = new W3CVCHolder(com.danubetech.verifiablecredentials.VerifiableCredential W3CVCHolder credentialHolder = new W3CVCHolder(crd);
.fromJson(new StringReader(crd.getJson().toString())));
List<LdProof> proofs = credentialHolder.getProofs(); List<LdProof> proofs = credentialHolder.getProofs();
if (proofs == null || proofs.size() == 0) { if (proofs == null || proofs.size() == 0) {
@ -59,14 +54,24 @@ public class EmbeddedProofProbe extends Probe<VerifiableCredential> {
} }
// get proof of standard type and purpose // get proof of standard type and purpose
Optional<LdProof> selectedProof = proofs.stream() Optional<LdProof> selectedProof =
proofs.stream()
.filter(proof -> proof.getProofPurpose().equals("assertionMethod")) .filter(proof -> proof.getProofPurpose().equals("assertionMethod"))
.filter(proof -> proof.isType("Ed25519Signature2020") || .filter(
(proof.isType("DataIntegrityProof") && proof.getJsonObject().containsKey("cryptosuite") && ALLOWED_CRYPTOSUITES.contains(proof.getJsonObject().get("cryptosuite")))) proof ->
proof.isType("Ed25519Signature2020")
|| (proof.isType("DataIntegrityProof")
&& proof.getJsonObject().containsKey("cryptosuite")
&& ALLOWED_CRYPTOSUITES.contains(
proof.getJsonObject().get("cryptosuite"))))
.findFirst(); .findFirst();
if (!selectedProof.isPresent()) { if (!selectedProof.isPresent()) {
return error("No proof with type any of (\"Ed25519Signature2020\", \"DataIntegrityProof\" with cryptosuite attr of \"eddsa-rdfc-2022\" or \"eddsa-2022\") or proof purpose \"assertionMethod\" found", ctx); return error(
"No proof with type any of (\"Ed25519Signature2020\", \"DataIntegrityProof\" with"
+ " cryptosuite attr of \"eddsa-rdfc-2022\" or \"eddsa-2022\") or proof purpose"
+ " \"assertionMethod\" found",
ctx);
} }
LdProof proof = selectedProof.get(); LdProof proof = selectedProof.get();
@ -137,26 +142,41 @@ public class EmbeddedProofProbe extends Probe<VerifiableCredential> {
// resolved. // resolved.
Optional<JsonStructure> keyStructure; Optional<JsonStructure> keyStructure;
try { try {
Document keyDocument = credentialHolder.getCredential().getDocumentLoader().loadDocument(uri, Document keyDocument =
new DocumentLoaderOptions()); credentialHolder
.getCredential()
.getDocumentLoader()
.loadDocument(uri, new DocumentLoaderOptions());
keyStructure = keyDocument.getJsonContent(); keyStructure = keyDocument.getJsonContent();
} catch (Exception e) { } catch (Exception e) {
return error("Key document not found at " + method + ". URI: " + uri return error(
+ " doesn't return a valid document. Reason: " + e.getMessage() + " ", ctx); "Key document not found at "
+ method
+ ". URI: "
+ uri
+ " doesn't return a valid document. Reason: "
+ e.getMessage()
+ " ",
ctx);
} }
if (keyStructure.isEmpty()) { if (keyStructure.isEmpty()) {
return error("Key document not found at " + method + ". URI: " + uri return error(
+ " doesn't return a valid document. Reason: The document is empty.", ctx); "Key document not found at "
+ method
+ ". URI: "
+ uri
+ " doesn't return a valid document. Reason: The document is empty.",
ctx);
} }
// check did in "assertionMethod" // check did in "assertionMethod"
JsonArray assertionMethod = keyStructure.get().asJsonObject() JsonArray assertionMethod =
.getJsonArray("assertionMethod"); keyStructure.get().asJsonObject().getJsonArray("assertionMethod");
if (assertionMethod == null) { if (assertionMethod == null) {
return error("Document doesn't have a list of assertion methods at URI: " + uri, ctx); return error("Document doesn't have a list of assertion methods at URI: " + uri, ctx);
} else { } else {
Boolean anyMatch = false; Boolean anyMatch = false;
for(int i = 0; i < assertionMethod.size(); i++) { for (int i = 0; i < assertionMethod.size(); i++) {
String assertionMethodValue = assertionMethod.getString(i); String assertionMethodValue = assertionMethod.getString(i);
if (assertionMethodValue.equals(method.toString())) { if (assertionMethodValue.equals(method.toString())) {
anyMatch = true; anyMatch = true;
@ -169,12 +189,14 @@ public class EmbeddedProofProbe extends Probe<VerifiableCredential> {
} }
// get keys from "verificationMethod" // get keys from "verificationMethod"
JsonArray keyVerificationMethod = keyStructure.get().asJsonObject() JsonArray keyVerificationMethod =
.getJsonArray("verificationMethod"); keyStructure.get().asJsonObject().getJsonArray("verificationMethod");
if (keyVerificationMethod == null) { if (keyVerificationMethod == null) {
return error("Document doesn't have a list of verification methods at URI: " + uri, ctx); return error(
"Document doesn't have a list of verification methods at URI: " + uri, ctx);
} }
Optional<JsonValue> verificationMethodMaybe = keyVerificationMethod.stream() Optional<JsonValue> verificationMethodMaybe =
keyVerificationMethod.stream()
.filter(n -> n.asJsonObject().getString("id").equals(method.toString())) .filter(n -> n.asJsonObject().getString("id").equals(method.toString()))
.findFirst(); .findFirst();
if (verificationMethodMaybe.isEmpty()) { if (verificationMethodMaybe.isEmpty()) {
@ -190,8 +212,11 @@ public class EmbeddedProofProbe extends Probe<VerifiableCredential> {
} }
} else if (method.getScheme().equals("http") || method.getScheme().equals("https")) { } else if (method.getScheme().equals("http") || method.getScheme().equals("https")) {
try { try {
Document keyDocument = credentialHolder.getCredential().getDocumentLoader().loadDocument(method, Document keyDocument =
new DocumentLoaderOptions()); credentialHolder
.getCredential()
.getDocumentLoader()
.loadDocument(method, new DocumentLoaderOptions());
Optional<JsonStructure> keyStructure = keyDocument.getJsonContent(); Optional<JsonStructure> keyStructure = keyDocument.getJsonContent();
if (keyStructure.isEmpty()) { if (keyStructure.isEmpty()) {
return error("Key document not found at " + method, ctx); return error("Key document not found at " + method, ctx);
@ -203,8 +228,8 @@ public class EmbeddedProofProbe extends Probe<VerifiableCredential> {
// Then look for a controller document (e.g. DID Document) with a // Then look for a controller document (e.g. DID Document) with a
// 'verificationMethod' // 'verificationMethod'
// that is a Ed25519VerificationKey2020 document // that is a Ed25519VerificationKey2020 document
JsonObject keyVerificationMethod = keyStructure.get().asJsonObject() JsonObject keyVerificationMethod =
.getJsonObject("verificationMethod"); keyStructure.get().asJsonObject().getJsonObject("verificationMethod");
if (keyVerificationMethod.isEmpty()) { if (keyVerificationMethod.isEmpty()) {
return error("Cannot parse key document from " + method, ctx); return error("Cannot parse key document from " + method, ctx);
} }
@ -234,9 +259,10 @@ public class EmbeddedProofProbe extends Probe<VerifiableCredential> {
return error("Invalid public key: " + e.getMessage(), ctx); return error("Invalid public key: " + e.getMessage(), ctx);
} }
if (controller != null) { if (controller != null && credentialHolder.getCredential().getIssuer() != null) {
if (!controller.equals(credentialHolder.getCredential().getIssuer().toString())) { if (!controller.equals(credentialHolder.getCredential().getIssuer().toString())) {
return error("Key controller does not match issuer: " + credentialHolder.getCredential().getIssuer(), return error(
"Key controller does not match issuer: " + credentialHolder.getCredential().getIssuer(),
ctx); ctx);
} }
} }
@ -245,7 +271,7 @@ public class EmbeddedProofProbe extends Probe<VerifiableCredential> {
byte[] publicKey = Multicodec.decode(Codec.Ed25519PublicKey, publicKeyMulticodec); byte[] publicKey = Multicodec.decode(Codec.Ed25519PublicKey, publicKeyMulticodec);
// choose verifier // choose verifier
LdVerifier<?> verifier = getVerifier(proof, publicKey); LdVerifier<?> verifier = getVerifier(proof, publicKey, crd);
try { try {
boolean verify = verifier.verify(credentialHolder.getCredential(), proof); boolean verify = verifier.verify(credentialHolder.getCredential(), proof);
@ -259,10 +285,12 @@ public class EmbeddedProofProbe extends Probe<VerifiableCredential> {
return success(ctx); return success(ctx);
} }
private LdVerifier<?> getVerifier(LdProof proof, byte[] publicKey) { private LdVerifier<?> getVerifier(LdProof proof, byte[] publicKey, VerifiableCredential crd) {
return proof.isType("Ed25519Signature2020") return proof.isType("Ed25519Signature2020")
? new Ed25519Signature2020LdVerifier(publicKey) ? new Ed25519Signature2020LdVerifier(publicKey)
: new Ed25519Signature2022LdVerifier(publicKey); : crd.getVersion() == VerifiableCredential.VCVersion.VCDMv1p1
? new Ed25519Signature2022LdVerifier(publicKey)
: new Ed25519Signature2022VCDM20LdVerifier(publicKey);
} }
private Boolean IsValidPublicKeyMultibase(String publicKeyMultibase) { private Boolean IsValidPublicKeyMultibase(String publicKeyMultibase) {
@ -273,7 +301,6 @@ public class EmbeddedProofProbe extends Probe<VerifiableCredential> {
} catch (Exception e) { } catch (Exception e) {
return false; return false;
} }
} }
public static final String ID = EmbeddedProofProbe.class.getSimpleName(); public static final String ID = EmbeddedProofProbe.class.getSimpleName();

View File

@ -22,7 +22,7 @@ public class ExpirationProbe extends Probe<Credential> {
@Override @Override
public ReportItems run(Credential crd, RunContext ctx) throws Exception { public ReportItems run(Credential crd, RunContext ctx) throws Exception {
/* /*
* If the AchievementCredential or EndorsementCredential has an expirationDate property * If the AchievementCredential or EndorsementCredential has an expirationDate or "validUntil" property
* and the expiration date is prior to the current date, the credential has expired. * and the expiration date is prior to the current date, the credential has expired.
*/ */
JsonNode node = crd.getJson().get(crd.getExpiresAtPropertyName()); JsonNode node = crd.getJson().get(crd.getExpiresAtPropertyName());
@ -30,10 +30,10 @@ public class ExpirationProbe extends Probe<Credential> {
try { try {
ZonedDateTime expirationDate = ZonedDateTime.parse(node.textValue()); ZonedDateTime expirationDate = ZonedDateTime.parse(node.textValue());
if (ZonedDateTime.now().isAfter(expirationDate)) { if (ZonedDateTime.now().isAfter(expirationDate)) {
return fatal("The credential has expired (expiration date was " + node.asText() + ").", ctx); return fatal("The credential has expired (expiration date or validUntil was " + node.asText() + ").", ctx);
} }
} catch (Exception e) { } catch (Exception e) {
return exception("Error while checking expirationDate: " + e.getMessage(), ctx.getResource()); return exception("Error while checking expirationDate or validUntil: " + e.getMessage(), ctx.getResource());
} }
} }
return success(ctx); return success(ctx);

View File

@ -22,7 +22,7 @@ public class IssuanceProbe extends Probe<Credential> {
@Override @Override
public ReportItems run(Credential crd, RunContext ctx) throws Exception { public ReportItems run(Credential crd, RunContext ctx) throws Exception {
/* /*
* If the AchievementCredential or EndorsementCredential issuanceDate * If the AchievementCredential or EndorsementCredential issuanceDate or "validFrom"
* property after the current date, the credential is not yet valid. * property after the current date, the credential is not yet valid.
*/ */
JsonNode node = crd.getJson().get(crd.getIssuedOnPropertyName()); JsonNode node = crd.getJson().get(crd.getIssuedOnPropertyName());
@ -30,10 +30,10 @@ public class IssuanceProbe extends Probe<Credential> {
try { try {
ZonedDateTime issuanceDate = ZonedDateTime.parse(node.textValue()); ZonedDateTime issuanceDate = ZonedDateTime.parse(node.textValue());
if (issuanceDate.isAfter(ZonedDateTime.now())) { if (issuanceDate.isAfter(ZonedDateTime.now())) {
return fatal("The credential is not yet issued (issuance date is " + node.asText() + ").", ctx); return fatal("The credential is not yet issued or valid (issuance date or validFrom is " + node.asText() + ").", ctx);
} }
} catch (Exception e) { } catch (Exception e) {
return exception("Error while checking issuanceDate: " + e.getMessage(), ctx.getResource()); return exception("Error while checking issuanceDate or ValidFrom: " + e.getMessage(), ctx.getResource());
} }
} }
return success(ctx); return success(ctx);

View File

@ -120,6 +120,7 @@ public class CachingDocumentLoader extends ConfigurableDocumentLoader {
.put("https://w3id.org/security/suites/ed25519-2020/v1",Resources.getResource("contexts/security-suites-ed25519-2020-v1.jsonld")) .put("https://w3id.org/security/suites/ed25519-2020/v1",Resources.getResource("contexts/security-suites-ed25519-2020-v1.jsonld"))
.put("https://w3id.org/security/data-integrity/v1",Resources.getResource("contexts/data-integrity-v1.jsonld")) .put("https://w3id.org/security/data-integrity/v1",Resources.getResource("contexts/data-integrity-v1.jsonld"))
.put("https://www.w3.org/2018/credentials/v1", Resources.getResource("contexts/2018-credentials-v1.jsonld")) .put("https://www.w3.org/2018/credentials/v1", Resources.getResource("contexts/2018-credentials-v1.jsonld"))
.put("https://www.w3.org/ns/credentials/v2", Resources.getResource("contexts/credentials-v2.jsonld"))
.put("https://w3id.org/security/v1", Resources.getResource("contexts/security-v1.jsonld")) .put("https://w3id.org/security/v1", Resources.getResource("contexts/security-v1.jsonld"))
.put("https://w3id.org/security/v2", Resources.getResource("contexts/security-v2.jsonld")) .put("https://w3id.org/security/v2", Resources.getResource("contexts/security-v2.jsonld"))
.put("https://w3id.org/security/v3", Resources.getResource("contexts/security-v3-unstable.jsonld")) .put("https://w3id.org/security/v3", Resources.getResource("contexts/security-v3-unstable.jsonld"))

View File

@ -13,7 +13,7 @@ public class Ed25519Signature2022LdVerifier extends LdVerifier<Ed25519Signature2
public Ed25519Signature2022LdVerifier(ByteVerifier verifier) { public Ed25519Signature2022LdVerifier(ByteVerifier verifier) {
super(SignatureSuites.SIGNATURE_SUITE_ED25519SIGNATURE2022, verifier, new URDNA2015Canonicalizer()); super(SignatureSuites.SIGNATURE_SUITE_ED25519SIGNATURE2022, verifier, new URDNA2015Canonicalizer(Eddsa2022LdProof.builder()));
} }
public Ed25519Signature2022LdVerifier(byte[] publicKey) { public Ed25519Signature2022LdVerifier(byte[] publicKey) {

View File

@ -0,0 +1,53 @@
package org.oneedtech.inspect.vc.verification;
import com.danubetech.keyformats.crypto.ByteVerifier;
import com.danubetech.keyformats.crypto.impl.Ed25519_EdDSA_PublicKeyVerifier;
import com.danubetech.keyformats.jose.JWSAlgorithm;
import info.weboftrust.ldsignatures.LdProof;
import info.weboftrust.ldsignatures.verifier.LdVerifier;
import io.ipfs.multibase.Multibase;
import java.security.GeneralSecurityException;
public class Ed25519Signature2022VCDM20LdVerifier extends LdVerifier<Ed25519Signature2022SignatureSuite> {
public Ed25519Signature2022VCDM20LdVerifier(ByteVerifier verifier) {
super(SignatureSuites.SIGNATURE_SUITE_ED25519SIGNATURE2022, verifier, new URDNA2015Canonicalizer(Eddsa2022v2LdProof.builder()));
}
public Ed25519Signature2022VCDM20LdVerifier(byte[] publicKey) {
this(new Ed25519_EdDSA_PublicKeyVerifier(publicKey));
}
public Ed25519Signature2022VCDM20LdVerifier() {
this((ByteVerifier) null);
}
public static boolean verify(byte[] signingInput, LdProof ldProof, ByteVerifier verifier) throws GeneralSecurityException {
// verify
String proofValue = ldProof.getProofValue();
if (proofValue == null) throw new GeneralSecurityException("No 'proofValue' in proof.");
boolean verify;
byte[] bytes = Multibase.decode(proofValue);
verify = verifier.verify(signingInput, bytes, JWSAlgorithm.EdDSA);
// done
return verify;
}
@Override
public boolean verify(byte[] signingInput, LdProof ldProof) throws GeneralSecurityException {
return verify(signingInput, ldProof, this.getVerifier());
}
}

View File

@ -0,0 +1,49 @@
package org.oneedtech.inspect.vc.verification;
import java.net.URI;
import com.apicatalog.jsonld.loader.DocumentLoader;
import foundation.identity.jsonld.JsonLDObject;
import foundation.identity.jsonld.JsonLDUtils;
import info.weboftrust.ldsignatures.LdProof;
public class Eddsa2022v2LdProof extends LdProof {
public static final URI[] DEFAULT_JSONLD_CONTEXTS = { LDSecurityContexts.JSONLD_CONTEXT_W3ID_VC_V2 };
public static final DocumentLoader DEFAULT_DOCUMENT_LOADER = LDSecurityContexts.DOCUMENT_LOADER;
public static Builder<? extends Builder<?>> builder() {
return new Builder(new Eddsa2022v2LdProof());
}
/*
* Factory methods
*/
public static class Builder<B extends Builder<B>> extends LdProof.Builder<B> {
private boolean addCryptosuite = true;
public Builder(LdProof jsonLdObject) {
super(jsonLdObject);
}
@Override
public B base(JsonLDObject base) {
addCryptosuite = false;
return super.base(base);
}
@Override
public LdProof build() {
super.build();
if (addCryptosuite) {
JsonLDUtils.jsonLdAdd(this.jsonLdObject, "cryptosuite", "eddsa-rdfc-2022");
}
return (LdProof) this.jsonLdObject;
}
}
}

View File

@ -15,6 +15,7 @@ import foundation.identity.jsonld.ConfigurableDocumentLoader;
public class LDSecurityContexts { public class LDSecurityContexts {
public static final URI JSONLD_CONTEXT_W3ID_SUITES_ED25519_2022_V1 = URI.create("https://w3id.org/security/data-integrity/v1"); public static final URI JSONLD_CONTEXT_W3ID_SUITES_ED25519_2022_V1 = URI.create("https://w3id.org/security/data-integrity/v1");
public static final URI JSONLD_CONTEXT_W3ID_VC_V2 = URI.create("https://www.w3.org/ns/credentials/v2");
public static final Map<URI, JsonDocument> CONTEXTS; public static final Map<URI, JsonDocument> CONTEXTS;
public static final DocumentLoader DOCUMENT_LOADER; public static final DocumentLoader DOCUMENT_LOADER;
@ -29,6 +30,8 @@ public class LDSecurityContexts {
CONTEXTS.put(JSONLD_CONTEXT_W3ID_SUITES_ED25519_2022_V1, CONTEXTS.put(JSONLD_CONTEXT_W3ID_SUITES_ED25519_2022_V1,
JsonDocument.of(MediaType.JSON_LD, Resources.getResource("contexts/data-integrity-v1.jsonld").openStream())); JsonDocument.of(MediaType.JSON_LD, Resources.getResource("contexts/data-integrity-v1.jsonld").openStream()));
CONTEXTS.put(JSONLD_CONTEXT_W3ID_VC_V2,
JsonDocument.of(MediaType.JSON_LD, Resources.getResource("contexts/credentials-v2.jsonld").openStream()));
for (Map.Entry<URI, JsonDocument> context : CONTEXTS.entrySet()) { for (Map.Entry<URI, JsonDocument> context : CONTEXTS.entrySet()) {
context.getValue().setDocumentUrl(context.getKey()); context.getValue().setDocumentUrl(context.getKey());

View File

@ -1,28 +1,29 @@
package org.oneedtech.inspect.vc.verification; package org.oneedtech.inspect.vc.verification;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.List;
import foundation.identity.jsonld.JsonLDException; import foundation.identity.jsonld.JsonLDException;
import foundation.identity.jsonld.JsonLDObject; import foundation.identity.jsonld.JsonLDObject;
import info.weboftrust.ldsignatures.LdProof; import info.weboftrust.ldsignatures.LdProof;
import info.weboftrust.ldsignatures.canonicalizer.Canonicalizer; import info.weboftrust.ldsignatures.canonicalizer.Canonicalizer;
import info.weboftrust.ldsignatures.util.SHAUtil; import info.weboftrust.ldsignatures.util.SHAUtil;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.List;
public class URDNA2015Canonicalizer extends Canonicalizer { public class URDNA2015Canonicalizer extends Canonicalizer {
public URDNA2015Canonicalizer() { private LdProof.Builder<?> proofBuilder;
public URDNA2015Canonicalizer(LdProof.Builder<?> proofBuilder) {
super(List.of("urdna2015")); super(List.of("urdna2015"));
this.proofBuilder = proofBuilder;
} }
@Override @Override
public byte[] canonicalize(LdProof ldProof, JsonLDObject jsonLdObject) throws IOException, GeneralSecurityException, JsonLDException { public byte[] canonicalize(LdProof ldProof, JsonLDObject jsonLdObject) throws IOException, GeneralSecurityException, JsonLDException {
// construct the LD proof without proof values // construct the LD proof without proof values
LdProof ldProofWithoutProofValues = proofBuilder
LdProof ldProofWithoutProofValues = Eddsa2022LdProof.builder()
.base(ldProof) .base(ldProof)
.defaultContexts(true) .defaultContexts(true)
.build(); .build();

View File

@ -0,0 +1,290 @@
{
"@context": {
"@protected": true,
"@vocab": "https://www.w3.org/ns/credentials/issuer-dependent#",
"id": "@id",
"type": "@type",
"kid": {
"@id": "https://www.iana.org/assignments/jose#kid",
"@type": "@id"
},
"iss": {
"@id": "https://www.iana.org/assignments/jose#iss",
"@type": "@id"
},
"sub": {
"@id": "https://www.iana.org/assignments/jose#sub",
"@type": "@id"
},
"jku": {
"@id": "https://www.iana.org/assignments/jose#jku",
"@type": "@id"
},
"x5u": {
"@id": "https://www.iana.org/assignments/jose#x5u",
"@type": "@id"
},
"aud": {
"@id": "https://www.iana.org/assignments/jwt#aud",
"@type": "@id"
},
"exp": {
"@id": "https://www.iana.org/assignments/jwt#exp",
"@type": "https://www.w3.org/2001/XMLSchema#nonNegativeInteger"
},
"nbf": {
"@id": "https://www.iana.org/assignments/jwt#nbf",
"@type": "https://www.w3.org/2001/XMLSchema#nonNegativeInteger"
},
"iat": {
"@id": "https://www.iana.org/assignments/jwt#iat",
"@type": "https://www.w3.org/2001/XMLSchema#nonNegativeInteger"
},
"cnf": {
"@id": "https://www.iana.org/assignments/jwt#cnf",
"@context": {
"@protected": true,
"kid": {
"@id": "https://www.iana.org/assignments/jwt#kid",
"@type": "@id"
},
"jwk": {
"@id": "https://www.iana.org/assignments/jwt#jwk",
"@type": "@json"
}
}
},
"_sd_alg": {
"@id": "https://www.iana.org/assignments/jwt#_sd_alg"
},
"_sd": {
"@id": "https://www.iana.org/assignments/jwt#_sd"
},
"...": {
"@id": "https://www.iana.org/assignments/jwt#..."
},
"digestSRI": {
"@id": "https://www.w3.org/2018/credentials#digestSRI",
"@type": "https://www.w3.org/2018/credentials#sriString"
},
"digestMultibase": {
"@id": "https://w3id.org/security#digestMultibase",
"@type": "https://w3id.org/security#multibase"
},
"mediaType": {
"@id": "https://schema.org/encodingFormat"
},
"description": "https://schema.org/description",
"name": "https://schema.org/name",
"EnvelopedVerifiableCredential": "https://www.w3.org/2018/credentials#EnvelopedVerifiableCredential",
"VerifiableCredential": {
"@id": "https://www.w3.org/2018/credentials#VerifiableCredential",
"@context": {
"@protected": true,
"id": "@id",
"type": "@type",
"credentialSchema": {
"@id": "https://www.w3.org/2018/credentials#credentialSchema",
"@type": "@id"
},
"credentialStatus": {
"@id": "https://www.w3.org/2018/credentials#credentialStatus",
"@type": "@id"
},
"credentialSubject": {
"@id": "https://www.w3.org/2018/credentials#credentialSubject",
"@type": "@id"
},
"description": "https://schema.org/description",
"evidence": {
"@id": "https://www.w3.org/2018/credentials#evidence",
"@type": "@id"
},
"validFrom": {
"@id": "https://www.w3.org/2018/credentials#validFrom",
"@type": "http://www.w3.org/2001/XMLSchema#dateTime"
},
"validUntil": {
"@id": "https://www.w3.org/2018/credentials#validUntil",
"@type": "http://www.w3.org/2001/XMLSchema#dateTime"
},
"issuer": {
"@id": "https://www.w3.org/2018/credentials#issuer",
"@type": "@id"
},
"name": "https://schema.org/name",
"proof": {
"@id": "https://w3id.org/security#proof",
"@type": "@id",
"@container": "@graph"
},
"refreshService": {
"@id": "https://www.w3.org/2018/credentials#refreshService",
"@type": "@id"
},
"termsOfUse": {
"@id": "https://www.w3.org/2018/credentials#termsOfUse",
"@type": "@id"
},
"confidenceMethod": {
"@id": "https://www.w3.org/2018/credentials#confidenceMethod",
"@type": "@id"
},
"relatedResource": {
"@id": "https://www.w3.org/2018/credentials#relatedResource",
"@type": "@id"
}
}
},
"VerifiablePresentation": {
"@id": "https://www.w3.org/2018/credentials#VerifiablePresentation",
"@context": {
"@protected": true,
"id": "@id",
"type": "@type",
"holder": {
"@id": "https://www.w3.org/2018/credentials#holder",
"@type": "@id"
},
"proof": {
"@id": "https://w3id.org/security#proof",
"@type": "@id",
"@container": "@graph"
},
"verifiableCredential": {
"@id": "https://www.w3.org/2018/credentials#verifiableCredential",
"@type": "@id",
"@container": "@graph",
"@context": null
},
"termsOfUse": {
"@id": "https://www.w3.org/2018/credentials#termsOfUse",
"@type": "@id"
}
}
},
"JsonSchemaCredential": "https://www.w3.org/2018/credentials#JsonSchemaCredential",
"JsonSchema": {
"@id": "https://www.w3.org/2018/credentials#JsonSchema",
"@context": {
"@protected": true,
"id": "@id",
"type": "@type",
"jsonSchema": {
"@id": "https://w3.org/2018/credentials#jsonSchema",
"@type": "@json"
}
}
},
"BitstringStatusListCredential": "https://www.w3.org/ns/credentials/status#BitstringStatusListCredential",
"BitstringStatusList": {
"@id": "https://www.w3.org/ns/credentials/status#BitstringStatusList",
"@context": {
"@protected": true,
"id": "@id",
"type": "@type",
"statusPurpose": "https://www.w3.org/ns/credentials/status#statusPurpose",
"encodedList": {
"@id": "https://www.w3.org/ns/credentials/status#encodedList",
"@type": "https://w3id.org/security#multibase"
},
"ttl": "https://www.w3.org/ns/credentials/status#ttl",
"statusReference": "https://www.w3.org/ns/credentials/status#statusReference",
"statusSize": "https://www.w3.org/ns/credentials/status#statusSize",
"statusMessage": {
"@id": "https://www.w3.org/ns/credentials/status#statusMessage",
"@context": {
"@protected": true,
"id": "@id",
"type": "@type",
"status": "https://www.w3.org/ns/credentials/status#status",
"message": "https://www.w3.org/ns/credentials/status#message"
}
}
}
},
"BitstringStatusListEntry": {
"@id": "https://www.w3.org/ns/credentials/status#BitstringStatusListEntry",
"@context": {
"@protected": true,
"id": "@id",
"type": "@type",
"statusPurpose": "https://www.w3.org/ns/credentials/status#statusPurpose",
"statusListIndex": "https://www.w3.org/ns/credentials/status#statusListIndex",
"statusListCredential": {
"@id": "https://www.w3.org/ns/credentials/status#statusListCredential",
"@type": "@id"
}
}
},
"DataIntegrityProof": {
"@id": "https://w3id.org/security#DataIntegrityProof",
"@context": {
"@protected": true,
"id": "@id",
"type": "@type",
"challenge": "https://w3id.org/security#challenge",
"created": {
"@id": "http://purl.org/dc/terms/created",
"@type": "http://www.w3.org/2001/XMLSchema#dateTime"
},
"domain": "https://w3id.org/security#domain",
"expires": {
"@id": "https://w3id.org/security#expiration",
"@type": "http://www.w3.org/2001/XMLSchema#dateTime"
},
"nonce": "https://w3id.org/security#nonce",
"previousProof": {
"@id": "https://w3id.org/security#previousProof",
"@type": "@id"
},
"proofPurpose": {
"@id": "https://w3id.org/security#proofPurpose",
"@type": "@vocab",
"@context": {
"@protected": true,
"id": "@id",
"type": "@type",
"assertionMethod": {
"@id": "https://w3id.org/security#assertionMethod",
"@type": "@id",
"@container": "@set"
},
"authentication": {
"@id": "https://w3id.org/security#authenticationMethod",
"@type": "@id",
"@container": "@set"
},
"capabilityInvocation": {
"@id": "https://w3id.org/security#capabilityInvocationMethod",
"@type": "@id",
"@container": "@set"
},
"capabilityDelegation": {
"@id": "https://w3id.org/security#capabilityDelegationMethod",
"@type": "@id",
"@container": "@set"
},
"keyAgreement": {
"@id": "https://w3id.org/security#keyAgreementMethod",
"@type": "@id",
"@container": "@set"
}
}
},
"cryptosuite": {
"@id": "https://w3id.org/security#cryptosuite",
"@type": "https://w3id.org/security#cryptosuiteString"
},
"proofValue": {
"@id": "https://w3id.org/security#proofValue",
"@type": "https://w3id.org/security#multibase"
},
"verificationMethod": {
"@id": "https://w3id.org/security#verificationMethod",
"@type": "@id"
}
}
}
}
}

View File

@ -44,6 +44,15 @@ public class OB30Tests {
}); });
} }
@Test
void testSimpleV1JsonValid() {
assertDoesNotThrow(()->{
Report report = validator.run(Samples.OB30.JSON.SIMPLE_V1_JSON.asFileResource());
if(verbose) PrintHelper.print(report, true);
assertWarning(report);
});
}
@Test @Test
void testSimpleDidKeyMethodJsonValid() { void testSimpleDidKeyMethodJsonValid() {
assertDoesNotThrow(()->{ assertDoesNotThrow(()->{
@ -219,7 +228,7 @@ public class OB30Tests {
assertDoesNotThrow(()->{ assertDoesNotThrow(()->{
Report report = validator.run(Samples.OB30.JSON.SIMPLE_JSON_VERSION_CONTEXT.asFileResource()); Report report = validator.run(Samples.OB30.JSON.SIMPLE_JSON_VERSION_CONTEXT.asFileResource());
if(verbose) PrintHelper.print(report, true); if(verbose) PrintHelper.print(report, true);
assertHasValidProbeID(report, ContextPropertyProbe.ID); assertHasProbeID(report, ContextPropertyProbe.ID, true);
}); });
} }
@ -342,7 +351,6 @@ public class OB30Tests {
}); });
} }
@Disabled //TODO IssuanceVerifierProbe is not run because FATAL: InvalidSignature terminates
@Test @Test
void testSimpleJsonNotIssued() { void testSimpleJsonNotIssued() {
//"issuanceDate": "2040-01-01T00:00:00Z", //"issuanceDate": "2040-01-01T00:00:00Z",
@ -382,11 +390,11 @@ public class OB30Tests {
} }
@Test @Test
void testEddsa2022Valid() { void testEddsa2022Warning() {
assertDoesNotThrow(()->{ assertDoesNotThrow(()->{
Report report = validator.run(Samples.OB30.JSON.SIMPLE_EDDSA_20222_JSON.asFileResource()); Report report = validator.run(Samples.OB30.JSON.SIMPLE_EDDSA_20222_JSON.asFileResource());
if(verbose) PrintHelper.print(report, true); if(verbose) PrintHelper.print(report, true);
assertValid(report); assertWarning(report);
}); });
} }

View File

@ -11,6 +11,7 @@ public class Samples {
public static final class JSON { public static final class JSON {
public final static Sample COMPLETE_JSON = new Sample("ob30/complete.json", false); 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 = new Sample("ob30/simple.json", true);
public final static Sample SIMPLE_V1_JSON = new Sample("ob30/simple_v1.json", true);
public final static Sample SIMPLE_EDDSA_20222_JSON = new Sample("ob30/simple-eddsa-2022.json", true); public final static Sample SIMPLE_EDDSA_20222_JSON = new Sample("ob30/simple-eddsa-2022.json", true);
public final static Sample SIMPLE_DID_KEY_METHOD_JSON = new Sample("ob30/simple-did-key-method.json", true); public final static Sample SIMPLE_DID_KEY_METHOD_JSON = new Sample("ob30/simple-did-key-method.json", true);
public final static Sample SIMPLE_DID_WEB_METHOD_JSON = new Sample("ob30/simple-did-web-method.json", true); public final static Sample SIMPLE_DID_WEB_METHOD_JSON = new Sample("ob30/simple-did-web-method.json", true);

View File

@ -1,9 +1,8 @@
{ {
"@context": [ "@context": [
"https://www.w3.org/2018/credentials/v1", "https://www.w3.org/ns/credentials/v2",
"https://purl.imsglobal.org/spec/ob/v3p0/context.json", "https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json",
"https://purl.imsglobal.org/spec/ob/v3p0/extensions.json", "https://purl.imsglobal.org/spec/ob/v3p0/extensions.json"
"https://w3id.org/security/suites/ed25519-2020/v1"
], ],
"id": "http://1edtech.edu/endorsementcredential/3732", "id": "http://1edtech.edu/endorsementcredential/3732",
"type": [ "type": [
@ -12,15 +11,19 @@
], ],
"issuer": { "issuer": {
"id": "https://state.gov/issuers/565049", "id": "https://state.gov/issuers/565049",
"type": ["Profile"], "type": [
"Profile"
],
"name": "State Department of Education" "name": "State Department of Education"
}, },
"issuanceDate": "2010-01-01T00:00:00Z", "validFrom": "2010-01-01T00:00:00Z",
"expirationDate": "2030-01-01T00:00:00Z", "validUntil": "2030-01-01T00:00:00Z",
"name": "Example endorsement", "name": "Example endorsement",
"credentialSubject": { "credentialSubject": {
"id": "https://1edtech.edu/issuers/565049", "id": "https://1edtech.edu/issuers/565049",
"type": ["EndorsementSubject"], "type": [
"EndorsementSubject"
],
"endorsementComment": "1EdTech University is in good standing" "endorsementComment": "1EdTech University is in good standing"
}, },
"credentialSchema": [ "credentialSchema": [
@ -30,10 +33,11 @@
} }
], ],
"proof": [{ "proof": [{
"type": "Ed25519Signature2020", "type": "DataIntegrityProof",
"created": "2010-01-01T19:23:24Z", "created": "2010-01-01T19:23:24Z",
"verificationMethod": "https://state.gov/issuers/565049#z6MkjZRZv3aez3r18pB1RBFJR1kwUVJ5jHt92JmQwXbd5hwi", "verificationMethod": "https://state.gov/issuers/565049#z6MkoMGF38Ck9xkdqrbZt4h9eHb1qc3GhAAkoSWa4Vy3SHRN",
"cryptosuite": "eddsa-rdfc-2022",
"proofPurpose": "assertionMethod", "proofPurpose": "assertionMethod",
"proofValue": "z347N8ntbL3usCGshtUZiyrBeGBhYVAqyi4HUhz4fBmU1zVwk5eRfPZJvKoendfyGaeSbJcAfQEVNpvcHLzVhDtQC" "proofValue": "z4DKZeDFKKvz5dDVPEky9NU8Zk3J8tH62Vtnm7drwwvPhDKwd6wL6td8skZkbyqw17y5zNJxfjT42dKpQc3Mgx1x6"
}] }]
} }

View File

@ -1,8 +1,7 @@
{ {
"@context": [ "@context": [
"https://www.w3.org/2018/credentials/v1", "https://www.w3.org/ns/credentials/v2",
"https://purl.imsglobal.org/spec/ob/v3p0/context/ob_v3p0.jsonld", "https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json"
"https://w3id.org/security/suites/ed25519-2020/v1"
], ],
"id": "http://example.com/credentials/3527", "id": "http://example.com/credentials/3527",
"type": [ "type": [
@ -35,13 +34,13 @@
"name": "Teamwork" "name": "Teamwork"
} }
}, },
"proof": [ "validFrom": "2024-03-21T14:56:35Z",
{ "proof": [{
"type": "Ed25519Signature2020", "type": "DataIntegrityProof",
"created": "2022-11-16T18:54:22Z", "created": "2010-01-01T19:23:24Z",
"verificationMethod": "https://example.com/issuers/876543#z6MknNHHrBzPytzu6CUBP9Lg7fg4KSBjzimc2Frh693YbMiv", "verificationMethod": "https://example.com/issuers/876543#z6MkjZRZv3aez3r18pB1RBFJR1kwUVJ5jHt92JmQwXbd5hwi",
"cryptosuite": "eddsa-rdfc-2022",
"proofPurpose": "assertionMethod", "proofPurpose": "assertionMethod",
"proofValue": "z5gJZKchSJEYPGeq6bsqiLKuxT6mXqAovPbqYX66CB7u9CSNFdV41vHtysjHFiitvoyhfPxsaZnWftrZZZW2txPQK" "proofValue": "z56yYTVAJxcTduuDvdCfnmEcYsRwHS7aBxHTgqYQUWYuXQxTyEswJTs4ynNeB8yjdoLcspTYL4z6mscwC47fJ8bBN"
} }]
]
} }

View File

@ -1,8 +1,7 @@
{ {
"@context": [ "@context": [
"https://www.w3.org/2018/credentials/v1", "https://www.w3.org/ns/credentials/v2",
"https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.1.json", "https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.2.json"
"https://w3id.org/security/suites/ed25519-2020/v1"
], ],
"id": "http://example.com/credentials/3527", "id": "http://example.com/credentials/3527",
"type": [ "type": [
@ -16,7 +15,7 @@
], ],
"name": "Example Corp" "name": "Example Corp"
}, },
"issuanceDate": "2010-01-01T00:00:00Z", "validFrom": "2010-01-01T00:00:00Z",
"name": "Teamwork Badge", "name": "Teamwork Badge",
"credentialSubject": { "credentialSubject": {
"id": "did:example:ebfeb1f712ebc6f1c276e12ec21", "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
@ -35,13 +34,12 @@
"name": "Teamwork" "name": "Teamwork"
} }
}, },
"proof": [ "proof": [{
{ "type": "DataIntegrityProof",
"type": "Ed25519Signature2020", "created": "2010-01-01T19:23:24Z",
"created": "2022-11-16T18:54:22Z", "verificationMethod": "https://example.com/issuers/876543#z6MkjZRZv3aez3r18pB1RBFJR1kwUVJ5jHt92JmQwXbd5hwi",
"verificationMethod": "https://example.com/issuers/876543#z6MknNHHrBzPytzu6CUBP9Lg7fg4KSBjzimc2Frh693YbMiv", "cryptosuite": "eddsa-rdfc-2022",
"proofPurpose": "assertionMethod", "proofPurpose": "assertionMethod",
"proofValue": "z5gJZKchSJEYPGeq6bsqiLKuxT6mXqAovPbqYX66CB7u9CSNFdV41vHtysjHFiitvoyhfPxsaZnWftrZZZW2txPQK" "proofValue": "zD8RrkKVSVEPYspwCe9T1a68NAVt2GyV566uR6QLdxCMdkg2b4rdUf9w1BC8ZEyhGdEz13kzkBwkjTTvoYAYsy15"
} }]
]
} }

View File

@ -1,33 +1,47 @@
{ {
"@context" : [ "https://www.w3.org/2018/credentials/v1", "https://purl.imsglobal.org/spec/ob/v3p0/context.json", "https://purl.imsglobal.org/spec/ob/v3p0/extensions.json", "https://w3id.org/security/suites/ed25519-2020/v1" ], "@context": [
"id" : "urn:uuid:280c19b6-9680-4a37-ba84-e38b1a4e4584", "https://www.w3.org/ns/credentials/v2",
"type" : [ "VerifiableCredential", "AchievementCredential" ], "https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json",
"issuer" : { "https://purl.imsglobal.org/spec/ob/v3p0/extensions.json"
"type" : [ "Profile" ], ],
"name" : "Andy F. Miller", "id": "urn:uuid:280c19b6-9680-4a37-ba84-e38b1a4e4584",
"id" : "urn:uuid:6f2e33e5-7a29-4155-840a-59483ba10164" "type": [
"VerifiableCredential",
"AchievementCredential"
],
"issuer": {
"type": [
"Profile"
],
"name": "Andy F. Miller",
"id": "urn:uuid:6f2e33e5-7a29-4155-840a-59483ba10164"
}, },
"issuanceDate" : "2022-11-10T07:38:00-08:00", "validFrom": "2022-11-10T07:38:00-08:00",
"name" : "test 1", "name": "test 1",
"credentialSubject" : { "credentialSubject": {
"id" : "urn:uuid:6f2e33e5-7a29-4155-840a-59483ba10164", "id": "urn:uuid:6f2e33e5-7a29-4155-840a-59483ba10164",
"type" : [ "AchievementSubject" ], "type": [
"achievement" : { "AchievementSubject"
"id" : "urn:uuid:35258e6f-4c05-4215-8ada-38a5a5b80510", ],
"type" : [ "Achievement" ], "achievement": {
"achievementType" : "Achievement", "id": "urn:uuid:35258e6f-4c05-4215-8ada-38a5a5b80510",
"name" : "test 1", "type": [
"description" : "This is a test achievement", "Achievement"
"criteria" : { ],
"narrative" : "There is no criteria" "achievementType": "Achievement",
"name": "test 1",
"description": "This is a test achievement",
"criteria": {
"narrative": "There is no criteria"
} }
} }
}, },
"proof" : [ { "proof": [{
"type" : "Ed25519Signature2020", "type": "DataIntegrityProof",
"created" : "2022-11-16T20:39:53Z", "created": "2010-01-01T19:23:24Z",
"proofPurpose" : "assertionMethod", "verificationMethod": "did:key:z6MkjZRZv3aez3r18pB1RBFJR1kwUVJ5jHt92JmQwXbd5hwi",
"verificationMethod" : "did:key:z6MkwAQmEfso8UjHJZTQajRtqR5hDxAD95iJD4z53XnKCFms", "cryptosuite": "eddsa-rdfc-2022",
"proofValue" : "z361ueyGzREPvsWdnWUfkzTKXEd6u2DPPu2kDw3pDERJmzDFCqsuaPneqcRgz2hk9ycaNDYmC4Fy9c6S6BDDt5fVB" "proofPurpose": "assertionMethod",
} ] "proofValue": "z5v2mkEWTLxzJ4VCxvUx5dRoy54Hp81GpyABUk7NswQECwDH6Ecwv5F3Mqso7t18UY6WScm5Qszo6nqiiqmevRWHc"
}]
} }

View File

@ -1,9 +1,7 @@
{ {
"@context": [ "@context": [
"https://www.w3.org/2018/credentials/v1", "https://www.w3.org/ns/credentials/v2",
"https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.1.json", "https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json"
"https://purl.imsglobal.org/spec/ob/v3p0/extensions.json",
"https://w3id.org/security/suites/ed25519-2020/v1"
], ],
"id": "https://dc.1edtech.org/wellspring2022/wellspring-portal/credential/d002b4e9-6fd9-4af0-b1f7-faa9237b46ca", "id": "https://dc.1edtech.org/wellspring2022/wellspring-portal/credential/d002b4e9-6fd9-4af0-b1f7-faa9237b46ca",
"type": [ "type": [
@ -12,22 +10,30 @@
], ],
"issuer": { "issuer": {
"id": "did:web:dc.1edtech.org:wellspring2022:wellspring-portal:org:da1e96e9-afcc-4eed-b9a2-2ddf7353214c", "id": "did:web:dc.1edtech.org:wellspring2022:wellspring-portal:org:da1e96e9-afcc-4eed-b9a2-2ddf7353214c",
"type": ["Profile"], "type": [
"Profile"
],
"address": { "address": {
"type": ["Address"], "type": [
"Address"
],
"addressCountry": "Japan" "addressCountry": "Japan"
}, },
"name": "1EdTech Testing" "name": "1EdTech Testing"
}, },
"awardedDate": "2023-05-22T14:09:00Z", "awardedDate": "2023-05-22T14:09:00Z",
"issuanceDate": "2023-05-23T01:07:22Z", "validFrom": "2023-05-23T01:07:22Z",
"name": "ob3-simple-did-web-method.json", "name": "ob3-simple-did-web-method.json",
"credentialSubject": { "credentialSubject": {
"id": "did:web:dc.1edtech.org:wellspring2022:wellspring-portal:learner:6896f98f-6b42-4c75-98ec-8befd0dc0b29", "id": "did:web:dc.1edtech.org:wellspring2022:wellspring-portal:learner:6896f98f-6b42-4c75-98ec-8befd0dc0b29",
"type": ["AchievementSubject"], "type": [
"AchievementSubject"
],
"achievement": { "achievement": {
"id": "https://dc.1edtech.org/wellspring2022/wellspring-portal/achievement/66457db3-fb3d-4ae3-8f32-bc8c79c9f0db", "id": "https://dc.1edtech.org/wellspring2022/wellspring-portal/achievement/66457db3-fb3d-4ae3-8f32-bc8c79c9f0db",
"type": ["Achievement"], "type": [
"Achievement"
],
"achievementType": "Achievement", "achievementType": "Achievement",
"criteria": { "criteria": {
"narrative": "Passes tests" "narrative": "Passes tests"
@ -37,9 +43,13 @@
}, },
"source": { "source": {
"id": "did:web:dc.1edtech.org:wellspring2022:wellspring-portal:org:da1e96e9-afcc-4eed-b9a2-2ddf7353214c", "id": "did:web:dc.1edtech.org:wellspring2022:wellspring-portal:org:da1e96e9-afcc-4eed-b9a2-2ddf7353214c",
"type": ["Profile"], "type": [
"Profile"
],
"address": { "address": {
"type": ["Address"], "type": [
"Address"
],
"addressCountry": "Japan" "addressCountry": "Japan"
}, },
"name": "1EdTech Testing" "name": "1EdTech Testing"
@ -54,10 +64,11 @@
"type": "1EdTechCredentialRefresh" "type": "1EdTechCredentialRefresh"
}, },
"proof": [{ "proof": [{
"type": "Ed25519Signature2020", "type": "DataIntegrityProof",
"created": "2023-05-23T01:07:22Z", "created": "2010-01-01T19:23:24Z",
"proofPurpose": "assertionMethod",
"verificationMethod": "did:web:dc.1edtech.org:wellspring2022:wellspring-portal:org:da1e96e9-afcc-4eed-b9a2-2ddf7353214c#key-0", "verificationMethod": "did:web:dc.1edtech.org:wellspring2022:wellspring-portal:org:da1e96e9-afcc-4eed-b9a2-2ddf7353214c#key-0",
"proofValue": "z5tVhex5rV9aTxTrGh26uyVdC6BWXG8dQCkzNjgkPWtwAjGzMyYXzrQYJ2XrKUsNpYE3fTXsgUSBwDCY11vbyGBw7" "cryptosuite": "eddsa-rdfc-2022",
"proofPurpose": "assertionMethod",
"proofValue": "z54xk5KNnchymcgxxaTECoREb3n9t8AeUU7AV5mNXhF56D82KPBtoXrPrR9DuEDL5oJtDxL3Cdv42Bt5QCJYcG4gc"
}] }]
} }

View File

@ -1,7 +1,6 @@
{ {
"@context": [ "@context": [
"https://purl.imsglobal.org/spec/ob/v3p0/context.json", "https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json"
"https://w3id.org/security/suites/ed25519-2020/v1"
], ],
"id": "http://example.edu/credentials/3732", "id": "http://example.edu/credentials/3732",
"type": [ "type": [
@ -25,11 +24,12 @@
}, },
"proof": [ "proof": [
{ {
"type": "Ed25519Signature2020", "type": "DataIntegrityProof",
"created": "2022-06-28T16:28:36Z", "created": "2024-03-20T14:53:19Z",
"verificationMethod": "did:key:z6MkkUD3J14nkYzn46QeuaVSnp7dF85QJKwKvJvfsjx79aXj", "verificationMethod": "https://example.com/issuers/876543#z6MkrvfzkMnvCroEUP2DVc9SHPE48CRsvHiVSusHioxTYu1x",
"cryptosuite": "eddsa-rdfc-2022",
"proofPurpose": "assertionMethod", "proofPurpose": "assertionMethod",
"proofValue": "z3MUt2ZuU8Byqivxh6GphEM65AFYyNaGYibm97xLTafM7uGufZQLKvJR8itZwxKskvtFM3CUty46v26DZidMNoQnM" "proofValue": "z76jrNcyxHg5fV17h96yCRwqUaTQZD2QQivyNqHyLSvqu3aWGC3nLShzZEGbH3LnVFodwov9rPQxi3QRP7adCrzV"
} }
] ]
} }

View File

@ -1,8 +1,7 @@
{ {
"@context": [ "@context": [
"https://www.w3.org/2018/credentials/v1", "https://www.w3.org/ns/credentials/v2",
"https://purl.imsglobal.org/spec/ob/v3p0/context.json", "https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json"
"https://w3id.org/security/suites/ed25519-2020/v1"
], ],
"id": "http://example.com/credentials/3527", "id": "http://example.com/credentials/3527",
"type": [ "type": [
@ -16,7 +15,7 @@
], ],
"name": "Example Corp" "name": "Example Corp"
}, },
"issuanceDate": "2010-01-01T00:00:00Z", "validFrom": "2010-01-01T00:00:00Z",
"name": "Teamwork Badge", "name": "Teamwork Badge",
"credentialSubject": { "credentialSubject": {
"id": "did:example:ebfeb1f712ebc6f1c276e12ec21", "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
@ -176,13 +175,12 @@
} }
] ]
}, },
"proof": [ "proof": {
{ "type": "DataIntegrityProof",
"type": "Ed25519Signature2020", "created": "2010-01-01T19:23:24Z",
"created": "2022-11-16T18:54:22Z", "verificationMethod": "https://example.com/issuers/876543#z6MkjZRZv3aez3r18pB1RBFJR1kwUVJ5jHt92JmQwXbd5hwi",
"verificationMethod": "https://example.com/issuers/876543#z6MknNHHrBzPytzu6CUBP9Lg7fg4KSBjzimc2Frh693YbMiv", "cryptosuite": "eddsa-rdfc-2022",
"proofPurpose": "assertionMethod", "proofPurpose": "assertionMethod",
"proofValue": "z5gJZKchSJEYPGeq6bsqiLKuxT6mXqAovPbqYX66CB7u9CSNFdV41vHtysjHFiitvoyhfPxsaZnWftrZZZW2txPQK" "proofValue": "zW2X3KbSiPJ4zmN1GD641owCgz87NjsFpcRpjAdDoPhW7pWvyJUEap3iDKUWovRM43r15Wru6cv8qBVvVgnJxhuH"
}
} }
]
}

View File

@ -1,8 +1,7 @@
{ {
"@context": [ "@context": [
"https://www.w3.org/2018/credentials/v1", "https://www.w3.org/ns/credentials/v2",
"https://purl.imsglobal.org/spec/ob/v3p0/context.json", "https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json"
"https://w3id.org/security/suites/ed25519-2020/v1"
], ],
"id": "http://example.com/credentials/3527", "id": "http://example.com/credentials/3527",
"type": [ "type": [
@ -16,15 +15,17 @@
], ],
"name": "Example Corp" "name": "Example Corp"
}, },
"issuanceDate": "2010-01-01T00:00:00Z", "validFrom": "2010-01-01T00:00:00Z",
"name": "Teamwork Badge", "name": "Teamwork Badge",
"credentialSubject": { "credentialSubject": {
"identifier": [{ "identifier": [
{
"type": "InvalidIdentityObject", "type": "InvalidIdentityObject",
"hashed": true, "hashed": true,
"identityHash": "asdjhsadas", "identityHash": "asdjhsadas",
"identityType": "lisSourcedId" "identityType": "lisSourcedId"
}], }
],
"type": [ "type": [
"AchievementSubject" "AchievementSubject"
], ],
@ -40,13 +41,12 @@
"name": "Teamwork" "name": "Teamwork"
} }
}, },
"proof": [ "proof": {
{ "type": "DataIntegrityProof",
"type": "Ed25519Signature2020", "created": "2010-01-01T19:23:24Z",
"created": "2022-11-16T18:54:22Z", "verificationMethod": "https://example.com/issuers/876543#z6MkjZRZv3aez3r18pB1RBFJR1kwUVJ5jHt92JmQwXbd5hwi",
"verificationMethod": "https://example.com/issuers/876543#z6MknNHHrBzPytzu6CUBP9Lg7fg4KSBjzimc2Frh693YbMiv", "cryptosuite": "eddsa-rdfc-2022",
"proofPurpose": "assertionMethod", "proofPurpose": "assertionMethod",
"proofValue": "z5gJZKchSJEYPGeq6bsqiLKuxT6mXqAovPbqYX66CB7u9CSNFdV41vHtysjHFiitvoyhfPxsaZnWftrZZZW2txPQK" "proofValue": "z5M8kUcxhKZ8niHpZt1LUBLrJGeLMnYaCmwrdR7MrcGzyiGz65zkk59212f7xpd7odxGVDp4e6MvNABsQ8YGn7U98"
}
]
} }
}

View File

@ -1,8 +1,7 @@
{ {
"@context": [ "@context": [
"https://www.w3.org/2018/credentials/v1", "https://www.w3.org/ns/credentials/v2",
"https://purl.imsglobal.org/spec/ob/v3p0/context.json", "https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json"
"https://w3id.org/security/suites/ed25519-2020/v1"
], ],
"id": "http://example.com/credentials/3527", "id": "http://example.com/credentials/3527",
"type": [ "type": [
@ -16,7 +15,7 @@
], ],
"name": "Example Corp" "name": "Example Corp"
}, },
"issuanceDate": "2010-01-01T00:00:00Z", "validFrom": "2010-01-01T00:00:00Z",
"name": "Teamwork Badge", "name": "Teamwork Badge",
"credentialSubject": { "credentialSubject": {
"id": "did:example:ebfeb1f712ebc6f1c276e12ec21", "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
@ -40,13 +39,12 @@
"name": "1EdTech College of Arts" "name": "1EdTech College of Arts"
} }
}, },
"proof": [ "proof": {
{ "type": "DataIntegrityProof",
"type": "Ed25519Signature2020", "created": "2010-01-01T19:23:24Z",
"created": "2022-11-16T18:54:22Z", "verificationMethod": "https://example.com/issuers/876543#z6MkjZRZv3aez3r18pB1RBFJR1kwUVJ5jHt92JmQwXbd5hwi",
"verificationMethod": "https://example.com/issuers/876543#z6MknNHHrBzPytzu6CUBP9Lg7fg4KSBjzimc2Frh693YbMiv", "cryptosuite": "eddsa-rdfc-2022",
"proofPurpose": "assertionMethod", "proofPurpose": "assertionMethod",
"proofValue": "z5gJZKchSJEYPGeq6bsqiLKuxT6mXqAovPbqYX66CB7u9CSNFdV41vHtysjHFiitvoyhfPxsaZnWftrZZZW2txPQK" "proofValue": "z5kJkNSdserQduikVPAfEZ3qMPQRkyvcB7tTaNuxjqNZioQmijmWouvBqSGnAeKKoXAavTk4cxY94iuiEW9boXVyV"
}
} }
]
}

View File

@ -1,8 +1,7 @@
{ {
"@context": [ "@context": [
"https://www.w3.org/2018/credentials/v1", "https://www.w3.org/ns/credentials/v2",
"https://purl.imsglobal.org/spec/ob/v3p0/context.json", "https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json"
"https://w3id.org/security/suites/ed25519-2020/v1"
], ],
"id": "http://example.com/credentials/3527", "id": "http://example.com/credentials/3527",
"type": [ "type": [
@ -16,7 +15,7 @@
], ],
"name": "Example Corp" "name": "Example Corp"
}, },
"issuanceDate": "2010-01-01T00:00:00Z", "validFrom": "2010-01-01T00:00:00Z",
"name": "Teamwork Badge", "name": "Teamwork Badge",
"credentialSubject": { "credentialSubject": {
"id": "did:example:ebfeb1f712ebc6f1c276e12ec21", "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
@ -80,13 +79,12 @@
} }
] ]
}, },
"proof": [ "proof": {
{ "type": "DataIntegrityProof",
"type": "Ed25519Signature2020", "created": "2010-01-01T19:23:24Z",
"created": "2022-11-16T18:54:22Z", "verificationMethod": "https://example.com/issuers/876543#z6MkjZRZv3aez3r18pB1RBFJR1kwUVJ5jHt92JmQwXbd5hwi",
"verificationMethod": "https://example.com/issuers/876543#z6MknNHHrBzPytzu6CUBP9Lg7fg4KSBjzimc2Frh693YbMiv", "cryptosuite": "eddsa-rdfc-2022",
"proofPurpose": "assertionMethod", "proofPurpose": "assertionMethod",
"proofValue": "z5gJZKchSJEYPGeq6bsqiLKuxT6mXqAovPbqYX66CB7u9CSNFdV41vHtysjHFiitvoyhfPxsaZnWftrZZZW2txPQK" "proofValue": "z5YBoPB9tjivuKpRyj9GknLKkReBcpjHxmeR4fGbAppoUpGC2GhbEC8eFdtrnk97ToRPYoQKdtFYDdixGqWXtRpsm"
}
} }
]
}

View File

@ -1,8 +1,7 @@
{ {
"@context": [ "@context": [
"https://www.w3.org/2018/credentials/v1", "https://www.w3.org/ns/credentials/v2",
"https://purl.imsglobal.org/spec/ob/v3p0/context.json", "https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json"
"https://w3id.org/security/suites/ed25519-2020/v1"
], ],
"id": "http://example.com/credentials/3527", "id": "http://example.com/credentials/3527",
"type": [ "type": [
@ -16,7 +15,7 @@
], ],
"name": "Example Corp" "name": "Example Corp"
}, },
"issuanceDate": "2010-01-01T00:00:00Z", "validFrom": "2010-01-01T00:00:00Z",
"name": "Teamwork Badge", "name": "Teamwork Badge",
"credentialSubject": { "credentialSubject": {
"id": "did:example:ebfeb1f712ebc6f1c276e12ec21", "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
@ -35,13 +34,12 @@
"name": "Teamwork" "name": "Teamwork"
} }
}, },
"proof": [ "proof": {
{ "type": "DataIntegrityProof",
"type": "Ed25519Signature2020", "created": "2010-01-01T19:23:24Z",
"created": "2022-11-16T18:54:22Z", "verificationMethod": "https://example.com/issuers/876543#z6MkjZRZv3aez3r18pB1RBFJR1kwUVJ5jHt92JmQwXbd5hwi",
"verificationMethod": "https://example.com/issuers/876543#z6MknNHHrBzPytzu6CUBP9Lg7fg4KSBjzimc2Frh693YbMiv", "cryptosuite": "eddsa-rdfc-2022",
"proofPurpose": "assertionMethod", "proofPurpose": "assertionMethod",
"proofValue": "z5gJZKchSJEYPGeq6bsqiLKuxT6mXqAovPbqYX66CB7u9CSNFdV41vHtysjHFiitvoyhfPxsaZnWftrZZZW2txPQK" "proofValue": "z57amKtkLGz6Gs4s1R7hcgkWzrxayXt7HZ4L5Gt8VBGcM2Z4881fEDARqa8pM2N2dniqXz3U4cC6zW3UBfkQZCfN"
}
]
} }
}

View File

@ -1,8 +1,7 @@
{ {
"@context": [ "@context": [
"https://www.w3.org/2018/credentials/v1", "https://www.w3.org/ns/credentials/v2",
"https://purl.imsglobal.org/spec/ob/v3p0/context.json", "https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json"
"https://w3id.org/security/suites/ed25519-2020/v1"
], ],
"id": "http://example.com/credentials/3527", "id": "http://example.com/credentials/3527",
"type": [ "type": [
@ -16,7 +15,7 @@
], ],
"name": "Example Corp" "name": "Example Corp"
}, },
"issuanceDate": "2010-01-01T00:00:00Z", "validFrom": "2010-01-01T00:00:00Z",
"name": "Teamwork Badge", "name": "Teamwork Badge",
"credentialSubject": { "credentialSubject": {
"id": "did:example:ebfeb1f712ebc6f1c276e12ec21", "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
@ -54,13 +53,12 @@
"audience": "Department" "audience": "Department"
} }
], ],
"proof": [ "proof": {
{ "type": "DataIntegrityProof",
"type": "Ed25519Signature2020", "created": "2010-01-01T19:23:24Z",
"created": "2022-11-16T18:54:22Z", "verificationMethod": "https://example.com/issuers/876543#z6MkjZRZv3aez3r18pB1RBFJR1kwUVJ5jHt92JmQwXbd5hwi",
"verificationMethod": "https://example.com/issuers/876543#z6MknNHHrBzPytzu6CUBP9Lg7fg4KSBjzimc2Frh693YbMiv", "cryptosuite": "eddsa-rdfc-2022",
"proofPurpose": "assertionMethod", "proofPurpose": "assertionMethod",
"proofValue": "z5gJZKchSJEYPGeq6bsqiLKuxT6mXqAovPbqYX66CB7u9CSNFdV41vHtysjHFiitvoyhfPxsaZnWftrZZZW2txPQK" "proofValue": "zbXsNxLTdGdCTdyfkefLRenndjs6QoXnwCYtNbXj4ZtwxrGa2xctb78XrBjuTNK8FKskysBYvMuSzvWYSzfzTXWX"
}
} }
]
}

View File

@ -1,8 +1,7 @@
{ {
"@context": [ "@context": [
"https://www.w3.org/2018/credentials/v1", "https://www.w3.org/ns/credentials/v2",
"https://purl.imsglobal.org/spec/ob/v3p0/context.json", "https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json"
"https://w3id.org/security/suites/ed25519-2020/v1"
], ],
"id": "http://example.com/credentials/3527", "id": "http://example.com/credentials/3527",
"type": [ "type": [
@ -16,8 +15,8 @@
], ],
"name": "Example Corp" "name": "Example Corp"
}, },
"issuanceDate": "2010-01-01T00:00:00Z", "validFrom": "2010-01-01T00:00:00Z",
"expirationDate": "2010-01-01T00:00:00Z", "validUntil": "2010-01-01T00:00:00Z",
"name": "Teamwork Badge", "name": "Teamwork Badge",
"credentialSubject": { "credentialSubject": {
"id": "did:example:ebfeb1f712ebc6f1c276e12ec21", "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
@ -36,13 +35,12 @@
"name": "Teamwork" "name": "Teamwork"
} }
}, },
"proof": [ "proof": [{
{ "type": "DataIntegrityProof",
"type": "Ed25519Signature2020", "created": "2010-01-01T19:23:24Z",
"created": "2022-11-16T18:54:22Z", "verificationMethod": "https://example.com/issuers/876543#z6MkjZRZv3aez3r18pB1RBFJR1kwUVJ5jHt92JmQwXbd5hwi",
"verificationMethod": "https://example.com/issuers/876543#z6MknNHHrBzPytzu6CUBP9Lg7fg4KSBjzimc2Frh693YbMiv", "cryptosuite": "eddsa-rdfc-2022",
"proofPurpose": "assertionMethod", "proofPurpose": "assertionMethod",
"proofValue": "z5gJZKchSJEYPGeq6bsqiLKuxT6mXqAovPbqYX66CB7u9CSNFdV41vHtysjHFiitvoyhfPxsaZnWftrZZZW2txPQK" "proofValue": "z2mAP6ezimojRWSHDhS1VfJgDdMCqa4oPbmJT1tCs43t5bRiwsrrhHxrmTEeAF2EBjErrzxoJj3HCKsdkyVkno11f"
} }]
]
} }

View File

@ -1,8 +1,7 @@
{ {
"@context": [ "@context": [
"https://www.w3.org/2018/credentials/v1", "https://www.w3.org/ns/credentials/v2",
"https://purl.imsglobal.org/spec/ob/v3p0/context.json", "https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json"
"https://w3id.org/security/suites/ed25519-2020/v1"
], ],
"id": "http://example.edu/credentials/3732", "id": "http://example.edu/credentials/3732",
"type": [ "type": [
@ -16,8 +15,8 @@
], ],
"name": "Example University" "name": "Example University"
}, },
"issuanceDate": "2040-01-01T00:00:00Z", "validFrom": "2040-01-01T00:00:00Z",
"expirationDate": "2050-01-20T00:00:00Z", "validUntil": "2050-01-20T00:00:00Z",
"name": "Example University Degree", "name": "Example University Degree",
"credentialSubject": { "credentialSubject": {
"id": "did:example:ebfeb1f712ebc6f1c276e12ec21", "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
@ -25,13 +24,12 @@
"AchievementSubject" "AchievementSubject"
] ]
}, },
"proof": [ "proof": {
{ "type": "DataIntegrityProof",
"type": "Ed25519Signature2020", "created": "2010-01-01T19:23:24Z",
"created": "2022-06-28T16:28:36Z", "verificationMethod": "https://example.edu/issuers/565049#z6MkjZRZv3aez3r18pB1RBFJR1kwUVJ5jHt92JmQwXbd5hwi",
"verificationMethod": "did:key:z6MkkUD3J14nkYzn46QeuaVSnp7dF85QJKwKvJvfsjx79aXj", "cryptosuite": "eddsa-rdfc-2022",
"proofPurpose": "assertionMethod", "proofPurpose": "assertionMethod",
"proofValue": "z3MUt2ZuU8Byqivxh6GphEM65AFYyNaGYibm97xLTafM7uGufZQLKvJR8itZwxKskvtFM3CUty46v26DZidMNoQnM" "proofValue": "z5EUB8AAu98Tdagjaf6QP7zY7MovnYTEB6vnNBgWjaCtaiNQfqNLQmEPpxvQuQPmVfQ49wcadz3DNUDk4CAt79HaF"
} }
]
} }

View File

@ -1,8 +1,7 @@
{ {
"@context": [ "@context": [
"https://www.w3.org/2018/credentials/v1", "https://www.w3.org/ns/credentials/v2",
"https://purl.imsglobal.org/spec/ob/v3p0/context.json", "https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json"
"https://w3id.org/security/suites/ed25519-2020/v1"
], ],
"id": "http://example.com/credentials/3527", "id": "http://example.com/credentials/3527",
"type": [ "type": [
@ -28,7 +27,7 @@
} }
] ]
}, },
"issuanceDate": "2010-01-01T00:00:00Z", "validFrom": "2010-01-01T00:00:00Z",
"name": "Teamwork Badge", "name": "Teamwork Badge",
"credentialSubject": { "credentialSubject": {
"id": "did:example:ebfeb1f712ebc6f1c276e12ec21", "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
@ -47,13 +46,12 @@
"name": "Teamwork" "name": "Teamwork"
} }
}, },
"proof": [ "proof": {
{ "type": "DataIntegrityProof",
"type": "Ed25519Signature2020", "created": "2010-01-01T19:23:24Z",
"created": "2022-11-16T18:54:22Z", "verificationMethod": "https://example.com/issuers/876543#z6MkjZRZv3aez3r18pB1RBFJR1kwUVJ5jHt92JmQwXbd5hwi",
"verificationMethod": "https://example.com/issuers/876543#z6MknNHHrBzPytzu6CUBP9Lg7fg4KSBjzimc2Frh693YbMiv", "cryptosuite": "eddsa-rdfc-2022",
"proofPurpose": "assertionMethod", "proofPurpose": "assertionMethod",
"proofValue": "z5gJZKchSJEYPGeq6bsqiLKuxT6mXqAovPbqYX66CB7u9CSNFdV41vHtysjHFiitvoyhfPxsaZnWftrZZZW2txPQK" "proofValue": "z3y8SeYGgaCjgeqe5vbKv9egn5zxHPoFNDYRXa9pHPxMua2P9PEinYmmjq12FqXYr272DhKj6tvBTCzvx3KRc8ys8"
}
} }
]
}

View File

@ -1,8 +1,7 @@
{ {
"@context": [ "@context": [
"https://www.w3.org/2018/credentials/v1", "https://www.w3.org/ns/credentials/v2",
"https://purl.imsglobal.org/spec/ob/v3p0/context.json", "https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json"
"https://w3id.org/security/suites/ed25519-2020/v1"
], ],
"id": "http://example.com/credentials/3527", "id": "http://example.com/credentials/3527",
"type": [ "type": [
@ -23,7 +22,7 @@
"name": "Example Parent Corp" "name": "Example Parent Corp"
} }
}, },
"issuanceDate": "2010-01-01T00:00:00Z", "validFrom": "2010-01-01T00:00:00Z",
"name": "Teamwork Badge", "name": "Teamwork Badge",
"credentialSubject": { "credentialSubject": {
"id": "did:example:ebfeb1f712ebc6f1c276e12ec21", "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
@ -42,13 +41,12 @@
"name": "Teamwork" "name": "Teamwork"
} }
}, },
"proof": [ "proof": {
{ "type": "DataIntegrityProof",
"type": "Ed25519Signature2020", "created": "2010-01-01T19:23:24Z",
"created": "2022-11-16T18:54:22Z", "verificationMethod": "https://example.com/issuers/876543#z6MkjZRZv3aez3r18pB1RBFJR1kwUVJ5jHt92JmQwXbd5hwi",
"verificationMethod": "https://example.com/issuers/876543#z6MknNHHrBzPytzu6CUBP9Lg7fg4KSBjzimc2Frh693YbMiv", "cryptosuite": "eddsa-rdfc-2022",
"proofPurpose": "assertionMethod", "proofPurpose": "assertionMethod",
"proofValue": "z5gJZKchSJEYPGeq6bsqiLKuxT6mXqAovPbqYX66CB7u9CSNFdV41vHtysjHFiitvoyhfPxsaZnWftrZZZW2txPQK" "proofValue": "z3f57gU5zssuyZTW2HxK2tV6qXCHyE3xdCHCczsUoRMSDBooCGboVBWUZygqpqskN5Mmpww8Qu3JARf1YvGcCzE34"
}
} }
]
}

View File

@ -1,8 +1,7 @@
{ {
"@context": [ "@context": [
"https://www.w3.org/2018/credentials/v1", "https://www.w3.org/ns/credentials/v2",
"https://purl.imsglobal.org/spec/ob/v3p0/context.json", "https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json"
"https://w3id.org/security/suites/ed25519-2020/v1"
], ],
"id": "http://example.com/credentials/3527", "id": "http://example.com/credentials/3527",
"type": [ "type": [
@ -16,7 +15,7 @@
], ],
"name": "Example Corp" "name": "Example Corp"
}, },
"issuanceDate": "2010-01-01T00:00:00Z", "validFrom": "2010-01-01T00:00:00Z",
"name": "Teamwork Badge", "name": "Teamwork Badge",
"credentialSubject": { "credentialSubject": {
"id": "did:example:ebfeb1f712ebc6f1c276e12ec21", "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
@ -35,13 +34,12 @@
"name": "Teamwork" "name": "Teamwork"
} }
}, },
"proof": [ "proof": {
{ "type": "DataIntegrityProof",
"type": "Ed25519Signature2020", "created": "2010-01-01T19:23:24Z",
"created": "2022-11-16T18:54:22Z", "verificationMethod": "https://example.com/issuers/876543#z6MkjZRZv3aez3r18pB1RBFJR1kwUVJ5jHt92JmQwXbd5hwi",
"verificationMethod": "https://example.com/issuers/876543#z6MknNHHrBzPytzu6CUBP9Lg7fg4KSBjzimc2Frh693YbMiv", "cryptosuite": "eddsa-rdfc-2022",
"proofPurpose": "assertionMethod", "proofPurpose": "assertionMethod",
"proofValue": "z5gJZKchSJEYPGeq6bsqiLKuxT6mXqAovPbqYX66CB7u9CSNFdV41vHtysjHFiitvoyhfPxsaZnWftrZZZW2txPQK" "proofValue": "z2t8HUUbHs1G3o5t1uCTA7kbdprP21W9xmf8qJaDBWBoHSBFvJB26Bdq7Fi1ko2cnaHAvXETdMX6dPGFSA2rTP4KW"
}
} }
]
}

View File

@ -1,15 +1,14 @@
{ {
"@context": [ "@context": [
"https://www.w3.org/2018/credentials/v1", "https://www.w3.org/ns/credentials/v2",
"https://purl.imsglobal.org/spec/ob/v3p0/context.json", "https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json"
"https://w3id.org/security/suites/ed25519-2020/v1"
], ],
"id": "http://example.edu/credentials/3732", "id": "http://example.edu/credentials/3732",
"type": [ "type": [
"VerifiableCredential", "VerifiableCredential",
"OpenBadgeCredential" "OpenBadgeCredential"
], ],
"issuanceDate": "2010-01-01T00:00:00Z", "validFrom": "2010-01-01T00:00:00Z",
"name": "Example University Degree", "name": "Example University Degree",
"credentialSubject": { "credentialSubject": {
"id": "did:example:ebfeb1f712ebc6f1c276e12ec21", "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
@ -17,13 +16,12 @@
"AchievementSubject" "AchievementSubject"
] ]
}, },
"proof": [ "proof": {
{ "type": "DataIntegrityProof",
"type": "Ed25519Signature2020", "created": "2010-01-01T19:23:24Z",
"created": "2022-06-28T16:28:36Z", "verificationMethod": "https://example.com/issuers/876543#z6MkjZRZv3aez3r18pB1RBFJR1kwUVJ5jHt92JmQwXbd5hwi",
"verificationMethod": "did:key:z6MkkUD3J14nkYzn46QeuaVSnp7dF85QJKwKvJvfsjx79aXj", "cryptosuite": "eddsa-rdfc-2022",
"proofPurpose": "assertionMethod", "proofPurpose": "assertionMethod",
"proofValue": "z3MUt2ZuU8Byqivxh6GphEM65AFYyNaGYibm97xLTafM7uGufZQLKvJR8itZwxKskvtFM3CUty46v26DZidMNoQnM" "proofValue": "z5ZjnJNPeQznivpmedtQZDAy9vXVz2BbhZp13fGpTfMnsgzccs2Z3Se2BRWeECSMo92cUsQP63LhMb6veWuD223j2"
} }
]
} }

View File

@ -1,33 +1,23 @@
{ {
"@context": [ "@context": [
"https://www.w3.org/2018/credentials/v1", "https://www.w3.org/ns/credentials/v2",
"https://purl.imsglobal.org/spec/ob/v3p0/context.json", "https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json"
"https://w3id.org/security/suites/ed25519-2020/v1"
], ],
"id": "http://example.com/credentials/3527", "id": "http://example.com/credentials/3527",
"type": [ "type": ["VerifiableCredential", "OpenBadgeCredential"],
"VerifiableCredential",
"OpenBadgeCredential"
],
"issuer": { "issuer": {
"id": "https://example.com/issuers/876543", "id": "https://example.com/issuers/876543",
"type": [ "type": ["Profile"],
"Profile"
],
"name": "Example Corp" "name": "Example Corp"
}, },
"issuanceDate": "2010-01-01T00:00:00Z", "validFrom": "2010-01-01T00:00:00Z",
"name": "Teamwork Badge", "name": "Teamwork Badge",
"credentialSubject": { "credentialSubject": {
"id": "did:example:ebfeb1f712ebc6f1c276e12ec21", "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
"type": [ "type": ["AchievementSubject"],
"AchievementSubject"
],
"achievement": { "achievement": {
"id": "https://example.com/achievements/21st-century-skills/teamwork", "id": "https://example.com/achievements/21st-century-skills/teamwork",
"type": [ "type": ["Achievement"],
"Achievement"
],
"criteria": { "criteria": {
"narrative": "Team members are nominated for this badge by their peers and recognized upon review by Example Corp management." "narrative": "Team members are nominated for this badge by their peers and recognized upon review by Example Corp management."
}, },
@ -37,11 +27,12 @@
}, },
"proof": [ "proof": [
{ {
"type": "Ed25519Signature2020", "type": "DataIntegrityProof",
"created": "2022-11-16T18:54:22Z", "created": "2024-03-20T14:53:19Z",
"verificationMethod": "z6MknNHHrBzPytzu6CUBP9Lg7fg4KSBjzimc2Frh693YbMiv", "verificationMethod": "z6MkrvfzkMnvCroEUP2DVc9SHPE48CRsvHiVSusHioxTYu1x",
"cryptosuite": "eddsa-rdfc-2022",
"proofPurpose": "assertionMethod", "proofPurpose": "assertionMethod",
"proofValue": "z5gJZKchSJEYPGeq6bsqiLKuxT6mXqAovPbqYX66CB7u9CSNFdV41vHtysjHFiitvoyhfPxsaZnWftrZZZW2txPQK" "proofValue": "z76jrNcyxHg5fV17h96yCRwqUaTQZD2QQivyNqHyLSvqu3aWGC3nLShzZEGbH3LnVFodwov9rPQxi3QRP7adCrzV"
} }
] ]
} }

View File

@ -1,33 +1,23 @@
{ {
"@context": [ "@context": [
"https://www.w3.org/2018/credentials/v1", "https://www.w3.org/ns/credentials/v2",
"https://purl.imsglobal.org/spec/ob/v3p0/context.json", "https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json"
"https://w3id.org/security/suites/ed25519-2020/v1"
], ],
"id": "http://example.com/credentials/3527", "id": "http://example.com/credentials/3527",
"type": [ "type": ["VerifiableCredential", "OpenBadgeCredential"],
"VerifiableCredential",
"OpenBadgeCredential"
],
"issuer": { "issuer": {
"id": "https://example.com/issuers/876543", "id": "https://example.com/issuers/876543",
"type": [ "type": ["Profile"],
"Profile"
],
"name": "Example Corp" "name": "Example Corp"
}, },
"issuanceDate": "2010-01-01T00:00:00Z", "validFrom": "2010-01-01T00:00:00Z",
"name": "Teamwork Badge", "name": "Teamwork Badge",
"credentialSubject": { "credentialSubject": {
"id": "did:example:ebfeb1f712ebc6f1c276e12ec21", "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
"type": [ "type": ["AchievementSubject"],
"AchievementSubject"
],
"achievement": { "achievement": {
"id": "https://example.com/achievements/21st-century-skills/teamwork", "id": "https://example.com/achievements/21st-century-skills/teamwork",
"type": [ "type": ["Achievement"],
"Achievement"
],
"criteria": { "criteria": {
"narrative": "Team members are nominated for this badge by their peers and recognized upon review by Example Corp management." "narrative": "Team members are nominated for this badge by their peers and recognized upon review by Example Corp management."
}, },
@ -37,11 +27,12 @@
}, },
"proof": [ "proof": [
{ {
"type": "Ed25519Signature2020", "type": "DataIntegrityProof",
"created": "2022-11-16T18:54:22Z", "created": "2024-03-20T14:53:19Z",
"verificationMethod": "did:example:z6MknNHHrBzPytzu6CUBP9Lg7fg4KSBjzimc2Frh693YbMiv", "verificationMethod": "did:example:z6MkrvfzkMnvCroEUP2DVc9SHPE48CRsvHiVSusHioxTYu1x",
"cryptosuite": "eddsa-rdfc-2022",
"proofPurpose": "assertionMethod", "proofPurpose": "assertionMethod",
"proofValue": "z5gJZKchSJEYPGeq6bsqiLKuxT6mXqAovPbqYX66CB7u9CSNFdV41vHtysjHFiitvoyhfPxsaZnWftrZZZW2txPQK" "proofValue": "z76jrNcyxHg5fV17h96yCRwqUaTQZD2QQivyNqHyLSvqu3aWGC3nLShzZEGbH3LnVFodwov9rPQxi3QRP7adCrzV"
} }
] ]
} }

View File

@ -1,33 +1,23 @@
{ {
"@context": [ "@context": [
"https://www.w3.org/2018/credentials/v1", "https://www.w3.org/ns/credentials/v2",
"https://purl.imsglobal.org/spec/ob/v3p0/context.json", "https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json"
"https://w3id.org/security/suites/ed25519-2020/v1"
], ],
"id": "http://example.com/credentials/3527", "id": "http://example.com/credentials/3527",
"type": [ "type": ["VerifiableCredential", "OpenBadgeCredential"],
"VerifiableCredential",
"OpenBadgeCredential"
],
"issuer": { "issuer": {
"id": "https://example.com/issuers/876543", "id": "https://example.com/issuers/876543",
"type": [ "type": ["Profile"],
"Profile"
],
"name": "Example Corp" "name": "Example Corp"
}, },
"issuanceDate": "2010-01-01T00:00:00Z", "validFrom": "2010-01-01T00:00:00Z",
"name": "Teamwork Badge", "name": "Teamwork Badge",
"credentialSubject": { "credentialSubject": {
"id": "did:example:ebfeb1f712ebc6f1c276e12ec21", "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
"type": [ "type": ["AchievementSubject"],
"AchievementSubject"
],
"achievement": { "achievement": {
"id": "https://example.com/achievements/21st-century-skills/teamwork", "id": "https://example.com/achievements/21st-century-skills/teamwork",
"type": [ "type": ["Achievement"],
"Achievement"
],
"criteria": { "criteria": {
"narrative": "Team members are nominated for this badge by their peers and recognized upon review by Example Corp management." "narrative": "Team members are nominated for this badge by their peers and recognized upon review by Example Corp management."
}, },
@ -37,11 +27,12 @@
}, },
"proof": [ "proof": [
{ {
"type": "Ed25519Signature2020", "type": "DataIntegrityProof",
"created": "2022-11-16T18:54:22Z", "created": "2024-03-20T14:53:19Z",
"verificationMethod": "xxx:z6MknNHHrBzPytzu6CUBP9Lg7fg4KSBjzimc2Frh693YbMiv", "verificationMethod": "xxx:z6MkrvfzkMnvCroEUP2DVc9SHPE48CRsvHiVSusHioxTYu1x",
"cryptosuite": "eddsa-rdfc-2022",
"proofPurpose": "assertionMethod", "proofPurpose": "assertionMethod",
"proofValue": "z5gJZKchSJEYPGeq6bsqiLKuxT6mXqAovPbqYX66CB7u9CSNFdV41vHtysjHFiitvoyhfPxsaZnWftrZZZW2txPQK" "proofValue": "z76jrNcyxHg5fV17h96yCRwqUaTQZD2QQivyNqHyLSvqu3aWGC3nLShzZEGbH3LnVFodwov9rPQxi3QRP7adCrzV"
} }
] ]
} }

View File

@ -1,9 +1,8 @@
{ {
"@context": [ "@context": [
"https://www.w3.org/2018/credentials/v1", "https://www.w3.org/ns/credentials/v2",
"https://purl.imsglobal.org/spec/ob/v3p0/context.json", "https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json",
"https://purl.imsglobal.org/spec/ob/v3p0/extensions.json", "https://purl.imsglobal.org/spec/ob/v3p0/extensions.json"
"https://w3id.org/security/suites/ed25519-2020/v1"
], ],
"id": "http://example.edu/credentials/3732", "id": "http://example.edu/credentials/3732",
"type": [ "type": [
@ -17,7 +16,7 @@
], ],
"name": "Example University" "name": "Example University"
}, },
"issuanceDate": "2010-01-01T00:00:00Z", "validFrom": "2010-01-01T00:00:00Z",
"name": "Example University Degree", "name": "Example University Degree",
"credentialSubject": { "credentialSubject": {
"id": "did:example:ebfeb1f712ebc6f1c276e12ec21", "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
@ -42,13 +41,12 @@
"type": "1EdTechJsonSchemaValidator2019" "type": "1EdTechJsonSchemaValidator2019"
} }
], ],
"proof": [ "proof": {
{ "type": "DataIntegrityProof",
"type": "Ed25519Signature2020", "created": "2010-01-01T19:23:24Z",
"created": "2022-09-15T15:48:32Z", "verificationMethod": "https://example.edu/issuers/565049#z6MkjZRsdasZv3aez3r18pB1RBFJR1kwUVJ5jHt92JmQwXbd5hwi",
"verificationMethod": "https://example.edu/issuers/565049#xxMkmY1R6tG2NEdRHzphdRT6JqxeYpHwLAHwbrDfQULpkMAj", "cryptosuite": "eddsa-rdfc-2022",
"proofPurpose": "assertionMethod", "proofPurpose": "assertionMethod",
"proofValue": "z3yUuWbFsLUp2CUrSZRaRbTk1UnkhpoJgJYu1SdMqd3AEMotpY41sKky7VzavnSfjApggtWJg1tcREvs5H4ZNnBRH" "proofValue": "z4HwAsa7GvwL7so7CoQ8v3ShzykRPCq8pfkAFKuAPrJx28S69pXphpqL8ApjoxEcMaqbgkaCUyKuEohhGXBR4Fh3L"
} }
]
} }

View File

@ -1,34 +1,23 @@
{ {
"@context": [ "@context": [
"https://www.w3.org/2018/credentials/v1", "https://www.w3.org/ns/credentials/v2",
"https://purl.imsglobal.org/spec/ob/v3p0/context.json", "https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json"
"https://purl.imsglobal.org/spec/ob/v3p0/extensions.json",
"https://w3id.org/security/suites/ed25519-2020/v1"
],
"id": "http://example.edu/credentials/3732",
"type": [
"VerifiableCredential",
"OpenBadgeCredential"
], ],
"id": "http://example.com/credentials/3527",
"type": ["VerifiableCredential", "OpenBadgeCredential"],
"issuer": { "issuer": {
"id": "https://example.edu/issuers/565049", "id": "https://example.com/issuers/876543",
"type": [ "type": ["Profile"],
"Profile" "name": "Example Corp"
],
"name": "Example University"
}, },
"issuanceDate": "2010-01-01T00:00:00Z", "validFrom": "2010-01-01T00:00:00Z",
"name": "Example University Degree", "name": "Teamwork Badge",
"credentialSubject": { "credentialSubject": {
"id": "did:example:ebfeb1f712ebc6f1c276e12ec21", "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
"type": [ "type": ["AchievementSubject"],
"AchievementSubject"
],
"achievement": { "achievement": {
"id": "https://example.com/achievements/21st-century-skills/teamwork", "id": "https://example.com/achievements/21st-century-skills/teamwork",
"type": [ "type": ["Achievement"],
"Achievement"
],
"criteria": { "criteria": {
"narrative": "Team members are nominated for this badge by their peers and recognized upon review by Example Corp management." "narrative": "Team members are nominated for this badge by their peers and recognized upon review by Example Corp management."
}, },
@ -36,19 +25,14 @@
"name": "Teamwork" "name": "Teamwork"
} }
}, },
"credentialSchema": [
{
"id": "https://purl.imsglobal.org/spec/ob/v3p0/schema/json/ob_v3p0_achievementcredential_schema.json",
"type": "1EdTechJsonSchemaValidator2019"
}
],
"proof": [ "proof": [
{ {
"type": "Ed25519Signature2020", "type": "DataIntegrityProof",
"created": "2022-09-15T15:48:32Z", "created": "2024-03-20T14:53:19Z",
"verificationMethod": "https://example.edu/issuers/565049#z6MkmY1R6tG2NEdRHzphdRT6JqxeYpHwLAHwbrDfQULpkMAj", "verificationMethod": "https://example.com/issuers/876543#z6MkrvfzkMnvCroEUP2DVc9SHPE48CRsvHiVSusHioxTYu1x",
"cryptosuite": "eddsa-rdfc-2022",
"proofPurpose": "assertionMethod", "proofPurpose": "assertionMethod",
"proofValue": "z3fQCWGpz7b1HSH6DTwYiH5vutqtpJb5SHiP1VFK22xeBEW2D61tC9j3SktwPLNxPnTNZnPt4GeAZJPdVYserRqs4" "proofValue": "z76jrNcyxHg5fV17h96yCRwqUaTQZD2QQivyNqHyLSvqu3aWGC3nLShzZEGbH3LvNFodwov9rPQxi3QRP7adCrzV"
} }
] ]
} }

View File

@ -1,8 +1,7 @@
{ {
"@context": [ "@context": [
"https://www.w3.org/2018/credentials/v1", "https://www.w3.org/ns/credentials/v2",
"https://purl.imsglobal.org/spec/ob/v3p0/context.json", "https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json"
"https://w3id.org/security/suites/ed25519-2020/v1"
], ],
"id": "http://example.edu/credentials/3732", "id": "http://example.edu/credentials/3732",
"type": [ "type": [
@ -16,7 +15,7 @@
], ],
"name": "Example University" "name": "Example University"
}, },
"issuanceDate": "2010-01-01T00:00:00Z", "validFrom": "2010-01-01T00:00:00Z",
"name": "Example University Degree", "name": "Example University Degree",
"credentialSubject": { "credentialSubject": {
"id": "did:example:ebfeb1f712ebc6f1c276e12ec21", "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
@ -24,13 +23,12 @@
"AchievementSubject" "AchievementSubject"
] ]
}, },
"proof": [ "proof": {
{ "type": "DataIntegrityProof",
"type": "Ed25519Signature2020", "created": "2010-01-01T19:23:24Z",
"created": "2022-06-09T22:56:28Z", "verificationMethod": "https://example.edu/issuers/565049#z6MkjZRZv3aez3r18pB1RBFJR1kwUVJ5jHt92JmQwXbd5hwi",
"verificationMethod": "https://example.edu/issuers/565049#key-1", "cryptosuite": "eddsa-rdfc-2022",
"proofPurpose": "assertionMethod", "proofPurpose": "assertionMethod",
"proofValue": "z58ieJCh4kN6eE2Vq4TyYURKSC4hWWEK7b75NNUL2taZMhKqwTteuByG1wRoGDdCqqNLW5Gq1diUi4qyZ63tQRtyN" "proofValue": "z662W1sSqKoA8ryTKK7PPVGKRrBkx5id3aDvdFNtguJcVFHJggDnkwJFntbo2cWfSwumCh9mgcYUe2RgpK1GZFyxa"
}
]
} }
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

After

Width:  |  Height:  |  Size: 82 KiB

View File

@ -5,34 +5,24 @@
<![CDATA[ <![CDATA[
{ {
"@context": [ "@context": [
"https://www.w3.org/2018/credentials/v1", "https://www.w3.org/ns/credentials/v2",
"https://purl.imsglobal.org/spec/ob/v3p0/context.json", "https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json"
"https://w3id.org/security/suites/ed25519-2020/v1"
], ],
"id": "http://example.com/credentials/3527", "id": "http://example.com/credentials/3527",
"type": [ "type": ["VerifiableCredential", "OpenBadgeCredential"],
"VerifiableCredential",
"OpenBadgeCredential"
],
"issuer": { "issuer": {
"id": "https://example.com/issuers/876543", "id": "https://example.com/issuers/876543",
"type": [ "type": ["Profile"],
"Profile"
],
"name": "Example Corp" "name": "Example Corp"
}, },
"issuanceDate": "2010-01-01T00:00:00Z", "validFrom": "2010-01-01T00:00:00Z",
"name": "Teamwork Badge", "name": "Teamwork Badge",
"credentialSubject": { "credentialSubject": {
"id": "did:example:ebfeb1f712ebc6f1c276e12ec21", "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
"type": [ "type": ["AchievementSubject"],
"AchievementSubject"
],
"achievement": { "achievement": {
"id": "https://example.com/achievements/21st-century-skills/teamwork", "id": "https://example.com/achievements/21st-century-skills/teamwork",
"type": [ "type": ["Achievement"],
"Achievement"
],
"criteria": { "criteria": {
"narrative": "Team members are nominated for this badge by their peers and recognized upon review by Example Corp management." "narrative": "Team members are nominated for this badge by their peers and recognized upon review by Example Corp management."
}, },
@ -42,11 +32,12 @@
}, },
"proof": [ "proof": [
{ {
"type": "Ed25519Signature2020", "type": "DataIntegrityProof",
"created": "2022-11-16T18:54:22Z", "created": "2024-03-20T14:53:19Z",
"verificationMethod": "https://example.com/issuers/876543#z6MknNHHrBzPytzu6CUBP9Lg7fg4KSBjzimc2Frh693YbMiv", "verificationMethod": "https://example.com/issuers/876543#z6MkrvfzkMnvCroEUP2DVc9SHPE48CRsvHiVSusHioxTYu1x",
"cryptosuite": "eddsa-rdfc-2022",
"proofPurpose": "assertionMethod", "proofPurpose": "assertionMethod",
"proofValue": "z5gJZKchSJEYPGeq6bsqiLKuxT6mXqAovPbqYX66CB7u9CSNFdV41vHtysjHFiitvoyhfPxsaZnWftrZZZW2txPQK" "proofValue": "z76jrNcyxHg5fV17h96yCRwqUaTQZD2QQivyNqHyLSvqu3aWGC3nLShzZEGbH3LnVFodwov9rPQxi3QRP7adCrzV"
} }
] ]
} }

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

@ -1,8 +1,7 @@
{ {
"@context": [ "@context": [
"https://www.w3.org/2018/credentials/v1", "https://www.w3.org/ns/credentials/v2",
"https://purl.imsglobal.org/spec/ob/v3p0/context.json", "https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json"
"https://w3id.org/security/suites/ed25519-2020/v1"
], ],
"id": "http://example.com/credentials/3527", "id": "http://example.com/credentials/3527",
"type": [ "type": [
@ -16,7 +15,7 @@
], ],
"name": "Example Corp" "name": "Example Corp"
}, },
"issuanceDate": "2010-01-01T00:00:00Z", "validFrom": "2010-01-01T00:00:00Z",
"name": "Teamwork Badge", "name": "Teamwork Badge",
"credentialSubject": { "credentialSubject": {
"id": "did:example:ebfeb1f712ebc6f1c276e12ec21", "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
@ -35,17 +34,19 @@
"name": "Teamwork" "name": "Teamwork"
} }
}, },
"proof": [{ "proof": [
{
"type": "SomeProofType", "type": "SomeProofType",
"created": "2022-11-16T18:54:22Z", "created": "2022-11-16T18:54:22Z",
"proofPurpose": "assertionMethod" "proofPurpose": "assertionMethod"
}, },
{ {
"type": "Ed25519Signature2020", "type": "DataIntegrityProof",
"created": "2022-11-16T18:54:22Z", "created": "2010-01-01T19:23:24Z",
"verificationMethod": "https://example.com/issuers/876543#z6MknNHHrBzPytzu6CUBP9Lg7fg4KSBjzimc2Frh693YbMiv", "verificationMethod": "https://example.com/issuers/876543#z6MkjZRZv3aez3r18pB1RBFJR1kwUVJ5jHt92JmQwXbd5hwi",
"cryptosuite": "eddsa-rdfc-2022",
"proofPurpose": "assertionMethod", "proofPurpose": "assertionMethod",
"proofValue": "z5gJZKchSJEYPGeq6bsqiLKuxT6mXqAovPbqYX66CB7u9CSNFdV41vHtysjHFiitvoyhfPxsaZnWftrZZZW2txPQK" "proofValue": "z41ZsNkz78FHSGkAD5J4b8EN49DkywMMJSL3UdUNffbsCAWmTLPvtnJpd3JGGooYX7TNrzgsTLkXUWiGsRRZ788ML"
} }
] ]
} }

View File

@ -1,8 +1,7 @@
{ {
"@context": [ "@context": [
"https://www.w3.org/2018/credentials/v1", "https://www.w3.org/ns/credentials/v2",
"https://purl.imsglobal.org/spec/ob/v3p0/context.json", "https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json"
"https://w3id.org/security/suites/ed25519-2020/v1"
], ],
"id": "http://example.com/credentials/3527", "id": "http://example.com/credentials/3527",
"type": [ "type": [
@ -16,7 +15,7 @@
], ],
"name": "Example Corp" "name": "Example Corp"
}, },
"issuanceDate": "2010-01-01T00:00:00Z", "validFrom": "2010-01-01T00:00:00Z",
"name": "Teamwork Badge", "name": "Teamwork Badge",
"credentialSubject": { "credentialSubject": {
"id": "did:example:ebfeb1f712ebc6f1c276e12ec21", "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
@ -35,13 +34,12 @@
"name": "Teamwork" "name": "Teamwork"
} }
}, },
"proof": [ "proof": [{
{ "type": "DataIntegrityProof",
"type": "Ed25519Signature2020", "created": "2010-01-01T19:23:24Z",
"created": "2022-11-16T18:54:22Z", "verificationMethod": "https://example.com/issuers/876543#z6MkjZRZv3aez3r18pB1RBFJR1kwUVJ5jHt92JmQwXbd5hwi",
"verificationMethod": "https://example.com/issuers/876543#z6MknNHHrBzPytzu6CUBP9Lg7fg4KSBjzimc2Frh693YbMiv", "cryptosuite": "eddsa-rdfc-2022",
"proofPurpose": "assertionMethod", "proofPurpose": "assertionMethod",
"proofValue": "z5gJZKchSJEYPGeq6bsqiLKuxT6mXqAovPbqYX66CB7u9CSNFdV41vHtysjHFiitvoyhfPxsaZnWftrZZZW2txPQK" "proofValue": "z41ZsNkz78FHSGkAD5J4b8EN49DkywMMJSL3UdUNffbsCAWmTLPvtnJpd3JGGooYX7TNrzgsTLkXUWiGsRRZ788ML"
} }]
]
} }

View File

@ -0,0 +1,38 @@
{
"@context": [
"https://www.w3.org/2018/credentials/v1",
"https://purl.imsglobal.org/spec/ob/v3p0/context.json",
"https://w3id.org/security/suites/ed25519-2020/v1"
],
"id": "http://example.com/credentials/3527",
"type": ["VerifiableCredential", "OpenBadgeCredential"],
"issuer": {
"id": "https://example.com/issuers/876543",
"type": ["Profile"],
"name": "Example Corp"
},
"issuanceDate": "2010-01-01T00:00:00Z",
"name": "Teamwork Badge",
"credentialSubject": {
"id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
"type": ["AchievementSubject"],
"achievement": {
"id": "https://example.com/achievements/21st-century-skills/teamwork",
"type": ["Achievement"],
"criteria": {
"narrative": "Team members are nominated for this badge by their peers and recognized upon review by Example Corp management."
},
"description": "This badge recognizes the development of the capacity to collaborate within a group environment.",
"name": "Teamwork"
}
},
"proof": [
{
"type": "Ed25519Signature2020",
"created": "2022-11-16T18:54:22Z",
"verificationMethod": "https://example.com/issuers/876543#z6MknNHHrBzPytzu6CUBP9Lg7fg4KSBjzimc2Frh693YbMiv",
"proofPurpose": "assertionMethod",
"proofValue": "z5gJZKchSJEYPGeq6bsqiLKuxT6mXqAovPbqYX66CB7u9CSNFdV41vHtysjHFiitvoyhfPxsaZnWftrZZZW2txPQK"
}
]
}

View File

@ -7,7 +7,7 @@
<groupId>org.1edtech</groupId> <groupId>org.1edtech</groupId>
<artifactId>vc-public-validator</artifactId> <artifactId>vc-public-validator</artifactId>
<version>1.0.4</version> <version>1.0.5</version>
<name>vc-public-validator</name> <name>vc-public-validator</name>
<packaging>pom</packaging> <packaging>pom</packaging>
<developers> <developers>
@ -22,7 +22,7 @@
<java.version>11</java.version> <java.version>11</java.version>
<log4j.version>2.17.2</log4j.version> <log4j.version>2.17.2</log4j.version>
<skipTests>false</skipTests> <skipTests>false</skipTests>
<public.core.version>1.0.4</public.core.version> <public.core.version>1.0.6</public.core.version>
</properties> </properties>
<modules> <modules>