Code cleanup
This commit is contained in:
		
							parent
							
								
									84a7f82c5f
								
							
						
					
					
						commit
						d620e9d323
					
				@ -13,14 +13,13 @@ import org.oneedtech.inspect.vc.util.CachingDocumentLoader;
 | 
				
			|||||||
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.ld.DocumentError;
 | 
					 | 
				
			||||||
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 com.apicatalog.vc.processor.StatusVerifier;
 | 
					 | 
				
			||||||
import com.danubetech.verifiablecredentials.VerifiableCredential;
 | 
					import com.danubetech.verifiablecredentials.VerifiableCredential;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import foundation.identity.jsonld.ConfigurableDocumentLoader;
 | 
					import foundation.identity.jsonld.ConfigurableDocumentLoader;
 | 
				
			||||||
 | 
					import info.weboftrust.ldsignatures.LdProof;
 | 
				
			||||||
import info.weboftrust.ldsignatures.verifier.Ed25519Signature2020LdVerifier;
 | 
					import info.weboftrust.ldsignatures.verifier.Ed25519Signature2020LdVerifier;
 | 
				
			||||||
import jakarta.json.JsonObject;
 | 
					import jakarta.json.JsonObject;
 | 
				
			||||||
import jakarta.json.JsonStructure;
 | 
					import jakarta.json.JsonStructure;
 | 
				
			||||||
@ -37,44 +36,50 @@ public class EmbeddedProofProbe extends Probe<Credential> {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Using verifiable-credentials-java
 | 
						 * Using verifiable-credentials-java from Danubetech
 | 
				
			||||||
	 * (https://github.com/danubetech/verifiable-credentials-java)
 | 
						 * (https://github.com/danubetech/verifiable-credentials-java)
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	@Override
 | 
						@Override
 | 
				
			||||||
	public ReportItems run(Credential crd, RunContext ctx) throws Exception {
 | 
						public ReportItems run(Credential crd, RunContext ctx) throws Exception {
 | 
				
			||||||
 | 
							
 | 
				
			||||||
		// TODO check that proof is Ed25519 - issue error if not ("type":
 | 
							// TODO: What there are multiple proofs?
 | 
				
			||||||
		// "Ed25519Signature2020",
 | 
					 | 
				
			||||||
		// TODO check value "proofPurpose": "assertionMethod", if not error
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		VerifiableCredential vc = VerifiableCredential.fromJson(new StringReader(crd.getJson().toString()));
 | 
							VerifiableCredential vc = VerifiableCredential.fromJson(new StringReader(crd.getJson().toString()));
 | 
				
			||||||
		vc.setDocumentLoader(new CachingDocumentLoader());
 | 
							vc.setDocumentLoader(new CachingDocumentLoader());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		URI method = vc.getLdProof().getVerificationMethod();
 | 
							LdProof proof = vc.getLdProof();
 | 
				
			||||||
 | 
							if (proof == null) {
 | 
				
			||||||
 | 
								return error("The verifiable credential is missing a proof.", ctx);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (!proof.isType("Ed25519Signature2020")) {
 | 
				
			||||||
 | 
								return error("Unknown proof type: " + proof.getType(), ctx);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (!proof.getProofPurpose().equals("assertionMethod")) {
 | 
				
			||||||
 | 
								return error("Invalid proof purpose: " + proof.getProofPurpose(), ctx);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							URI method = proof.getVerificationMethod();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// The verification method must dereference to an Ed25519VerificationKey2020.
 | 
							// The verification method must dereference to an Ed25519VerificationKey2020.
 | 
				
			||||||
		// Danubetech's Ed25519Signature2020LdVerifier expects the decoded public key
 | 
							// Danubetech's Ed25519Signature2020LdVerifier expects the decoded public key
 | 
				
			||||||
		// from the Ed25519VerificationKey2020 (32 bytes).
 | 
							// from the Ed25519VerificationKey2020 (32 bytes).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		String publicKeyMultibase;
 | 
							String publicKeyMultibase;
 | 
				
			||||||
		String controller;
 | 
							String controller = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Formats accepted:
 | 
							// Formats accepted:
 | 
				
			||||||
		//
 | 
							//
 | 
				
			||||||
		// [controller]#[publicKeyMultibase]
 | 
							// [controller]#[publicKeyMultibase]
 | 
				
			||||||
		// did:key:[publicKeyMultibase]
 | 
							// did:key:[publicKeyMultibase]
 | 
				
			||||||
 | 
							// http/s://[location of a Ed25519VerificationKey2020 document]
 | 
				
			||||||
 | 
							// http/s://[location of a controller document with a 'verificationMethod' with a Ed25519VerificationKey2020]
 | 
				
			||||||
		// [publicKeyMultibase]
 | 
							// [publicKeyMultibase]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// TODO fourth format that we don't support yet: a URL that returns a
 | 
					 | 
				
			||||||
		// Ed25519VerificationKey2020
 | 
					 | 
				
			||||||
		// if starts with http and does not have hashcode, try fetch and see if returns
 | 
					 | 
				
			||||||
		// Ed25519VerificationKey2020
 | 
					 | 
				
			||||||
		// property is publicKeyMultibase
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		publicKeyMultibase = method.toString();
 | 
							publicKeyMultibase = method.toString();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (method.getFragment() != null) {
 | 
							if (method.getFragment() != null) {
 | 
				
			||||||
			publicKeyMultibase = method.getFragment();
 | 
								publicKeyMultibase = method.getFragment();
 | 
				
			||||||
 | 
								controller = method.toString().substring(0, method.toString().indexOf("#"));
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			if (method.getScheme().equals("did")) {
 | 
								if (method.getScheme().equals("did")) {
 | 
				
			||||||
				if (method.getSchemeSpecificPart().startsWith("key:")) {
 | 
									if (method.getSchemeSpecificPart().startsWith("key:")) {
 | 
				
			||||||
@ -83,21 +88,22 @@ public class EmbeddedProofProbe extends Probe<Credential> {
 | 
				
			|||||||
					return error("Unknown verification method: " + method, ctx);
 | 
										return error("Unknown verification method: " + method, ctx);
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			} else if (method.getScheme().equals("http") || method.getScheme().equals("https")) {
 | 
								} else if (method.getScheme().equals("http") || method.getScheme().equals("https")) {
 | 
				
			||||||
 | 
									// TODO: Can we use proof.getDocumentLoader()?
 | 
				
			||||||
				ConfigurableDocumentLoader documentLoader = new ConfigurableDocumentLoader();
 | 
									ConfigurableDocumentLoader documentLoader = new ConfigurableDocumentLoader();
 | 
				
			||||||
				documentLoader.setEnableHttp(true);
 | 
									documentLoader.setEnableHttp(true);
 | 
				
			||||||
				documentLoader.setEnableHttps(true);
 | 
									documentLoader.setEnableHttps(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				// The verificationMethod URI must resolve to a Ed25519VerificationKey2020 as described here:
 | 
					 | 
				
			||||||
				// https://w3c-ccg.github.io/di-eddsa-2020/#ed25519verificationkey2020
 | 
					 | 
				
			||||||
				Document keyDocument = documentLoader.loadDocument(method, new DocumentLoaderOptions());
 | 
									Document keyDocument = documentLoader.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);
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				// First look for a plain key object
 | 
					
 | 
				
			||||||
 | 
									// First look for a Ed25519VerificationKey2020 document
 | 
				
			||||||
				controller = keyStructure.get().asJsonObject().getString("controller");
 | 
									controller = keyStructure.get().asJsonObject().getString("controller");
 | 
				
			||||||
				if (StringUtils.isBlank(controller)) {
 | 
									if (StringUtils.isBlank(controller)) {
 | 
				
			||||||
					// Then look for a controller document (e.g. DID Document)
 | 
										// Then look for a controller document (e.g. DID Document) with a 'verificationMethod'
 | 
				
			||||||
 | 
										// that is a Ed25519VerificationKey2020 document
 | 
				
			||||||
					JsonObject keyVerificationMethod = keyStructure.get().asJsonObject()
 | 
										JsonObject keyVerificationMethod = keyStructure.get().asJsonObject()
 | 
				
			||||||
							.getJsonObject("verificationMethod");
 | 
												.getJsonObject("verificationMethod");
 | 
				
			||||||
					if (keyVerificationMethod.isEmpty()) {
 | 
										if (keyVerificationMethod.isEmpty()) {
 | 
				
			||||||
@ -120,7 +126,13 @@ public class EmbeddedProofProbe extends Probe<Credential> {
 | 
				
			|||||||
				return error("Verification method does not contain an Ed25519 public key", ctx);
 | 
									return error("Verification method does not contain an Ed25519 public key", ctx);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		} catch (Exception e) {
 | 
							} catch (Exception e) {
 | 
				
			||||||
			return error("Verification method is invalid: " + e.getMessage(), ctx);
 | 
								return fatal("Invalid public key: " + e.getMessage(), ctx);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (controller != null) {
 | 
				
			||||||
 | 
								if (!controller.equals(vc.getIssuer().toString())) {
 | 
				
			||||||
 | 
									return error("Key controller does not match issuer: " + vc.getIssuer(), ctx);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Extract the publicKey bytes from the Multicodec
 | 
							// Extract the publicKey bytes from the Multicodec
 | 
				
			||||||
@ -128,72 +140,17 @@ public class EmbeddedProofProbe extends Probe<Credential> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		Ed25519Signature2020LdVerifier verifier = new Ed25519Signature2020LdVerifier(publicKey);
 | 
							Ed25519Signature2020LdVerifier verifier = new Ed25519Signature2020LdVerifier(publicKey);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// TODO find out whether we also should check that controller matches issuer ID:
 | 
					 | 
				
			||||||
		// if [controller]#[publicKeyMultibase] format - check [controller] segment
 | 
					 | 
				
			||||||
		// if did:key:[publicKeyMultibase] format: issuer ID must match the entire URI
 | 
					 | 
				
			||||||
		// if [publicKeyMultibase] -- don't check issuer ID. Maybe we should warn about
 | 
					 | 
				
			||||||
		// this syntax.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		try {
 | 
							try {
 | 
				
			||||||
			boolean verify = verifier.verify(vc);
 | 
								boolean verify = verifier.verify(vc);
 | 
				
			||||||
			if (!verify) {
 | 
								if (!verify) {
 | 
				
			||||||
				return error("Embedded proof verification failed.", ctx);
 | 
									return error("Embedded proof verification failed.", ctx);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		} catch (Exception e) {
 | 
							} catch (Exception e) {
 | 
				
			||||||
			return fatal("Embedded proof verification failed:" + e.getMessage(), ctx);
 | 
								return fatal("Embedded proof verification failed: " + e.getMessage(), ctx);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return success(ctx);
 | 
							return success(ctx);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
					 | 
				
			||||||
	 * Note: if using com.apicatalog Iron, we get a generic VC verifier that
 | 
					 | 
				
			||||||
	 * will test other stuff than the Proof. So sometimes it may be that
 | 
					 | 
				
			||||||
	 * Iron internally retests something that we're already testing out in the
 | 
					 | 
				
			||||||
	 * Inspector class (e.g. expiration). But use this for now -- and remember
 | 
					 | 
				
			||||||
	 * that this probe is only run if the given credential has internal proof
 | 
					 | 
				
			||||||
	 * (aka is not a jwt).
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// /*
 | 
					 | 
				
			||||||
	// * Using iron-verifiable-credentials
 | 
					 | 
				
			||||||
	// (https://github.com/filip26/iron-verifiable-credentials)
 | 
					 | 
				
			||||||
	// */
 | 
					 | 
				
			||||||
	// @Override
 | 
					 | 
				
			||||||
	// public ReportItems run(Credential crd, RunContext ctx) throws Exception {
 | 
					 | 
				
			||||||
	// JsonDocument jsonDoc = JsonDocument.of(new
 | 
					 | 
				
			||||||
	// StringReader(crd.getJson().toString()));
 | 
					 | 
				
			||||||
	// JsonObject json = jsonDoc.getJsonContent().get().asJsonObject();
 | 
					 | 
				
			||||||
	// try {
 | 
					 | 
				
			||||||
	// Vc.verify(json)
 | 
					 | 
				
			||||||
	// .loader(new CachingDocumentLoader())
 | 
					 | 
				
			||||||
	// .useBundledContexts(false) //we control the cache in the loader
 | 
					 | 
				
			||||||
	// .statusVerifier(new IronNoopStatusVerifier())
 | 
					 | 
				
			||||||
	// //.domain(...)
 | 
					 | 
				
			||||||
	// //.didResolver(...)
 | 
					 | 
				
			||||||
	// .isValid();
 | 
					 | 
				
			||||||
	// } catch (DocumentError e) {
 | 
					 | 
				
			||||||
	// return error(e.getType() + " " + e.getSubject(), ctx);
 | 
					 | 
				
			||||||
	// } catch (VerificationError e) {
 | 
					 | 
				
			||||||
	// //System.err.println(e.getCode() + " (ProofVerifierProbe)");
 | 
					 | 
				
			||||||
	// if(e.getCode() == Code.Internal) {
 | 
					 | 
				
			||||||
	// return exception(e.getMessage(), ctx.getResource());
 | 
					 | 
				
			||||||
	// } else if(e.getCode().equals(Code.Expired)) {
 | 
					 | 
				
			||||||
	// //handled by other probe
 | 
					 | 
				
			||||||
	// } else {
 | 
					 | 
				
			||||||
	// return fatal(e.getCode().name() + " " + e.getMessage(), ctx);
 | 
					 | 
				
			||||||
	// }
 | 
					 | 
				
			||||||
	//
 | 
					 | 
				
			||||||
	// }
 | 
					 | 
				
			||||||
	// return success(ctx);
 | 
					 | 
				
			||||||
	// }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	private static final class IronNoopStatusVerifier implements StatusVerifier {
 | 
					 | 
				
			||||||
		@Override
 | 
					 | 
				
			||||||
		public void verify(Status status) throws DocumentError, VerifyError {
 | 
					 | 
				
			||||||
			// noop
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	public static final String ID = EmbeddedProofProbe.class.getSimpleName();
 | 
						public static final String ID = EmbeddedProofProbe.class.getSimpleName();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user