aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/sec_certs
diff options
context:
space:
mode:
authorJ08nY2023-04-11 14:53:15 +0200
committerJ08nY2023-04-11 14:53:15 +0200
commit512bc150aecbff5f4e87e37a584dcf2f2a34674f (patch)
tree8222357075f014295f7cbf3cb38bca6c2e9bd891 /src/sec_certs
parent6d5715b989138da29f90fd8bad46f454903fdd1a (diff)
downloadsec-certs-512bc150aecbff5f4e87e37a584dcf2f2a34674f.tar.gz
sec-certs-512bc150aecbff5f4e87e37a584dcf2f2a34674f.tar.zst
sec-certs-512bc150aecbff5f4e87e37a584dcf2f2a34674f.zip
Move snapshot maching code to matcher.
Diffstat (limited to 'src/sec_certs')
-rw-r--r--src/sec_certs/model/fips_matching.py54
1 files changed, 48 insertions, 6 deletions
diff --git a/src/sec_certs/model/fips_matching.py b/src/sec_certs/model/fips_matching.py
index 0062f8df..2d3fa8a3 100644
--- a/src/sec_certs/model/fips_matching.py
+++ b/src/sec_certs/model/fips_matching.py
@@ -1,8 +1,18 @@
from __future__ import annotations
+import typing
+from operator import itemgetter
+from typing import Mapping, MutableMapping
+
from rapidfuzz import fuzz
-from sec_certs.sample import FIPSCertificate, IUTEntry, MIPEntry
+from sec_certs.configuration import config
+
+if typing.TYPE_CHECKING:
+ from sec_certs.dataset.fips import FIPSDataset
+ from sec_certs.sample.fips import FIPSCertificate
+ from sec_certs.sample.fips_iut import IUTEntry, IUTSnapshot
+ from sec_certs.sample.fips_mip import MIPEntry, MIPSnapshot
class FIPSProcessMatcher:
@@ -28,17 +38,13 @@ class FIPSProcessMatcher:
:param cert: The certificate to match against.
:return: The match score.
"""
- # TODO: Add logic to match on date?
- # Certification date should be after the entry date in MIP/IUT.
- # But a FIPS cert can have many validation dates, gets tricky.
- # Maybe this needs to be done outside of the matcher context,
- # when comparing several matches.
if cert.web_data.standard != self._standard:
return 0
if self._product is None or self._vendor is None:
return 0
if self._product == cert.name and self._vendor == cert.manufacturer:
return 99
+ # TODO: Move the CPE matching name/vendor normalization functions and use them here.
product_ratings = [
fuzz.token_set_ratio(self._product, cert.name),
@@ -49,3 +55,39 @@ class FIPSProcessMatcher:
fuzz.partial_token_sort_ratio(self._vendor, cert.manufacturer, score_cutoff=100),
]
return max((0, max(product_ratings) * 0.5 + max(vendor_ratings) * 0.5 - 2))
+
+ @classmethod
+ def match_snapshot(
+ cls, snapshot: IUTSnapshot | MIPSnapshot, dset: FIPSDataset
+ ) -> Mapping[IUTEntry | MIPEntry, FIPSCertificate | None]:
+ """
+ Match a whole snapshot of IUT/MIP entries to a FIPS certificate dataset.
+
+ Duplicates may occur.
+
+ :param snapshot: The snapshot to match the entries of.
+ :param dset: The dataset tot match to.
+ :return: The matching.
+ """
+ matches: MutableMapping[IUTEntry | MIPEntry, FIPSCertificate | None] = {}
+ for entry in snapshot:
+ matcher = FIPSProcessMatcher(entry)
+ scores = sorted(((matcher.match(cert), cert) for cert in dset), key=itemgetter(0), reverse=True)
+ found = False
+ for score, cert in scores:
+ if score < config.fips_matching_threshold:
+ break
+ validations = cert.web_data.validation_history
+ if not validations:
+ continue
+ for validation in validations:
+ if validation.date >= snapshot.timestamp.date():
+ # It could be this cert, so take it
+ found = True
+ matches[entry] = cert
+ break
+ if found:
+ break
+ else:
+ matches[entry] = None
+ return matches