Skip to content

Commit

Permalink
Add digests verification
Browse files Browse the repository at this point in the history
  • Loading branch information
aydarng committed Aug 20, 2024
1 parent c28678a commit 9fe2b3f
Show file tree
Hide file tree
Showing 2 changed files with 146 additions and 71 deletions.
85 changes: 80 additions & 5 deletions src/verifier/core/reporting.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@
import zipfile
from collections import namedtuple
from dataclasses import asdict
from hashlib import sha256

import falcon
import multibase
from hio.base import doing
from keri import kering
from keri.core import coring, Siger
from keri.core import coring, Siger, MtrDex

from verifier.core.basing import ReportStats

Expand Down Expand Up @@ -54,6 +56,13 @@ def loadEnds(app, hby, vdb, filer):
app.add_route("/reports/{aid}/{dig}", reportEnd)


def get_non_prefixed_digest(dig):
prefix, digest = dig.split("_", 1)
if not digest:
raise kering.ValidationError(f"Digest ({dig}) must start with prefix")
return digest


class Filer:
""" Report status filer
Expand Down Expand Up @@ -92,19 +101,82 @@ def create(self, aid, dig, filename, typ, stream):
)

idx = 0
non_pref_dig = get_non_prefixed_digest(dig) # Temporarily remove prefix
non_pref_dig = bytes.fromhex(non_pref_dig)
diger = coring.Diger(raw=non_pref_dig, code=MtrDex.SHA2_256)

report = b''
while True:
chunk = stream.read(4096)
report += chunk
if not chunk:
break
key = f"{dig}.{idx}".encode("utf-8")
key = f"{diger.qb64}.{idx}".encode("utf-8")
self.vdb.setVal(db=self.vdb.imgs, key=key, val=chunk)
idx += 1
stats.size += len(chunk)

diger = coring.Diger(qb64=dig)
if not diger.verify(report):
raise kering.ValidationError(f"Report digets({dig} verification failed)")
with tempfile.TemporaryFile("w+b") as tf:
tf.write(report)
tf.seek(0)
with tempfile.TemporaryDirectory() as tempdirname:
z = zipfile.ZipFile(tf)
z.extractall(path=tempdirname)
manifest = None
for root, dirs, _ in os.walk(tempdirname):
if "META-INF" not in dirs or 'reports' not in dirs:
continue

metaDir = os.path.join(root, 'META-INF')
name = os.path.join(root, 'META-INF', 'reports.json')
if not os.path.exists(name):
continue
f = open(name, 'r')
manifest = json.load(f)
if "documentInfo" not in manifest:
raise kering.ValidationError("Invalid manifest file in report package, missing "
"'documentInfo")
reportsDir = os.path.join(root, 'reports')
files = os.listdir(reportsDir)

if manifest is None:
raise kering.ValidationError("No manifest in file, invalid signed report package")

docInfo = manifest["documentInfo"]

if "digests" not in docInfo:
raise kering.ValidationError("No digests found in manifest file")

digests = docInfo["digests"]
for digest in digests:
try:
file = digest["file"]
fullpath = os.path.normpath(os.path.join(metaDir, file))
f = open(fullpath, 'rb')
file_object = f.read()
f.close()
non_pref_dig = get_non_prefixed_digest(digest["dig"]) # Remove prefix
non_pref_dig = bytes.fromhex(non_pref_dig)
tmp_diger = coring.Diger(raw=non_pref_dig, code=MtrDex.SHA2_256)
if not tmp_diger.verify(file_object):
raise kering.ValidationError(f"Invalid digest for file {fullpath}")
except KeyError as e:
raise kering.ValidationError(f"Invalid digest in manifest digest list"
f"missing '{e.args[0]}'")
except OSError:
raise kering.ValidationError(f"signature element={digest} point to invalid file")

except Exception as e:
raise kering.ValidationError(f"{e}")




self.vdb.rpts.add(keys=(aid,), val=diger)
self.vdb.stts.add(keys=(stats.status,), val=diger)
self.vdb.stats.pin(keys=(dig,), val=stats)
self.vdb.stats.pin(keys=(diger.qb64,), val=stats)

def get(self, dig):
""" Return report stats for given report.
Expand All @@ -116,7 +188,10 @@ def get(self, dig):
ReportStats: Report stats for report with digest dig or None
"""
if (stats := self.vdb.stats.get(keys=(dig,))) is None:
non_pref_dig = get_non_prefixed_digest(dig) # Temporarily remove prefix
non_pref_dig = bytes.fromhex(non_pref_dig)
diger = coring.Diger(raw=non_pref_dig, code=MtrDex.SHA2_256)
if (stats := self.vdb.stats.get(keys=(diger.qb64,))) is None:
return None

return stats
Expand Down
132 changes: 66 additions & 66 deletions tests/integration/test_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,79 +112,79 @@ def get():
if exceptions:
raise exceptions[0]

# @pytest.mark.manual
# def test_service_integration(seeder):
# with habbing.openHab(name="sid", temp=True, salt=b'0123456789abcdef') as (hby, hab):

# seeder.seedSchema(db=hby.db)
# regery, registry, verifier, seqner = reg_and_verf(hby, hab, registryName="qvireg")
# qvicred = get_qvi_cred(issuer=hab.pre, recipient=hab.pre, schema=Schema.QVI_SCHEMA, registry=registry)
# hab, qcrdntler, qsaid, qkmsgs, qtmsgs, qimsgs, qvimsgs = get_cred(hby, hab, regery, registry, verifier, Schema.QVI_SCHEMA, qvicred, seqner)
@pytest.mark.manual
def test_service_integration(seeder):
with habbing.openHab(name="sid", temp=True, salt=b'0123456789abcdef') as (hby, hab):

seeder.seedSchema(db=hby.db)
regery, registry, verifier, seqner = reg_and_verf(hby, hab, registryName="qvireg")
qvicred = get_qvi_cred(issuer=hab.pre, recipient=hab.pre, schema=Schema.QVI_SCHEMA, registry=registry)
hab, qcrdntler, qsaid, qkmsgs, qtmsgs, qimsgs, qvimsgs = get_cred(hby, hab, regery, registry, verifier, Schema.QVI_SCHEMA, qvicred, seqner)

# qviedge = get_qvi_edge(qvicred.sad["d"], Schema.QVI_SCHEMA)
qviedge = get_qvi_edge(qvicred.sad["d"], Schema.QVI_SCHEMA)

# leicred = get_lei_cred(issuer=hab.pre, recipient=hab.pre, schema=Schema.LEI_SCHEMA, registry=registry, sedge=qviedge)
# hab, lcrdntler, lsaid, lkmsgs, ltmsgs, limsgs, leimsgs = get_cred(hby, hab, regery, registry, verifier, Schema.LEI_SCHEMA, leicred, seqner)
leicred = get_lei_cred(issuer=hab.pre, recipient=hab.pre, schema=Schema.LEI_SCHEMA, registry=registry, sedge=qviedge)
hab, lcrdntler, lsaid, lkmsgs, ltmsgs, limsgs, leimsgs = get_cred(hby, hab, regery, registry, verifier, Schema.LEI_SCHEMA, leicred, seqner)

# #chained ecr auth cred
# eaedge = get_ecr_auth_edge(lsaid,Schema.LEI_SCHEMA)
#chained ecr auth cred
eaedge = get_ecr_auth_edge(lsaid,Schema.LEI_SCHEMA)

# eacred = get_ecr_auth_cred(aid=hab.pre, issuer=hab.pre, recipient=hab.pre, schema=Schema.ECR_AUTH_SCHEMA, registry=registry, sedge=eaedge)
# hab, eacrdntler, easaid, eakmsgs, eatmsgs, eaimsgs, eamsgs = get_cred(hby, hab, regery, registry, verifier, Schema.ECR_AUTH_SCHEMA, eacred, seqner)
eacred = get_ecr_auth_cred(aid=hab.pre, issuer=hab.pre, recipient=hab.pre, schema=Schema.ECR_AUTH_SCHEMA, registry=registry, sedge=eaedge)
hab, eacrdntler, easaid, eakmsgs, eatmsgs, eaimsgs, eamsgs = get_cred(hby, hab, regery, registry, verifier, Schema.ECR_AUTH_SCHEMA, eacred, seqner)

# #chained ecr auth cred
# ecredge = get_ecr_edge(easaid,Schema.ECR_AUTH_SCHEMA)
#chained ecr auth cred
ecredge = get_ecr_edge(easaid,Schema.ECR_AUTH_SCHEMA)

# ecr = get_ecr_cred(issuer=hab.pre, recipient=hab.pre, schema=Schema.ECR_SCHEMA, registry=registry, sedge=ecredge)
# hab, eccrdntler, ecsaid, eckmsgs, ectmsgs, ecimsgs, ecmsgs = get_cred(hby, hab, regery, registry, verifier, Schema.ECR_SCHEMA, ecr, seqner)
ecr = get_ecr_cred(issuer=hab.pre, recipient=hab.pre, schema=Schema.ECR_SCHEMA, registry=registry, sedge=ecredge)
hab, eccrdntler, ecsaid, eckmsgs, ectmsgs, ecimsgs, ecmsgs = get_cred(hby, hab, regery, registry, verifier, Schema.ECR_SCHEMA, ecr, seqner)

# app = falcon.App(
# middleware=falcon.CORSMiddleware(
# allow_origins='*',
# allow_credentials='*',
# expose_headers=['cesr-attachment', 'cesr-date', 'content-type']))
# vdb = basing.VerifierBaser(name=hby.name, temp=True)
# verifying.setup(app=app, hby=hby, vdb=vdb, reger=eccrdntler.rgy.reger)
# server = http.Server(port=port, app=app)
# httpServerDoer = http.ServerDoer(server=server)
# # class testCf:
# # def get():
# # return dict(LEIs=[f"{LEI1}",f"{LEI2}"])
# rootsCf = configing.Configer(name="verifier-config-public.json",
# headDirPath="/Users/meenyleeny/VSCode/vlei-verifier/scripts",
# base="",
# temp=False, reopen=True, clear=False)
# authDoers = authorizing.setup(hby, vdb=vdb, reger=eccrdntler.rgy.reger, cf=rootsCf)

# reportDoers = reporting.setup(app=app, hby=hby, vdb=vdb)

# doers = authDoers + reportDoers + [httpServerDoer]
# limit = 0.25
# tock = 0.03125
# doist = doing.Doist(limit=limit, tock=tock)
# doist.doers = doers
# doist.enter()
# # assert len(doist.deeds) == 2
# # assert [val[1] for val in doist.deeds] == [0.0, 0.0] # retymes
# # for doer in doers:
# # assert doer.baser.opened
# # assert "_test/keri/db/test" in doer.baser.path
# try:
# doist.recur()
# except Exception as e:
# raise ValueError(f"Likely you have another service running on {port}")

# issAndCred = bytearray()
# # issAndCred.extend(kmsgs)
# # issAndCred.extend(tmsgs)
# # issAndCred.extend(imsgs)
# issAndCred.extend(ecmsgs)
# acdc = issAndCred.decode("utf-8")

# # use this for integration testing debugging sessions
# while True:
# time.sleep(1)
# doist.recur()
app = falcon.App(
middleware=falcon.CORSMiddleware(
allow_origins='*',
allow_credentials='*',
expose_headers=['cesr-attachment', 'cesr-date', 'content-type']))
vdb = basing.VerifierBaser(name=hby.name, temp=True)
verifying.setup(app=app, hby=hby, vdb=vdb, reger=eccrdntler.rgy.reger)
server = http.Server(port=port, app=app)
httpServerDoer = http.ServerDoer(server=server)
# class testCf:
# def get():
# return dict(LEIs=[f"{LEI1}",f"{LEI2}"])
rootsCf = configing.Configer(name="verifier-config-public.json",
headDirPath="/home/aidar/Desktop/git/gleif/vlei-verifier/scripts",
base="",
temp=False, reopen=True, clear=False)
authDoers = authorizing.setup(hby, vdb=vdb, reger=eccrdntler.rgy.reger, cf=rootsCf)

reportDoers = reporting.setup(app=app, hby=hby, vdb=vdb)

doers = authDoers + reportDoers + [httpServerDoer]
limit = 0.25
tock = 0.03125
doist = doing.Doist(limit=limit, tock=tock)
doist.doers = doers
doist.enter()
# assert len(doist.deeds) == 2
# assert [val[1] for val in doist.deeds] == [0.0, 0.0] # retymes
# for doer in doers:
# assert doer.baser.opened
# assert "_test/keri/db/test" in doer.baser.path
try:
doist.recur()
except Exception as e:
raise ValueError(f"Likely you have another service running on {port}")

issAndCred = bytearray()
# issAndCred.extend(kmsgs)
# issAndCred.extend(tmsgs)
# issAndCred.extend(imsgs)
issAndCred.extend(ecmsgs)
acdc = issAndCred.decode("utf-8")

# use this for integration testing debugging sessions
while True:
time.sleep(1)
doist.recur()

def presentation_request(said, acdc, exceptions):
try:
Expand Down

0 comments on commit 9fe2b3f

Please sign in to comment.