<!doctype html>
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<link rel="stylesheet" href="css/style.v2.css">
|
|
<link rel="stylesheet" href="css/topnav.css">
|
|
<link rel="shortcut icon" href="https://www.pathcheck.org/hubfs/Favicon.png">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>Verifiable Credential Debugger</title>
|
|
|
|
<!-- Global site tag (gtag.js) - Google Analytics -->
|
|
<script async src="https://www.googletagmanager.com/gtag/js?id=G-DTDMHW3NV6"></script>
|
|
<script>
|
|
window.dataLayer = window.dataLayer || [];
|
|
function gtag(){dataLayer.push(arguments);}
|
|
gtag('js', new Date());
|
|
gtag('config', 'G-DTDMHW3NV6');
|
|
</script>
|
|
</head>
|
|
<body>
|
|
<div class="topnav">
|
|
<div class="topnavContainer">
|
|
<a href="index.html">Signers</a>
|
|
<a href="verify.html"><span class="xs-hidden">Universal </span>Verifier</a>
|
|
<a class="xs-hidden active" href="debug.html">QR Debugger</a>
|
|
<a class="xs-hidden" href="https://github.com/Path-Check/paper-cred-demo">Source Code</a>
|
|
<a href="https://github.com/Path-Check/paper-cred"><span class="xs-hidden"> QR </span>Specs</a>
|
|
<a href="http://vaccine-docs.pathcheck.org"><span class="xs-hidden">Vaccine </span>Docs</a>
|
|
<a class="xs-hidden" href="http://pathcheck.org">About PathCheck</a>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="center">
|
|
<h1>Verifiable Credential Debugger</h1>
|
|
<div class="full-div">
|
|
<div class="four-quarter-left">
|
|
<div>
|
|
<h4>Paste the QR Code here:</h4>
|
|
<textarea id="qr-verify" rows="10" placeholder="cred:type:version:signature:pubkey:payload
|
|
HC1:payload">HC1:6BFOXN%TSMAHN-H+XO5XF7:UY%FJ.G0II:3O6NRBD295QJQC8G9Z3RRAC/GPWBI$C9UDBQEAJJKHHGEC8.-B97U: K8*NHQ2VAP1US1Q7OKHHUEPOP%WUXQ72QETZU3UQRVULKHWWU:16Q8Q*7R-PP9$PB/9OK5JWEMN1/9VSL1Y813.UNNUR+UK0VF/94O5%ZE/NEVTEJAVX5NGTUY*U9/9-3APF6:66A$QZ76LZ6Q59HEDN*I4OIMEDTJCJKDLEDL9CVTAUPIAK29VC4/D-FD8RDVTADYI7VCE8C09DC8CMCI7UJ$JCDVC$XINYJ3A41VCSWC%PD:NKC7D$JCYJC1VCW CTCKY004SIVOHD C9DG4:GXMRD$S+A5M2FNW04QK7TSJWODTUOQ2CVE2JAWH6 $U0QPSXQ:PI*VIUXFOH68ZUOP6OH6XO9IE5IVU4S2PQONTI4L6OUC6VH6ZL4XP0N6F1L3RVT5BZ-H67NMWE7*UHS6NYHY8ES$ILVCK4L2+1M2LDD9GQS4.R1N52FVNCU8+NV6H2+9/$V:%G2.2.$JPJJPKK6U94QMXLMQAL1NJV8U3CW:BP40TX7A$B44W8:VD5J4*101AI</textarea>
|
|
<br><br>
|
|
<button class="qr-btn" onclick="verifyQRCode()">Verify</button>
|
|
<br><br>
|
|
<pre id="qr-verify-brand"></pre>
|
|
<pre id="qr-verify-result"></pre>
|
|
<pre id="qr-verify-verified"></pre>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="quarter">
|
|
<h4>Public Key (for HC1)</h4>
|
|
<textarea id="pubkey" rows="10" cols="30">-----BEGIN CERTIFICATE-----
|
|
MIIBYDCCAQYCEQCAG8uscdLb0ppaneNN5sB7MAoGCCqGSM49BAMCMDIxIzAhBgNV
|
|
BAMMGk5hdGlvbmFsIENTQ0Egb2YgRnJpZXNsYW5kMQswCQYDVQQGEwJGUjAeFw0y
|
|
MTA0MjcyMDQ3MDVaFw0yNjAzMTIyMDQ3MDVaMDYxJzAlBgNVBAMMHkRTQyBudW1i
|
|
ZXIgd29ya2VyIG9mIEZyaWVzbGFuZDELMAkGA1UEBhMCRlIwWTATBgcqhkjOPQIB
|
|
BggqhkjOPQMBBwNCAARkJeqyO85dyR+UrQ5Ey8EdgLyf9NtsCrwORAj6T68/elL1
|
|
9aoISQDbzaNYJjdD77XdHtd+nFGTQVpB88wPTwgbMAoGCCqGSM49BAMCA0gAMEUC
|
|
IQDvDacGFQO3tuATpoqf40CBv09nfglL3wh5wBwA1uA7lAIgZ4sOK2iaaTsFNqEN
|
|
AF7zi+d862ePRQ9Lwymr7XfwVm0=
|
|
-----END CERTIFICATE-----</textarea>
|
|
<br><br>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script src="js/qrcode.min.js"></script>
|
|
|
|
<script src="js/pcf-utils.js"></script>
|
|
<script src="js/ui-utils.js"></script>
|
|
|
|
<script src="js/pcf.sdk.min.js"></script>
|
|
<script src="js/eudgc.sdk.min.js"></script>
|
|
<script src="js/he.js"></script>
|
|
<script src="js/ajv7.min.js"></script>
|
|
|
|
<script src="js/divoc.sdk.min.js"></script>
|
|
<script src="js/json-beautify.min.js"></script>
|
|
<script src="js/bbs-cborld.sdk.min.js"></script>
|
|
<script src="js/bbs-jxt.sdk.min.js"></script>
|
|
|
|
<script>
|
|
function replacer(key, value) {
|
|
if (value instanceof Map) {
|
|
return {
|
|
'Map': Array.from(value.entries()), // or with spread: value: [...value]
|
|
};
|
|
} else {
|
|
return value;
|
|
}
|
|
}
|
|
function reviver(key, value) {
|
|
if(typeof value === 'object' && value !== null) {
|
|
if (value.dataType === 'Map') {
|
|
return new Map(value.value);
|
|
}
|
|
}
|
|
return value;
|
|
}
|
|
|
|
function e(elem) { return document.getElementById(elem); }
|
|
|
|
function schemaValidator() {
|
|
var ajv = new ajv7.default({strict: "log", validateFormats: false});
|
|
|
|
let client = new XMLHttpRequest();
|
|
client.open('GET', 'https://raw.githubusercontent.com/ehn-digital-green-development/ehn-dgc-schema/main/DGC.combined-schema.json', false);
|
|
client.setRequestHeader("Accept", "application/vnd.github.v3+json");
|
|
client.send();
|
|
|
|
const schema = JSON.parse(client.response);
|
|
delete schema['$schema'];
|
|
return ajv.compile(schema);
|
|
}
|
|
|
|
function getEUPayload(cwt) {
|
|
if (cwt instanceof Map) {
|
|
return cwt.get(-260).get(1);
|
|
}
|
|
return cwt;
|
|
}
|
|
|
|
function verifyQRCode() {
|
|
gtag('event', 'debugQR');
|
|
|
|
e("qr-verify-brand").innerHTML = "";
|
|
e("qr-verify-result").innerHTML = "Checking";
|
|
e('qr-verify-verified').innerHTML = "";
|
|
|
|
const qr = e("qr-verify").value;
|
|
if (qr === "" && qr == null) {
|
|
e('qr-verify-verified').innerHTML = "Certificate not found. ";
|
|
return;
|
|
}
|
|
|
|
if (qr.startsWith('CRED:')) {
|
|
e("qr-verify-brand").innerHTML = "PathCheck Verifiable QR"
|
|
PCFUtils.debugParseURI(qr).then(result => {
|
|
e("qr-verify-result").innerHTML = result;
|
|
});
|
|
PCFUtils.debugVerify(qr).then(debug => {
|
|
e('qr-verify-verified').innerHTML = debug;
|
|
});
|
|
} else if (qr.startsWith('CBLD:')) {
|
|
BBS_CBORLD.unpackAndVerify(qr).then(json => {
|
|
if (json) {
|
|
e("qr-verify-result").innerHTML = he.encode(beautify(json, null, 2, 80));
|
|
e('qr-verify-verified').innerHTML = "Signature Verified ";
|
|
} else {
|
|
e("qr-verify-result").innerHTML = "Something is wrong with the payload";
|
|
e('qr-verify-verified').innerHTML = "Could not Verify";
|
|
}
|
|
});
|
|
} else if (qr.startsWith('JXT:')) {
|
|
BBS_JXT.unpackAndVerify(qr).then(json => {
|
|
if (json) {
|
|
e("qr-verify-result").innerHTML = he.encode(beautify(json, null, 2, 80));
|
|
e('qr-verify-verified').innerHTML = "Signature Verified ";
|
|
} else {
|
|
e("qr-verify-result").innerHTML = "Something is wrong with the payload";
|
|
e('qr-verify-verified').innerHTML = "Could not Verify";
|
|
}
|
|
});
|
|
} else if (qr.startsWith('HC1:')) {
|
|
e("qr-verify-brand").innerHTML = "EU Digital Green Certificate Verifiable QR"
|
|
EUDGC.unpackAndVerify(qr, e('pubkey').value).then(json => {
|
|
const validator = schemaValidator();
|
|
const valid = validator(getEUPayload(json));
|
|
if (json) {
|
|
e('qr-verify-verified').innerHTML = "Signature Verified " + (valid? "and Schema is Valid" : " but Schema has errors " + JSON.stringify(validator.errors));
|
|
} else {
|
|
e('qr-verify-verified').innerHTML = "Could not Verify";
|
|
}
|
|
});
|
|
EUDGC.debug(qr).then(json => {
|
|
if (json) {
|
|
e("qr-verify-result").innerHTML = he.encode(beautify(json, replacer, 2, 80));
|
|
} else {
|
|
e("qr-verify-result").innerHTML = "Something is wrong with the payload";
|
|
}
|
|
});
|
|
} else if (qr.includes('did:india')) {
|
|
e("qr-verify-brand").innerHTML = "Divoc Verifiable QR"
|
|
DIVOC.verify(qr).then(result => {
|
|
if (result) {
|
|
e("qr-verify-result").innerHTML = he.encode(beautify(JSON.parse(qr), null, 2, 80));
|
|
e('qr-verify-verified').innerHTML = "Signature Verified";
|
|
} else {
|
|
e("qr-verify-result").innerHTML = "Something is wrong with the payload";
|
|
e('qr-verify-verified').innerHTML = "Could not Verify";
|
|
}
|
|
});
|
|
} else if (qr.includes('did:hpass')) {
|
|
e("qr-verify-brand").innerHTML = "Excelsior Pass Verifiable QR"
|
|
e("qr-verify-result").innerHTML = he.encode(beautify(JSON.parse(qr), null, 2, 80));
|
|
e('qr-verify-verified').innerHTML = "IBM's Pass verification has not been implemented yet.";
|
|
} else {
|
|
e("qr-verify-brand").innerHTML = "No idea what this is"
|
|
e("qr-verify-result").innerHTML = "";
|
|
e('qr-verify-verified').innerHTML = "The payload type has not been implemented yet.";
|
|
}
|
|
}
|
|
</script>
|
|
</body>
|
|
</html>
|
|
|
|
|