improvements
This commit is contained in:
parent
7aea0de780
commit
5b724b3ee8
|
@ -1,62 +0,0 @@
|
||||||
#!/usr/bin/env node
|
|
||||||
//
|
|
||||||
// Author: Guillaume Gagnon
|
|
||||||
// Licence: Apache 2.0
|
|
||||||
//
|
|
||||||
// Extract all payloads included in the Covid QR provided by the Quebec government (Preuve/passeport de vaccination)
|
|
||||||
// Note: The public key do not seems to be provided by the government at this point.
|
|
||||||
// Hence, it is not possible to validate QR authenticity at the time being.
|
|
||||||
// Public keys should be available here later on:
|
|
||||||
// https://covid19.quebec.ca/PreuveVaccinaleApi/issuer/.well-known/jwks.json
|
|
||||||
|
|
||||||
// This script has been built using this very nice and detailed HOWTO:
|
|
||||||
// https://github.com/dvci/health-cards-walkthrough/blob/main/SMART%20Health%20Cards.ipynb
|
|
||||||
//
|
|
||||||
// Also, more info about the SMART Health Cards Framework can be found here:
|
|
||||||
// https://smarthealth.cards/
|
|
||||||
|
|
||||||
|
|
||||||
const fs = require('fs');
|
|
||||||
var jsQR = require('jsqr');
|
|
||||||
var PNG = require('pngjs').PNG;
|
|
||||||
var jose = require('node-jose');
|
|
||||||
var base64url = require("base64url");
|
|
||||||
var zlib = require("zlib");
|
|
||||||
|
|
||||||
|
|
||||||
// Extract RAW QR from picture
|
|
||||||
imageData = PNG.sync.read(fs.readFileSync('./QR.png'))
|
|
||||||
const scannedQR = jsQR(new Uint8ClampedArray(imageData.data.buffer), imageData.width, imageData.height)
|
|
||||||
console.log("RAW QR DATA:")
|
|
||||||
console.log(scannedQR.data)
|
|
||||||
console.log("")
|
|
||||||
|
|
||||||
|
|
||||||
// Extract JWS
|
|
||||||
const scannedJWS = scannedQR
|
|
||||||
.chunks
|
|
||||||
.filter(chunk => chunk.type === "numeric")[0] // Grab the numeric chunk
|
|
||||||
.text.match(/(..?)/g) // Split into groups of 2 numeric characters each of which represent a single JWS char
|
|
||||||
.map(num => String.fromCharCode(parseInt(num, 10) + 45)).join('') // Convert from numeric encoding to JWS
|
|
||||||
console.log("JWS DATA:")
|
|
||||||
console.log(scannedJWS)
|
|
||||||
console.log("")
|
|
||||||
|
|
||||||
|
|
||||||
// Extract JWS Header
|
|
||||||
JWSHeaders = base64url.decode(scannedJWS.split(".")[0])
|
|
||||||
console.log("JWS HEAD:")
|
|
||||||
console.log(JWSHeaders)
|
|
||||||
console.log("")
|
|
||||||
|
|
||||||
|
|
||||||
// Extract payload
|
|
||||||
JWSPayload = scannedJWS.split(".")[1]
|
|
||||||
const payload = Buffer.from(JWSPayload, "base64");
|
|
||||||
zlib.inflateRaw(payload, function (err, decompressedResult) {
|
|
||||||
scannedResult = decompressedResult.toString("utf8");
|
|
||||||
console.log(scannedResult)
|
|
||||||
//const entries = JSON.parse(scannedResult) // Uncomment this bloc if you want to "beautify" the json output
|
|
||||||
// .vc.credentialSubject.fhirBundle.entry
|
|
||||||
// .map(entry => console.log(JSON.stringify(entry, null, 2)))
|
|
||||||
});
|
|
|
@ -1,98 +0,0 @@
|
||||||
{
|
|
||||||
"name": "covid-qr-decode",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"lockfileVersion": 1,
|
|
||||||
"requires": true,
|
|
||||||
"dependencies": {
|
|
||||||
"base64-js": {
|
|
||||||
"version": "1.5.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
|
||||||
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
|
|
||||||
},
|
|
||||||
"base64url": {
|
|
||||||
"version": "3.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz",
|
|
||||||
"integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A=="
|
|
||||||
},
|
|
||||||
"buffer": {
|
|
||||||
"version": "5.7.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
|
|
||||||
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
|
|
||||||
"requires": {
|
|
||||||
"base64-js": "^1.3.1",
|
|
||||||
"ieee754": "^1.1.13"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"es6-promise": {
|
|
||||||
"version": "4.2.8",
|
|
||||||
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz",
|
|
||||||
"integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w=="
|
|
||||||
},
|
|
||||||
"ieee754": {
|
|
||||||
"version": "1.2.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
|
||||||
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="
|
|
||||||
},
|
|
||||||
"jsqr": {
|
|
||||||
"version": "1.4.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/jsqr/-/jsqr-1.4.0.tgz",
|
|
||||||
"integrity": "sha512-dxLob7q65Xg2DvstYkRpkYtmKm2sPJ9oFhrhmudT1dZvNFFTlroai3AWSpLey/w5vMcLBXRgOJsbXpdN9HzU/A=="
|
|
||||||
},
|
|
||||||
"lodash": {
|
|
||||||
"version": "4.17.21",
|
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
|
||||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
|
||||||
},
|
|
||||||
"long": {
|
|
||||||
"version": "4.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz",
|
|
||||||
"integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA=="
|
|
||||||
},
|
|
||||||
"node-forge": {
|
|
||||||
"version": "0.10.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz",
|
|
||||||
"integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA=="
|
|
||||||
},
|
|
||||||
"node-jose": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/node-jose/-/node-jose-2.0.0.tgz",
|
|
||||||
"integrity": "sha512-j8zoFze1gijl8+DK/dSXXqX7+o2lMYv1XS+ptnXgGV/eloQaqq1YjNtieepbKs9jBS4WTnMOqyKSaQuunJzx0A==",
|
|
||||||
"requires": {
|
|
||||||
"base64url": "^3.0.1",
|
|
||||||
"buffer": "^5.5.0",
|
|
||||||
"es6-promise": "^4.2.8",
|
|
||||||
"lodash": "^4.17.15",
|
|
||||||
"long": "^4.0.0",
|
|
||||||
"node-forge": "^0.10.0",
|
|
||||||
"pako": "^1.0.11",
|
|
||||||
"process": "^0.11.10",
|
|
||||||
"uuid": "^3.3.3"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pako": {
|
|
||||||
"version": "1.0.11",
|
|
||||||
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
|
|
||||||
"integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="
|
|
||||||
},
|
|
||||||
"pngjs": {
|
|
||||||
"version": "6.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/pngjs/-/pngjs-6.0.0.tgz",
|
|
||||||
"integrity": "sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg=="
|
|
||||||
},
|
|
||||||
"process": {
|
|
||||||
"version": "0.11.10",
|
|
||||||
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
|
|
||||||
"integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI="
|
|
||||||
},
|
|
||||||
"uuid": {
|
|
||||||
"version": "3.4.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
|
|
||||||
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
|
|
||||||
},
|
|
||||||
"zlib": {
|
|
||||||
"version": "1.0.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/zlib/-/zlib-1.0.5.tgz",
|
|
||||||
"integrity": "sha1-bnyXL8NxxkWmr7A6sUdp3vEU/MA="
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
{
|
|
||||||
"name": "covid-qr-decode",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"description": "",
|
|
||||||
"main": "covid-qr-decode.js",
|
|
||||||
"scripts": {
|
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
|
||||||
},
|
|
||||||
"keywords": [],
|
|
||||||
"author": "Guillaume Gagnon",
|
|
||||||
"license": "Apache-2.0",
|
|
||||||
"bin": {
|
|
||||||
"hello": "./covid-qr-decode.js"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"base64url": "^3.0.1",
|
|
||||||
"jsqr": "^1.4.0",
|
|
||||||
"node-jose": "^2.0.0",
|
|
||||||
"pngjs": "^6.0.0",
|
|
||||||
"zlib": "^1.0.5"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,74 +0,0 @@
|
||||||
#!/usr/bin/python3
|
|
||||||
#
|
|
||||||
# Author: Guillaume Gagnon
|
|
||||||
# Licence: Apache 2.0
|
|
||||||
#
|
|
||||||
# Extract all payloads included in the Covid QR provided by the Quebec government (Preuve/passeport de vaccination)
|
|
||||||
# Note: The public key does not seem to be provided by the government at this point.
|
|
||||||
# Hence, it is not possible to validate QR authenticity at the time being. (Although code is provided)
|
|
||||||
# Public keys *should* be available here later on:
|
|
||||||
# https://covid19.quebec.ca/PreuveVaccinaleApi/issuer/.well-known/jwks.json
|
|
||||||
|
|
||||||
# More info about the SMART Health Cards Framework can be found here:
|
|
||||||
# https://smarthealth.cards/
|
|
||||||
|
|
||||||
from pyzbar.pyzbar import decode # Need to: pip install pyzbar
|
|
||||||
from PIL import Image
|
|
||||||
import re
|
|
||||||
from jose import jwk # Need to: pip install python-jose
|
|
||||||
from jose.utils import base64url_decode
|
|
||||||
import zlib
|
|
||||||
|
|
||||||
# Set path to the QR image
|
|
||||||
# TODO: Take as args?
|
|
||||||
QRImageFile = "./QR.png"
|
|
||||||
|
|
||||||
|
|
||||||
# Load QR data
|
|
||||||
decodedQR = decode(Image.open(QRImageFile))
|
|
||||||
QRData = decodedQR[0].data.decode("utf-8") # Get first element (this library support multiple QR codes in a file)
|
|
||||||
print ("---- RAW QR DATA:")
|
|
||||||
print (QRData +" \n")
|
|
||||||
|
|
||||||
|
|
||||||
# Rebuild JWS token
|
|
||||||
QRNumericData = re.sub("[^0-9]", "", QRData) # Only keep numeric values
|
|
||||||
QRNumericPairs = re.findall("..", QRNumericData) # Split into groups of 2 numeric characters each of which represent a single JWS char
|
|
||||||
JWSToken = ""
|
|
||||||
for n in QRNumericPairs:
|
|
||||||
JWSToken += chr(int(n) + 45) # Recreate the JWS string
|
|
||||||
print ("---- JWS TOKEN:")
|
|
||||||
print (JWSToken +"\n")
|
|
||||||
|
|
||||||
|
|
||||||
# Extract JWS Content
|
|
||||||
header, payload, signature = JWSToken.rsplit('.')
|
|
||||||
print ("---- JWS HEADER:")
|
|
||||||
decHeader = base64url_decode(header.encode('utf-8'))
|
|
||||||
print (decHeader.decode('utf-8') +"\n")
|
|
||||||
|
|
||||||
print ("---- JWS PAYLOAD:")
|
|
||||||
decPayload = base64url_decode(payload.encode('utf-8'))
|
|
||||||
uncompressedPayload = zlib.decompress(decPayload,-15) # Inflate RAW (use no headers bytes)
|
|
||||||
print (uncompressedPayload.decode("utf-8") + "\n")
|
|
||||||
|
|
||||||
print ("---- JWS SIGNATURE (base64):")
|
|
||||||
print (signature + "\n")
|
|
||||||
|
|
||||||
|
|
||||||
# Verify JWS token signature
|
|
||||||
# Note: commented for now. Will be fully implemented once the public keys are provided by the government
|
|
||||||
#hmac_key = {
|
|
||||||
# "kid": "### INSERT KID FROM QR PAYLOAD HERE ###",
|
|
||||||
# "alg": "ES256",
|
|
||||||
# "kty": "EC",
|
|
||||||
# "crv": "P-256",
|
|
||||||
# "use": "sig",
|
|
||||||
# "x": "### INSERT X MATCHING KID HERE ###",
|
|
||||||
# "y": "### INSERT Y MATCHING KID HERE ###"
|
|
||||||
#}
|
|
||||||
#key = jwk.construct(hmac_key)
|
|
||||||
#
|
|
||||||
#signedMessage, encodedSignature = JWSToken.rsplit('.', 1)
|
|
||||||
#decoded_sig = base64url_decode(encodedSignature.encode('utf-8'))
|
|
||||||
#key.verify(signedMessage, decoded_sig)
|
|
45
README.md
45
README.md
|
@ -1,36 +1,33 @@
|
||||||
# Covid Passport Decoder #
|
# Covid Passport Decoder
|
||||||
|
|
||||||
Extract all payloads included in the Covid QR provided by the Quebec government (Preuve/passeport de vaccination)
|
Forked from [ggqc007/Covid-QR-Decoder](https://github.com/ggqc007/Covid-QR-Decoder). Removed the JS version and improved the Py version.
|
||||||
|
|
||||||
**Note:** The public key does not seem to be provided by the government at this point.
|
* * *
|
||||||
Hence, it is not possible to validate QR authenticity at the time being. (Although some of the code is provided in the Python version)
|
|
||||||
|
|
||||||
Public keys *should* be available here later:
|
A simple commandline tool to extract the data from a Covid-19 QR code in the SMART Health Card format. Displays the data with fancy formatting. No error checking is preformed.
|
||||||
[https://covid19.quebec.ca/PreuveVaccinaleApi/issuer/.well-known/jwks.json](https://covid19.quebec.ca/PreuveVaccinaleApi/issuer/.well-known/jwks.json)
|
|
||||||
|
Sample code is included to validate the QR code. Requires the public key from an authority (probably the government).
|
||||||
|
|
||||||
More info about the SMART Health Cards Framework can be found here:
|
More info about the SMART Health Cards Framework can be found here:
|
||||||
[https://smarthealth.cards/](https://smarthealth.cards/)
|
<https://spec.smarthealth.cards/>
|
||||||
|
|
||||||
---
|
* * *
|
||||||
|
|
||||||
# This repo contains two versions #
|
# Usage
|
||||||
## JavaScript: ##
|
|
||||||
1. cd CovidQR-JS/
|
|
||||||
2. npm install
|
|
||||||
3. Edit the path to your .png QR image in the script
|
|
||||||
4. ./covid-qr-decode.js
|
|
||||||
|
|
||||||
|
1. `pip install python-jose pyzbar rich`
|
||||||
|
2. `./covid-qr-decode.py [path to QR code]`
|
||||||
|
|
||||||
## Python: ##
|
**Raw QR Code Data**: You can specify `--raw` to enter the raw QR code data instead of the path to a QR file.
|
||||||
1. cd CovidQR-Py/
|
|
||||||
2. pip install python-jose pyzbar (this will install some dependencies)
|
|
||||||
3. Edit the path to your .png QR image in the script
|
|
||||||
4. ./covid-qr-decode.py
|
|
||||||
|
|
||||||
# Sample payload #
|
**Validate:** To validate the QR code signature, add `--validate [path to public key]`.
|
||||||
> {"kid":"SOME-KEY-ID","zip":"SOME-ZIP","alg":"ES256"}
|
|
||||||
|
|
||||||
>{
|
# Sample Data Output
|
||||||
|
|
||||||
|
```json
|
||||||
|
{"kid":"SOME-KEY-ID","zip":"SOME-ZIP","alg":"ES256"}
|
||||||
|
|
||||||
|
{
|
||||||
"resource": {
|
"resource": {
|
||||||
"resourceType": "Patient",
|
"resourceType": "Patient",
|
||||||
"name": [
|
"name": [
|
||||||
|
@ -86,6 +83,4 @@ More info about the SMART Health Cards Framework can be found here:
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,117 @@
|
||||||
|
#!/usr/bin/python3
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
import zlib
|
||||||
|
|
||||||
|
from jose import jwk
|
||||||
|
from jose.utils import base64url_decode
|
||||||
|
from PIL import Image
|
||||||
|
from pyzbar.pyzbar import decode
|
||||||
|
from rich import print_json
|
||||||
|
from rich.console import Console
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument('data', help='The path to the QR code image file.')
|
||||||
|
parser.add_argument('--raw', help='Decode raw QR code data instead of an image file.', action='store_true')
|
||||||
|
parser.add_argument('--validate', help='Validate the QR code signature against a public key. Must be the path to a public key.', nargs='?', default=False)
|
||||||
|
|
||||||
|
# Print help if no input
|
||||||
|
if len(sys.argv) == 1:
|
||||||
|
parser.print_help(sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
QRImageFile = args.data
|
||||||
|
|
||||||
|
# Load data
|
||||||
|
if (not args.raw):
|
||||||
|
if (os.path.exists(QRImageFile)):
|
||||||
|
decodedQR = decode(Image.open(QRImageFile))
|
||||||
|
# Check that the QR code was decoded
|
||||||
|
if (len(decodedQR) == 0):
|
||||||
|
print(f'\033[91mError:\033[00m could not read the QR code.')
|
||||||
|
sys.exit(1)
|
||||||
|
QRData = decodedQR[0].data.decode("utf-8") # Get first element (this library supports multiple QR codes in a file)
|
||||||
|
else:
|
||||||
|
print(f'\033[91mError:\033[00m could not find QR code file: {QRImageFile}')
|
||||||
|
sys.exit(1)
|
||||||
|
if (args.raw):
|
||||||
|
QRData = QRImageFile
|
||||||
|
|
||||||
|
# Rebuild JWS token
|
||||||
|
QRNumericData = re.sub("[^0-9]", "", QRData) # Only keep numeric values
|
||||||
|
QRNumericPairs = re.findall("..", QRNumericData) # Split into groups of 2 numeric characters each of which represent a single JWS char
|
||||||
|
JWSToken = ""
|
||||||
|
for n in QRNumericPairs:
|
||||||
|
JWSToken += chr(int(n) + 45) # Recreate the JWS string
|
||||||
|
|
||||||
|
# Extract JWS Content.
|
||||||
|
try:
|
||||||
|
header, payload, signature = JWSToken.rsplit('.')
|
||||||
|
except ValueError:
|
||||||
|
print(f'\033[91mError:\033[00m only found {len(JWSToken.rsplit("."))} out of 3 parts of the JWS token.')
|
||||||
|
|
||||||
|
if (not args.raw):
|
||||||
|
print('The QR code couldn\'t be decoded.')
|
||||||
|
elif (args.raw):
|
||||||
|
print('The raw data couldn\'t be decoded. Make sure your provided string starts with \'shc:/\'.')
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# Print
|
||||||
|
console = Console()
|
||||||
|
|
||||||
|
if (not args.raw):
|
||||||
|
console.rule("[bold bright_red]RAW QR CODE DATA")
|
||||||
|
print(QRData + " \n")
|
||||||
|
elif (args.raw):
|
||||||
|
print('\n') # the raw qr code data can be confusing so lets put a line between that and the command above
|
||||||
|
|
||||||
|
console.rule("[bold bright_red]JWS TOKEN")
|
||||||
|
print(JWSToken + "\n")
|
||||||
|
|
||||||
|
console.rule("[bold bright_red]JWS HEADER")
|
||||||
|
decHeader = base64url_decode(header.encode('utf-8'))
|
||||||
|
print_json(decHeader.decode('utf-8'))
|
||||||
|
print('\n')
|
||||||
|
|
||||||
|
console.rule("[bold bright_red]JWS SIGNATURE (base64)")
|
||||||
|
print(signature + "\n")
|
||||||
|
|
||||||
|
console.rule("[bold bright_red]JWS PAYLOAD")
|
||||||
|
decPayload = base64url_decode(payload.encode('utf-8'))
|
||||||
|
uncompressedPayload = zlib.decompress(decPayload, -15).decode("utf-8")
|
||||||
|
print_json(uncompressedPayload)
|
||||||
|
|
||||||
|
# Verify the JWS token signature
|
||||||
|
if (args.validate != False):
|
||||||
|
print('\n')
|
||||||
|
console.rule("[bold bright_red]Validate")
|
||||||
|
if (args.validate == None or len(args.validate) == 0):
|
||||||
|
print(f'\033[91mError:\033[00m must provide the path to the public key file (--validate [path to public key]) to validate the QR code signature against.')
|
||||||
|
else:
|
||||||
|
if (os.path.exists(args.validate)):
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
print(f'\033[91mError:\033[00m could not find public key file: {args.validate}')
|
||||||
|
print('Not implemented.')
|
||||||
|
|
||||||
|
# hmac_key = {
|
||||||
|
# "kid": "### INSERT KID FROM QR PAYLOAD HERE ###",
|
||||||
|
# "alg": "ES256",
|
||||||
|
# "kty": "EC",
|
||||||
|
# "crv": "P-256",
|
||||||
|
# "use": "sig",
|
||||||
|
# "x": "### INSERT X MATCHING KID HERE ###",
|
||||||
|
# "y": "### INSERT Y MATCHING KID HERE ###"
|
||||||
|
# }
|
||||||
|
# key = jwk.construct(hmac_key)
|
||||||
|
#
|
||||||
|
# signedMessage, encodedSignature = JWSToken.rsplit('.', 1)
|
||||||
|
# decoded_sig = base64url_decode(encodedSignature.encode('utf-8'))
|
||||||
|
# key.verify(signedMessage, decoded_sig)
|
Loading…
Reference in New Issue