aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorPetr Svenda2020-10-15 17:30:15 +0200
committerGitHub2020-10-15 17:30:15 +0200
commit4b0e406d5a223286aef32a88899fbb627e25008a (patch)
tree229c8353a0555bd1df0bdb2b3f2b78869b21f2c7
parent08d37981b56d6e12c64994156d0a01704a9fa5dc (diff)
parent79ed1029a1f2fa3395a35ab8d5382af886d7ea7b (diff)
downloadsec-certs-4b0e406d5a223286aef32a88899fbb627e25008a.tar.gz
sec-certs-4b0e406d5a223286aef32a88899fbb627e25008a.tar.zst
sec-certs-4b0e406d5a223286aef32a88899fbb627e25008a.zip
Merge branch 'master' into feature/more-rules
-rw-r--r--.travis.yml10
-rw-r--r--setup.py30
-rw-r--r--src/analyze_certificates.py24
-rw-r--r--src/cert_rules.py167
-rw-r--r--src/download_files.py36
-rw-r--r--src/extract_certificates.py1242
-rw-r--r--src/fips_certificates.py444
-rw-r--r--src/process_certificates.py42
8 files changed, 1492 insertions, 503 deletions
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 00000000..493398bc
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,10 @@
+os: linux
+language: python
+dist: xenial
+python: "3.8"
+
+install:
+ - pip install .
+
+script:
+ - echo "Test here"
diff --git a/setup.py b/setup.py
new file mode 100644
index 00000000..9f4d51b0
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,30 @@
+#!/usr/bin/env python3
+from setuptools import setup
+
+setup(
+ name='sec-certs',
+ author='Petr Svenda',
+ author_email='',
+ version='0.0.0',
+ packages='sec-certs',
+ license='MIT',
+ description="Tool for analysis of security certificates",
+ long_description=open("README.md").read(),
+ long_description_content_type="text/markdown",
+ classifiers=[
+ "Development Status :: 3 - Alpha",
+ "License :: OSI Approved :: MIT License",
+ "Topic :: Security",
+ "Topic :: Security :: Cryptography",
+ "Programming Language :: Python :: 3",
+ "Intended Audience :: Developers",
+ "Intended Audience :: Science/Research"
+ ],
+ install_requires=[
+ "PyPDF2",
+ "matplotlib",
+ "graphviz",
+ "numpy",
+ "tabulate"
+ ]
+)
diff --git a/src/analyze_certificates.py b/src/analyze_certificates.py
index 92091949..addb1711 100644
--- a/src/analyze_certificates.py
+++ b/src/analyze_certificates.py
@@ -9,6 +9,7 @@ from dateutil import parser
import datetime
from tags_constants import *
import string
+import os
STOP_ON_UNEXPECTED_NUMS = False
@@ -57,10 +58,14 @@ def plot_bar_graph(data, x_data_labels, y_label, title, file_name):
plt.axis((x1, x2, y1 - 1, y2))
plt.savefig(file_name + '.png', bbox_inches='tight')
plt.savefig(file_name + '.pdf', bbox_inches='tight')
+ plt.close()
def plot_heatmap_graph(data_matrix, x_data_ticks, y_data_ticks, x_label, y_label, title, file_name):
- plt.figure(figsize=(round(len(x_data_ticks) / 2), 8), dpi=200, facecolor='w', edgecolor='k')
+ fig_size = round(len(x_data_ticks) / 2)
+ if fig_size == 0:
+ fig_size = 8
+ plt.figure(figsize=(fig_size, 8), dpi=200, facecolor='w', edgecolor='k')
#color_map = 'BuGn'
color_map = 'Purples'
plt.imshow(data_matrix, cmap=color_map, interpolation='none', aspect='auto')
@@ -76,8 +81,15 @@ def plot_heatmap_graph(data_matrix, x_data_ticks, y_data_ticks, x_label, y_label
plt.xlabel(x_label)
plt.ylabel(y_label)
plt.title(title)
- plt.savefig(file_name + '.png', bbox_inches='tight')
- plt.savefig(file_name + '.pdf', bbox_inches='tight')
+ try:
+ plt.savefig(file_name + '.png', bbox_inches='tight')
+ except RuntimeError as e:
+ print('RuntimeError while writing {} file as png'.format(file_name + '.png'))
+ try:
+ plt.savefig(file_name + '.pdf', bbox_inches='tight')
+ except RuntimeError as e:
+ print('RuntimeError while writing {} file as pdf'.format(file_name + '.pdf'))
+ plt.close()
def compute_and_plot_hist(data, bins, y_label, title, file_name):
@@ -109,8 +121,8 @@ def depricated_print_dot_graph_keywordsonly(filter_rules_group, all_items_found,
just_file_name = file_name
this_cert_id = cert_id[file_name]
- if file_name.rfind('\\') != -1:
- just_file_name = file_name[file_name.rfind('\\') + 1:]
+ if file_name.rfind(os.sep) != -1:
+ just_file_name = file_name[file_name.rfind(os.sep) + 1:]
# insert file name and identified probable certification id
if this_cert_id != "":
@@ -255,6 +267,7 @@ def plot_certid_to_item_graph(item_path, all_items_found, filter_label, out_dot_
dot.render(out_dot_name, view=False)
print('{} pdf rendered'.format(out_dot_name))
+
def analyze_references_graph(filter_rules_group, all_items_found, filter_label):
# build cert_id to item name mapping
certid_info = {}
@@ -430,6 +443,7 @@ def plot_schemes_multi_line_graph(x_ticks, data, prominent_data, x_label, y_labe
plt.title(title)
plt.savefig(file_name + '.png', bbox_inches='tight')
plt.savefig(file_name + '.pdf', bbox_inches='tight')
+ plt.close()
def analyze_cert_years_frequency(all_cert_items, filter_label):
diff --git a/src/cert_rules.py b/src/cert_rules.py
index 67069f23..8623996c 100644
--- a/src/cert_rules.py
+++ b/src/cert_rules.py
@@ -1,21 +1,21 @@
rules_cert_id = [
- 'BSI-DSZ-CC-[0-9]+?-[0-9]+', # German BSI
- 'BSI-DSZ-CC-[0-9]+?-(?:V|v)[0-9]+-[0-9]+', # German BSI
- 'BSI-DSZ-CC-[0-9]+?-(?:V|v)[0-9]+', # German BSI
- 'BSI [0-9]+?', # German BSI
- #'CC-Zert-.+?',
- 'ANSSI(?:-|-CC-)[0-9]+?/[0-9]+', # French
- #'ANSSI-CC-CER-F-.+?', # French
- 'DCSSI-[0-9]+?/[0-9]+?', # French
- 'Certification Report [0-9]+?/[0-9]+?', # French
- 'Rapport de certification [0-9]+?/[0-9]+?', # French
- 'NSCIB-CC-[0-9][0-9][0-9][0-9].+?', # Netherlands
- 'NSCIB-CC-[0-9][0-9][0-9][0-9][0-9]*-CR', # Netherlands
+ 'BSI-DSZ-CC-[0-9]+?-[0-9]+', # German BSI
+ 'BSI-DSZ-CC-[0-9]+?-(?:V|v)[0-9]+-[0-9]+', # German BSI
+ 'BSI-DSZ-CC-[0-9]+?-(?:V|v)[0-9]+', # German BSI
+ 'BSI [0-9]+?', # German BSI
+ # 'CC-Zert-.+?',
+ 'ANSSI(?:-|-CC-)[0-9]+?/[0-9]+', # French
+ # 'ANSSI-CC-CER-F-.+?', # French
+ 'DCSSI-[0-9]+?/[0-9]+?', # French
+ 'Certification Report [0-9]+?/[0-9]+?', # French
+ 'Rapport de certification [0-9]+?/[0-9]+?', # French
+ 'NSCIB-CC-[0-9][0-9][0-9][0-9].+?', # Netherlands
+ 'NSCIB-CC-[0-9][0-9][0-9][0-9][0-9]*-CR', # Netherlands
'NSCIB-CC-[0-9][0-9]-[0-9]+?-CR[0-9]+?', # Netherlands
- 'SERTIT-[0-9]+?', # Norway
- 'CCEVS-VR-(?:|VID)[0-9]+?-[0-9]+?', # US NSA
- #'[0-9][0-9\-]+?-CR', # Canada
- 'CRP[0-9][0-9][0-9][0-9]*?', # UK CESG
+ 'SERTIT-[0-9]+?', # Norway
+ 'CCEVS-VR-(?:|VID)[0-9]+?-[0-9]+?', # US NSA
+ # '[0-9][0-9\-]+?-CR', # Canada
+ 'CRP[0-9][0-9][0-9][0-9]*?', # UK CESG
'CERTIFICATION REPORT No. P[0-9]+?', # UK CESG
'20[0-9][0-9]-[0-9]+-INF-[0-9]+?', # Spain
'KECS-CR-[0-9]+?-[0-9]+?', # Korea
@@ -25,7 +25,7 @@ rules_cert_id = [
'OCSI/CERT/.+?', # Italia
'[0-9\\.]+?/TSE-CCCS-[0-9]+?', # Turkis CCCS
'BTBD-.+?', # Turkis CCCS
- ]
+]
rules_vendor = [
'NXP',
@@ -41,12 +41,12 @@ rules_vendor = [
'(?:G\&D|G\+D|Giesecke+Devrient|Giesecke \& Devrient)',
'Philips',
'Sagem',
- ]
+]
rules_eval_facilities = [
'Serma Technologies',
'THALES - CEACI'
- ]
+]
rules_protection_profiles = [
'BSI-(?:CC[-_]|)PP[-_]*.+?',
@@ -59,22 +59,21 @@ rules_protection_profiles = [
'ANSSI-CC-PP.+?',
'WBIS_V[0-9]\\.[0-9]',
'EHCT_V.+?'
- ]
+]
rules_technical_reports = [
'BSI[ ]*TR-[0-9]+?(?:-[0-9]+?|)',
- ]
-
+]
rules_device_id = [
'G87-.+?',
'ATMEL AT.+?',
- ]
+]
rules_os = [
'STARCOS(?: [0-9\\.]+?|)',
'JCOP[ ]*[0-9]'
- ]
+]
rules_standard_id = [
'FIPS ?(?:PUB )?[0-9]+-[0-9]+?',
@@ -92,13 +91,13 @@ rules_standard_id = [
'ICAO(?:-SAC|)',
'[Xx]\\.509',
'RFC [0-9]+'
- ]
+]
rules_security_level = [
'EAL[ ]*[0-9+]+?',
'EAL[ ]*[0-9] augmented+?',
'ITSEC[ ]*E[1-9]*.+?',
- ]
+]
rules_security_assurance_components = [
r'ACE_[A-Z]{3}(?:\.[0-9]|)',
@@ -136,7 +135,7 @@ rules_javacard = [
r'(?:Java Card|JavaCard) \(version [2-3]\.[0-9](?:\.[0-9]|)\)',
r'(?:Global Platform|GlobalPlatform) [2-3]\.[0-9]\.[0-9]',
r'(?:Global Platform|GlobalPlatform) \(version [2-3]\.[0-9]\.[0-9]\)',
- ]
+]
rules_crypto_algs = [
'RSA[- ]*(?:512|768|1024|1280|1536|2048|3072|4096|8192)',
@@ -156,7 +155,7 @@ rules_crypto_algs = [
'DTRNG',
'TRNG',
'RN[GD]',
- 'RBG'
+ 'RBG',
]
rules_block_cipher_modes = [
@@ -165,7 +164,7 @@ rules_block_cipher_modes = [
'CTR',
'CFB',
'OFB',
- 'GCM'
+ 'GCM',
]
rules_ecc_curves = [
@@ -187,15 +186,14 @@ rules_cplc = [
'IC[ ]*Fabricator',
'IC[ ]*Type',
'IC[ ]*Version',
- ]
+]
rules_crypto_engines = [
'TORNADO',
'SmartMX',
'SmartMX2'
'NesCrypt',
- ]
-
+]
rules_crypto_libs = [
'(?:NesLib|NESLIB) [v]*[0-9.]+',
@@ -203,8 +201,8 @@ rules_crypto_libs = [
'AT1 Secure RSA/ECC/SHA library',
'Crypto Library [v]*[0-9.]+',
'ATMEL Toolbox [0-9.]+',
- 'v1.02.013' # Infineon's ROCA-vulnerable library
- ]
+ 'v1.02.013' # Infineon's ROCA-vulnerable library
+]
rules_IC_data_groups = [
r'EF\.DG[1-9][0-6]?',
@@ -225,8 +223,7 @@ rules_defenses = [
'DFA',
'[Ff]+ault induction',
'ROCA',
- ]
-
+]
rules_certification_process = [
'[oO]ut of [sS]cope',
@@ -234,19 +231,99 @@ rules_certification_process = [
'.{0,100}[oO]ut of [sS]cope.{0,100}',
'.{0,100}confidential document.{0,100}',
'[sS]ecurity [fF]unction SF\\.[a-zA-Z0-9_]',
- ]
+]
rules_vulnerabilities = [
'CVE-[0-9]+?-[0-9]+?',
'CWE-[0-9]+?',
- ]
+]
rules_other = [
'library',
- #'http[s]*://.+?/'
- ]
+ # 'http[s]*://.+?/'
+]
+
+rules_fips_remove_algorithm_ids = [
+ r"HMAC(?:-SHA)?[ -]*((?:160|224|256|384|512)?(?: |[Dd]ecrypt|[Ee]ncrypt|KAT)*?[, ]*?(?:#|Cert\.?|Certificate)?[\s#]*?)?\s?(\d{4})",
+ r"HMAC(?:-SHA)?[ -]*((?:160|224|256|384|512)?(?: |[Dd]ecrypt|[Ee]ncrypt|KAT)*?[, ]*?(?:#|Cert\.?|Certificate)?[\s#]*?)?\s?(\d{3})",
+ r"HMAC(?:-SHA)?[ -]*((?:160|224|256|384|512)?(?: |[Dd]ecrypt|[Ee]ncrypt|KAT)*?[, ]*?(?:#|Cert\.?|Certificate)?[\s#]*?)?\s?(\d{2})",
+ r"HMAC(?:-SHA)?[ -]*((?:160|224|256|384|512)?(?: |[Dd]ecrypt|[Ee]ncrypt|KAT)*?[, ]*?(?:#|Cert\.?|Certificate)?[\s#]*?)?\s?(\d{1})",
+ r"SH[SA][-]*(?:160|224|256|384|512)?(?:[\s]*?(?:KAT)?[\s,]*?[\s(]*?(?:#|Cert\.?|Certificate)?[\s#]*?)(\d{4})(?:\)?\[#?\d+\])?",
+ r"SH[SA][-]*(?:160|224|256|384|512)?(?:[\s]*?(?:KAT)?[\s,]*?[\s(]*?(?:#|Cert\.?|Certificate)?[\s#]*?)(\d{3})(?:\)?\[#?\d+\])?",
+ r"SH[SA][-]*(?:160|224|256|384|512)?(?:[\s]*?(?:KAT)?[\s,]*?[\s(]*?(?:#|Cert\.?|Certificate)?[\s#]*?)(\d{2})(?:\)?\[#?\d+\])?",
+ r"SH[SA][-]*(?:160|224|256|384|512)?(?:[\s]*?(?:KAT)?[\s,]*?[\s(]*?(?:#|Cert\.?|Certificate)?[\s#]*?)(\d{1})(?:\)?\[#?\d+\])?",
+ r"RSA(?:[- ]*(?:512|768|1024|1280|1536|2048|3072|4096|8192)\s]*?(?:(?:KAT|Verify|PSS|\s)*?)?[\s,]*?[\s(]*?(?:#|Cert\.?|Certificate)?[\s#]*?)?\s?(\d{4})",
+ r"RSA(?:[- ]*(?:512|768|1024|1280|1536|2048|3072|4096|8192)\s]*?(?:(?:KAT|Verify|PSS|\s)*?)?[\s,]*?[\s(]*?(?:#|Cert\.?|Certificate)?[\s#]*?)?\s?(\d{3})",
+ r"RSA(?:[- ]*(?:512|768|1024|1280|1536|2048|3072|4096|8192)\s]*?(?:(?:KAT|Verify|PSS|\s)*?)?[\s,]*?[\s(]*?(?:#|Cert\.?|Certificate)?[\s#]*?)?\s?(\d{2})",
+ r"RSA(?:[- ]*(?:512|768|1024|1280|1536|2048|3072|4096|8192)\s]*?(?:(?:KAT|Verify|PSS|\s)*?)?[\s,]*?[\s(]*?(?:#|Cert\.?|Certificate)?[\s#]*?)?\s?(\d{1})",
+ r"(?:RSA)?[- ]?(?:SSA)?[- ]?PKCS\s?#?\d(?:-[Vv]1_5| [Vv]1[-_]5)?\s?(\d{4})?",
+ r"(?:RSA)?[- ]?(?:SSA)?[- ]?PKCS\s?#?\d(?:-[Vv]1_5| [Vv]1[-_]5)?\s?(\d{3})?",
+ r"(?:RSA)?[- ]?(?:SSA)?[- ]?PKCS\s?#?\d(?:-[Vv]1_5| [Vv]1[-_]5)?\s?(\d{2})?",
+ r"(?:RSA)?[- ]?(?:SSA)?[- ]?PKCS\s?#?\d(?:-[Vv]1_5| [Vv]1[-_]5)?\s?(\d{1})?",
+ r"AES[- ]*((?:128|192|256|)?(?: |[Dd]ecrypt|[Ee]ncrypt|KAT|CMAC|CTR)*?[,\s(]*?(?:#|Cert\.?|Certificate)?[\s#]*?)?\s?(\d{4})(?:\)?\[#?\d+\])?",
+ r"AES[- ]*((?:128|192|256|)?(?: |[Dd]ecrypt|[Ee]ncrypt|KAT|CMAC|CTR)*?[,\s(]*?(?:#|Cert\.?|Certificate)?[\s#]*?)?\s?(\d{3})(?:\)?\[#?\d+\])?",
+ r"AES[- ]*((?:128|192|256|)?(?: |[Dd]ecrypt|[Ee]ncrypt|KAT|CMAC|CTR)*?[,\s(]*?(?:#|Cert\.?|Certificate)?[\s#]*?)?\s?(\d{2})(?:\)?\[#?\d+\])?",
+ r"AES[- ]*((?:128|192|256|)?(?: |[Dd]ecrypt|[Ee]ncrypt|KAT|CMAC|CTR)*?[,\s(]*?(?:#|Cert\.?|Certificate)?[\s#]*?)?\s?(\d{1})(?:\)?\[#?\d+\])?",
+ r"Diffie[- ]*Hellman[,\s(]*?(?:CVL|\s)*?(?:#|Cert\.?|Certificate)?[\s#]*?\s?(\d{4})",
+ r"Diffie[- ]*Hellman[,\s(]*?(?:CVL|\s)*?(?:#|Cert\.?|Certificate)?[\s#]*?\s?(\d{3})",
+ r"Diffie[- ]*Hellman[,\s(]*?(?:CVL|\s)*?(?:#|Cert\.?|Certificate)?[\s#]*?\s?(\d{2})",
+ r"Diffie[- ]*Hellman[,\s(]*?(?:CVL|\s)*?(?:#|Cert\.?|Certificate)?[\s#]*?\s?(\d{1})",
+ r"DRBG[ -]*((?:160|224|256|384|512)?(?: |[Dd]ecrypt|[Ee]ncrypt|KAT)*?[,\s]*?(?:#|Cert\.?|Certificate)?[\s#]*?)?\s?(\d{4})",
+ r"DRBG[ -]*((?:160|224|256|384|512)?(?: |[Dd]ecrypt|[Ee]ncrypt|KAT)*?[,\s]*?(?:#|Cert\.?|Certificate)?[\s#]*?)?\s?(\d{3})",
+ r"DRBG[ -]*((?:160|224|256|384|512)?(?: |[Dd]ecrypt|[Ee]ncrypt|KAT)*?[,\s]*?(?:#|Cert\.?|Certificate)?[\s#]*?)?\s?(\d{2})",
+ r"DRBG[ -]*((?:160|224|256|384|512)?(?: |[Dd]ecrypt|[Ee]ncrypt|KAT)*?[,\s]*?(?:#|Cert\.?|Certificate)?[\s#]*?)?\s?(\d{1})",
+ r"DES[ -]*((?:160|224|256|384|512)?(?: |[Dd]ecrypt|[Ee]ncrypt|KAT)*?[,\s]*?(?:#|Cert\.?|Certificate)?[\s#]*?)?\s?(\d{4})",
+ r"DES[ -]*((?:160|224|256|384|512)?(?: |[Dd]ecrypt|[Ee]ncrypt|KAT)*?[,\s]*?(?:#|Cert\.?|Certificate)?[\s#]*?)?\s?(\d{3})",
+ r"DES[ -]*((?:160|224|256|384|512)?(?: |[Dd]ecrypt|[Ee]ncrypt|KAT)*?[,\s]*?(?:#|Cert\.?|Certificate)?[\s#]*?)?\s?(\d{2})",
+ r"DES[ -]*((?:160|224|256|384|512)?(?: |[Dd]ecrypt|[Ee]ncrypt|KAT)*?[,\s]*?(?:#|Cert\.?|Certificate)?[\s#]*?)?\s?(\d{1})",
+ r"CVL[\s#]*?(\d{4})",
+ r"CVL[\s#]*?(\d{3})",
+ r"CVL[\s#]*?(\d{2})",
+ r"CVL[\s#]*?(\d{1})",
+ r"PAA[: #]*?\d{4}",
+ r"PAA[: #]*?\d{3}",
+ r"PAA[: #]*?\d{2}",
+ r"PAA[: #]*?\d{1}",
+ r"(?:#|Cert\.?|Certificate)[\s#]*?(\d+)?\s*?(?:AES|SHS|SHA|RSA|HMAC|Diffie-Hellman|DRBG|DES|CVL)",
+ r"PKCS[ ]?#?\d+",
+ r"Survey #192" # why would they get an address like this /o\ cert 2079
+]
+rules_fips_cert = [
+ # r"(?:#\s?|Cert\.?[^. ]*?\s?)(?P<id>\d{4})",
+ # r"(?:#\s?|Cert\.?[^. ]*?\s?)(?P<id>\d{3})",
+ # r"(?:#\s?|Cert\.?[^. ]*?\s?)(?P<id>\d{2})",
+ # r"(?:#\s?|Cert\.?[^. ]*?\s?)(?P<id>\d{1})
+ r"(?:#[^\S\r\n]?|Cert\.?(?!.\s)[^\S\r\n]?|Certificate[^\S\r\n]?)(?P<id>\d{4})",
+ r"(?:#[^\S\r\n]?|Cert\.?(?!.\s)[^\S\r\n]?|Certificate[^\S\r\n]?)(?P<id>\d{3})",
+ r"(?:#[^\S\r\n]?|Cert\.?(?!.\s)[^\S\r\n]?|Certificate[^\S\r\n]?)(?P<id>\d{2})",
+ r"(?:#[^\S\r\n]?|Cert\.?(?!.\s)[^\S\r\n]?|Certificate[^\S\r\n]?)(?P<id>\d{1})"
+]
+
+# rule still too "general"
+rules_fips_security_level = [
+ r"[lL]evel (\d)"
+]
-#rules_security_target_class
+rules_fips_htmls = [
+ r"module-name\">\s*(?P<fips_module_name>[^<]*)",
+ r"module-standard\">\s*(?P<fips_standard>[^<]*)",
+ r"Status[\s\S]*?\">\s*(?P<fips_status>[^<]*)",
+ r"Sunset Date[\s\S]*?\">\s*(?P<fips_date_sunset>[^<]*)",
+ r"Validation Dates[\s\S]*?\">\s*(?P<fips_date_validation>[^<]*)",
+ r"Overall Level[\s\S]*?\">\s*(?P<fips_level>[^<]*)",
+ r"Caveat[\s\S]*?\">\s*(?P<fips_caveat>[^<]*)",
+ r"Security Level Exceptions[\s\S]*?\">\s*(?P<fips_exceptions><ul.*</ul>)",
+ r"Module Type[\s\S]*?\">\s*(?P<fips_type>[^<]*)",
+ r"Embodiment[\s\S]*?\">\s*(?P<fips_embodiment>[^<]*)",
+ r"Tested Configuration[\s\S]*?\">\s*(?P<fips_tested_conf><ul.*</ul>)",
+ r"FIPS Algorithms[\s\S]*?\">\s*(?P<fips_algorithms><tbody>[\s\S]*</tbody>)",
+ r"Allowed Algorithms[\s\S]*?\">\s*(?P<fips_allowed_algorithms>[^<]*)",
+ r"Software Versions[\s\S]*?\">\s*(?P<fips_software>[^<]*)",
+ r"Product URL[\s\S]*?\">\s*<a href=\"(?P<fips_url>.*)\"",
+ r"Vendor<\/h4>[\s\S]*?href=\".*?\">(?P<fips_vendor>.*?)<\/a>"
+]
+
+# rules_security_target_class
rules = {}
rules['rules_vendor'] = rules_vendor
rules['rules_cert_id'] = rules_cert_id
@@ -270,3 +347,11 @@ rules['rules_defenses'] = rules_defenses
rules['rules_certification_process'] = rules_certification_process
rules['rules_vulnerabilities'] = rules_vulnerabilities
rules['rules_other'] = rules_other
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# For FIPS
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+fips_rules = {}
+fips_rules['rules_fips_algorithms'] = rules_fips_remove_algorithm_ids
+fips_rules['rules_security_level'] = rules_fips_security_level
+fips_rules['rules_cert_id'] = rules_fips_cert
diff --git a/src/download_files.py b/src/download_files.py
new file mode 100644
index 00000000..a877593c
--- /dev/null
+++ b/src/download_files.py
@@ -0,0 +1,36 @@
+import extract_certificates
+
+FILE_ERRORS_STRATEGY = extract_certificates.FILE_ERRORS_STRATEGY
+
+
+def generate_fips_basic_download_script():
+ with open('download_fips_web.bat', 'w', errors=FILE_ERRORS_STRATEGY) as file:
+ file.write(
+ 'curl "https://csrc.nist.gov/projects/cryptographic-module-validation-program/validated-modules/search'
+ '/all" -o fips_modules_validated.html\n')
+
+
+def generate_fips_download_script(file_name, fips_dir):
+ """generate_fips_download_script.
+
+ :param file_name: name of the download file
+ :param fips_dir: directory for saved files
+ """
+ html_dir = fips_dir + '/html/'
+ sp_dir = fips_dir + '/security_policies/'
+
+ with open(file_name, 'w', errors=FILE_ERRORS_STRATEGY) as write_file:
+ # make directories for both html and security policies, scraping in one go
+ write_file.write('mkdir {}\n'.format(html_dir))
+ write_file.write('mkdir {}\n\n'.format(sp_dir))
+
+ for cert_id in range(1, 4001):
+ write_file.write(
+ 'curl "https://csrc.nist.gov/projects/cryptographic-module-validation-program/certificate/{}" -o {}{}.html\n'.format(
+ cert_id, html_dir, cert_id))
+ write_file.write(
+ 'curl "https://csrc.nist.gov/CSRC/media/projects/cryptographic-module-validation-program/documents'
+ '/security-policies/140sp{}.pdf" -o {}{}.pdf\n'.format(
+ cert_id, sp_dir, cert_id))
+ write_file.write("{} {}{}.pdf\n".format(
+ extract_certificates.PDF2TEXT_CONVERT, sp_dir, cert_id))
diff --git a/src/extract_certificates.py b/src/extract_certificates.py
index ada54be2..887f06a4 100644
--- a/src/extract_certificates.py
+++ b/src/extract_certificates.py
@@ -1,3 +1,5 @@
+from PyPDF2 import PdfFileReader
+from tags_constants import *
import re
import os
import operator
@@ -7,12 +9,11 @@ import csv
import string
from analyze_certificates import is_in_dict
-from cert_rules import rules
+from cert_rules import rules, fips_rules
from enum import Enum
-import matplotlib.pyplot as plt; plt.rcdefaults()
-from tags_constants import *
+import matplotlib.pyplot as plt
-from PyPDF2 import PdfFileReader
+plt.rcdefaults()
# if True, then exception is raised when unexpect intermediate number is obtained
# Used as sanity check during development to detect sudden drop in number of extracted features
@@ -21,16 +22,17 @@ APPEND_DETAILED_MATCH_MATCHES = False
VERBOSE = False
FILE_ERRORS_STRATEGY = 'surrogateescape'
'replace'
-#FILE_ERRORS_STRATEGY = 'strict'
+# FILE_ERRORS_STRATEGY = 'strict'
CC_WEB_URL = 'https://www.commoncriteriaportal.org'
PDF2TEXT_CONVERT = 'pdftotext -raw'
REGEXEC_SEP = '[ ,;\]”)(]'
LINE_SEPARATOR = ' '
-#LINE_SEPARATOR = '' # if newline is not replaced with space, long string included in matches are found
+# LINE_SEPARATOR = '' # if newline is not replaced with space, long string included in matches are found
printable = set(string.printable)
+
def search_files(folder):
for root, dirs, files in os.walk(folder):
yield from [os.path.join(root, x) for x in files]
@@ -49,7 +51,6 @@ def get_line_number(lines, line_length_compensation, match_start_index):
return -1
-
def load_cert_file(file_name, limit_max_lines=-1, line_separator=LINE_SEPARATOR):
lines = []
was_unicode_decode_error = False
@@ -76,7 +77,8 @@ def load_cert_file(file_name, limit_max_lines=-1, line_separator=LINE_SEPARATOR)
whole_text_with_newlines = ''
# we will estimate the line for searched matches
# => we need to known how much lines were modified (removal of eoln..)
- line_length_compensation = 1 - len(LINE_SEPARATOR) # for removed newline and for any added separator
+ # for removed newline and for any added separator
+ line_length_compensation = 1 - len(LINE_SEPARATOR)
lines_included = 0
for line in lines:
if limit_max_lines != -1 and lines_included >= limit_max_lines:
@@ -109,7 +111,7 @@ def normalize_match_string(match):
# normalize match
match = match.strip()
match = match.rstrip(']')
- match = match.rstrip('/')
+ match = match.rstrip(os.sep)
match = match.rstrip(';')
match = match.rstrip('.')
match = match.rstrip('”')
@@ -131,12 +133,16 @@ def set_match_string(items, key_name, new_value):
else:
old_value = items[key_name]
if old_value != new_value:
- print(' WARNING: values mismatch, key=\'{}\', old=\'{}\', new=\'{}\''.format(key_name, old_value, new_value))
+ print(' WARNING: values mismatch, key=\'{}\', old=\'{}\', new=\'{}\''.format(
+ key_name, old_value, new_value))
-def parse_cert_file(file_name, search_rules, limit_max_lines=-1, line_separator=LINE_SEPARATOR):
- whole_text, whole_text_with_newlines, was_unicode_decode_error = load_cert_file(file_name, limit_max_lines, line_separator)
+def parse_cert_file(file_name, search_rules, limit_max_lines=-1, line_separator=LINE_SEPARATOR,
+ should_censure_right_away=False, fips_items=None, ):
+ whole_text, whole_text_with_newlines, was_unicode_decode_error = load_cert_file(
+ file_name, limit_max_lines, line_separator)
+ file_name = os.path.splitext(os.path.splitext(os.path.basename(file_name))[0])[0]
# apply all rules
items_found_all = {}
for rule_group in search_rules.keys():
@@ -146,15 +152,31 @@ def parse_cert_file(file_name, search_rules, limit_max_lines=-1, line_separator=
items_found = items_found_all[rule_group]
for rule in search_rules[rule_group]:
+
rule_and_sep = rule + REGEXEC_SEP
- for m in re.finditer(rule_and_sep, whole_text):
+ for m in re.finditer(rule_and_sep, whole_text_with_newlines):
# insert rule if at least one match for it was found
if rule not in items_found:
items_found[rule] = {}
match = m.group()
match = normalize_match_string(match)
+ is_algorithm = False
+ if fips_items and match != '':
+ certs = [x['Certificate']
+ for x in fips_items[file_name]['fips_algorithms']]
+
+ match_cert_id = ''.join(filter(str.isdigit, match))
+ # if file_name == '/home/stan/sec-certs-master/files/fips/security_policies/3676.html.txt':
+
+ for fips_cert in certs:
+ for actual_cert in fips_cert:
+ if actual_cert != '' and match_cert_id == ''.join(filter(str.isdigit, actual_cert)):
+ is_algorithm = True
+
+ if is_algorithm:
+ continue
if match not in items_found[rule]:
items_found[rule][match] = {}
@@ -169,28 +191,37 @@ def parse_cert_file(file_name, search_rules, limit_max_lines=-1, line_separator=
# estimate line in original text file
# line_number = get_line_number(lines, line_length_compensation, match_span[0])
# start index, end index, line number
- #items_found[rule][match][TAG_MATCH_MATCHES].append([match_span[0], match_span[1], line_number])
+ # items_found[rule][match][TAG_MATCH_MATCHES].append([match_span[0], match_span[1], line_number])
if APPEND_DETAILED_MATCH_MATCHES:
- items_found[rule][match][TAG_MATCH_MATCHES].append([match_span[0], match_span[1]])
+ items_found[rule][match][TAG_MATCH_MATCHES].append(
+ [match_span[0], match_span[1]])
+ if should_censure_right_away:
+ whole_text_with_newlines = whole_text_with_newlines.replace(
+ match, 'x' * len(match))
# highlight all found strings from the input text and store the rest
- for rule_group in items_found_all.keys():
- items_found = items_found_all[rule_group]
- for rule in items_found.keys():
- for match in items_found[rule]:
- whole_text_with_newlines = whole_text_with_newlines.replace(match, 'x' * len(match)) # warning - if AES string is removed before AES-128, -128 will be left in text (does it matter?)
+ if not should_censure_right_away:
+ for rule_group in items_found_all.keys():
+ items_found = items_found_all[rule_group]
+ for rule in items_found.keys():
+ for match in items_found[rule]:
+ # warning - if AES string is removed before AES-128, -128 will be left in text (does it matter?)
+ whole_text_with_newlines = whole_text_with_newlines.replace(
+ match, 'x' * len(match))
return items_found_all, (whole_text_with_newlines, was_unicode_decode_error)
def print_total_matches_in_files(all_items_found_count):
- sorted_all_items_found_count = sorted(all_items_found_count.items(), key=operator.itemgetter(1))
+ sorted_all_items_found_count = sorted(
+ all_items_found_count.items(), key=operator.itemgetter(1))
for file_name_count in sorted_all_items_found_count:
print('{:03d}: {}'.format(file_name_count[1], file_name_count[0]))
def print_total_found_cert_ids(all_items_found_certid_count):
- sorted_certid_count = sorted(all_items_found_certid_count.items(), key=operator.itemgetter(1), reverse=True)
+ sorted_certid_count = sorted(
+ all_items_found_certid_count.items(), key=operator.itemgetter(1), reverse=True)
for file_name_count in sorted_certid_count:
print('{:03d}: {}'.format(file_name_count[1], file_name_count[0]))
@@ -199,8 +230,8 @@ def print_guessed_cert_id(cert_id):
sorted_cert_id = sorted(cert_id.items(), key=operator.itemgetter(1))
for double in sorted_cert_id:
just_file_name = double[0]
- if just_file_name.rfind('\\') != -1:
- just_file_name = just_file_name[just_file_name.rfind('\\') + 1:]
+ if just_file_name.rfind(os.sep) != -1:
+ just_file_name = just_file_name[just_file_name.rfind(os.sep) + 1:]
print('{:30s}: {}'.format(double[1], just_file_name))
@@ -247,19 +278,21 @@ def estimate_cert_id(frontpage_scan, keywords_scan, file_name):
keywords_cert_id = match
num_items_found_certid_group += num_occurences
if VERBOSE:
- print(' -> most frequent cert id: {}, {}x'.format(keywords_cert_id, num_items_found_certid_group))
+ print(' -> most frequent cert id: {}, {}x'.format(keywords_cert_id,
+ num_items_found_certid_group))
# try to search for certificate id directly in file name - if found, higher priority
filename_cert_id = ''
if file_name != None:
file_name_no_suff = file_name[:file_name.rfind('.')]
- file_name_no_suff = file_name_no_suff[file_name_no_suff.rfind('\\') + 1:]
+ file_name_no_suff = file_name_no_suff[file_name_no_suff.rfind(
+ os.sep) + 1:]
for rule in rules['rules_cert_id']:
file_name_no_suff += ' '
matches = re.findall(rule, file_name_no_suff)
if len(matches) > 0:
# we found cert id directly in name
- #print(' -> cert id found directly in certificate name: {}'.format(matches[0]))
+ # print(' -> cert id found directly in certificate name: {}'.format(matches[0]))
filename_cert_id = matches[0]
if VERBOSE:
@@ -302,9 +335,11 @@ def print_specified_property_sorted(section_name, item_name, items_found_all):
for file_name in items_found_all.keys():
if section_name in items_found_all[file_name].keys():
if item_name in items_found_all[file_name][section_name].keys():
- specific_item_values.append(items_found_all[file_name][item_name])
+ specific_item_values.append(
+ items_found_all[file_name][item_name])
else:
- print('WARNING: Item {} not found in file {}'.format(item_name, file_name))
+ print('WARNING: Item {} not found in file {}'.format(
+ item_name, file_name))
print('*** Occurrences of *{}* item'.format(item_name))
sorted_items = sorted(specific_item_values)
@@ -314,16 +349,18 @@ def print_specified_property_sorted(section_name, item_name, items_found_all):
def print_found_properties(items_found_all):
print_specified_property_sorted(TAG_CERT_ID, items_found_all)
- print_specified_property_sorted(TAG_CERT_ITEM , items_found_all)
+ print_specified_property_sorted(TAG_CERT_ITEM, items_found_all)
print_specified_property_sorted(TAG_CERT_ITEM_VERSION, items_found_all)
- print_specified_property_sorted(TAG_REFERENCED_PROTECTION_PROFILES, items_found_all)
- print_specified_property_sorted(TAG_CC_VERSION , items_found_all)
+ print_specified_property_sorted(
+ TAG_REFERENCED_PROTECTION_PROFILES, items_found_all)
+ print_specified_property_sorted(TAG_CC_VERSION, items_found_all)
print_specified_property_sorted(TAG_CC_SECURITY_LEVEL, items_found_all)
- print_specified_property_sorted(TAG_DEVELOPER , items_found_all)
+ print_specified_property_sorted(TAG_DEVELOPER, items_found_all)
print_specified_property_sorted(TAG_CERT_LAB, items_found_all)
def search_only_headers_bsi(walk_dir):
+ print('BSI HEADER SEARCH')
LINE_SEPARATOR_STRICT = ' '
NUM_LINES_TO_INVESTIGATE = 15
rules_certificate_preface = [
@@ -340,13 +377,14 @@ def search_only_headers_bsi(walk_dir):
file_ext = file_name[file_name.rfind('.'):]
if file_ext != '.txt':
continue
- print('*** {} ***'.format(file_name))
+ # print('*** {} ***'.format(file_name))
no_match_yet = True
#
# Process front page with info: cert_id, certified_item and developer
#
- whole_text, whole_text_with_newlines, was_unicode_decode_error = load_cert_file(file_name, NUM_LINES_TO_INVESTIGATE, LINE_SEPARATOR_STRICT)
+ whole_text, whole_text_with_newlines, was_unicode_decode_error = load_cert_file(
+ file_name, NUM_LINES_TO_INVESTIGATE, LINE_SEPARATOR_STRICT)
for rule in rules_certificate_preface:
rule_and_sep = rule + REGEXEC_SEP
@@ -372,9 +410,13 @@ def search_only_headers_bsi(walk_dir):
for from_keyword in FROM_KEYWORD_LIST:
from_keyword_len = len(from_keyword)
if certified_item.find(from_keyword) != -1:
- print('string **{}** detected in certified item - shall not be here, fixing...'.format(from_keyword))
- certified_item_first = certified_item[:certified_item.find(from_keyword)]
- developer = certified_item[certified_item.find(from_keyword) + from_keyword_len:]
+ print(
+ 'string **{}** detected in certified item - shall not be here, fixing...'.format(
+ from_keyword))
+ certified_item_first = certified_item[:certified_item.find(
+ from_keyword)]
+ developer = certified_item[certified_item.find(
+ from_keyword) + from_keyword_len:]
certified_item = certified_item_first
continue
@@ -387,7 +429,8 @@ def search_only_headers_bsi(walk_dir):
developer = developer[:end_pos]
items_found[TAG_CERT_ID] = normalize_match_string(cert_id)
- items_found[TAG_CERT_ITEM] = normalize_match_string(certified_item)
+ items_found[TAG_CERT_ITEM] = normalize_match_string(
+ certified_item)
items_found[TAG_DEVELOPER] = normalize_match_string(developer)
items_found[TAG_CERT_LAB] = 'BSI'
@@ -398,7 +441,8 @@ def search_only_headers_bsi(walk_dir):
'PP Conformance: (.+)Functionality: (.+)Assurance: (.+)The IT Product identified',
]
- whole_text, whole_text_with_newlines, was_unicode_decode_error = load_cert_file(file_name)
+ whole_text, whole_text_with_newlines, was_unicode_decode_error = load_cert_file(
+ file_name)
for rule in rules_certificate_third:
rule_and_sep = rule + REGEXEC_SEP
@@ -413,9 +457,12 @@ def search_only_headers_bsi(walk_dir):
cc_version = match_groups[1]
cc_security_level = match_groups[2]
- items_found[TAG_REFERENCED_PROTECTION_PROFILES] = normalize_match_string(ref_protection_profiles)
- items_found[TAG_CC_VERSION] = normalize_match_string(cc_version)
- items_found[TAG_CC_SECURITY_LEVEL] = normalize_match_string(cc_security_level)
+ items_found[TAG_REFERENCED_PROTECTION_PROFILES] = normalize_match_string(
+ ref_protection_profiles)
+ items_found[TAG_CC_VERSION] = normalize_match_string(
+ cc_version)
+ items_found[TAG_CC_SECURITY_LEVEL] = normalize_match_string(
+ cc_security_level)
if no_match_yet:
files_without_match.append(file_name)
@@ -443,64 +490,105 @@ def search_only_headers_anssi(walk_dir):
HEADER_DUPLICITIES = 4
rules_certificate_preface = [
- (HEADER_TYPE.HEADER_FULL, 'Référence du rapport de certification(.+)Nom du produit(.+)Référence/version du produit(.*)Conformité à un profil de protection(.+)Critères d\'évaluation et version(.+)Niveau d\'évaluation(.+)Développeurs(.+)Centre d\'évaluation(.+)Accords de reconnaissance applicables'),
- (HEADER_TYPE.HEADER_FULL, 'Référence du rapport de certification(.+)Nom du produit(.+)Référence/version du produit(.*)Conformité à un profil de protection(.+)Critères d’évaluation et version(.+)Niveau d’évaluation(.+)Développeurs(.+)Centre d’évaluation(.+)Accords de reconnaissance applicables'),
- (HEADER_TYPE.HEADER_FULL, 'Référence du rapport de certification(.+)Nom du produit(.+)()Conformité à un profil de protection(.+)Critères d\'évaluation et version(.+)Niveau d\'évaluation(.+)Développeur (.+)Centre d\'évaluation(.+)Accords de reconnaissance applicables'),
- (HEADER_TYPE.HEADER_FULL, 'Référence du rapport de certification(.+)Nom des produits(.+)Référence/version des produits(.+)Conformité à un profil de protection(.+)Critères d\'évaluation et version(.+)Niveau d\'évaluation(.+)Développeur\(s\)(.+)Centre d\'évaluation(.+)Accords de reconnaissance applicables'),
- (HEADER_TYPE.HEADER_FULL, 'Référence du rapport de certification(.+)Nom des produits(.+)Référence/version des produits(.+)Conformité à un profil de protection(.+)Critères d\'évaluation et version(.+)Niveau d\'évaluation(.+)Développeur (.+)Centre d\'évaluation(.+)Accords de reconnaissance'),
- (HEADER_TYPE.HEADER_FULL, 'Référence du rapport de certification(.+)Nom du produit(.+)Référence/version du produit(.+)Conformité aux profils de protection(.+)Critères d’évaluation et version(.+)Niveau d’évaluation(.+)Développeur\(s\)(.+)Centre d’évaluation(.+)Accords de reconnaissance applicables'),
- (HEADER_TYPE.HEADER_FULL, 'Référence du rapport de certification(.+)Nom du produit(.+)Référence/version du produit(.+)Conformité à un profil de protection(.+)Critères d’évaluation et version(.+)Niveau d’évaluation(.+)Développeur\(s\)(.+)Centre d’évaluation(.+)Accords de reconnaissance applicables'),
- (HEADER_TYPE.HEADER_FULL, 'Référence du rapport de certification(.+)Nom du produit(.+)Référence/version du produit(.+)Conformité à un profil de protection(.+)Critères d’évaluation et version(.+)Niveau d’évaluation(.+)Développeur (.+)Centre d’évaluation(.+)Accords de reconnaissance applicables'),
- (HEADER_TYPE.HEADER_FULL, 'Référence du rapport de certification(.+)Nom du produit(.+)Référence/version du produit(.+)Conformité à des profils de protection(.+)Critères d’évaluation et version(.+)Niveau d’évaluation(.+)Développeurs(.+)Centre d’évaluation(.+)Accords de reconnaissance applicables'),
- (HEADER_TYPE.HEADER_FULL, 'Référence du rapport de certification(.+)Nom du produit(.+)Référence/version du produit(.+)Conformité aux profils de protection(.+)Critères d\’évaluation et version(.+)Niveau d\’évaluation(.+)Développeurs(.+)Centre d\’évaluation(.+)Accords de reconnaissance applicables'),
- (HEADER_TYPE.HEADER_FULL, 'Référence du rapport de certification(.+)Nom du produit \(référence/version\)(.+)Nom de la TOE \(référence/version\)(.+)Conformité à un profil de protection(.+)Critères d\’évaluation et version(.+)Niveau d\’évaluation(.+)Développeurs(.+)Centre d’évaluation(.+)Accords de reconnaissance applicables'),
- (HEADER_TYPE.HEADER_FULL, 'Référence du rapport de certification(.+)Nom du produit(.+)Référence/version du produit(.+)Conformité aux profil de protection(.+)Critères d’évaluation et version(.+)Niveau d’évaluation(.+)Développeur\(s\)(.+)Centre d’évaluation(.+)Accords de reconnaissance applicables'),
- (HEADER_TYPE.HEADER_FULL, 'Référence du rapport de certification(.+)Nom du produit(.+)Référence/version du produit(.+)Conformité à un profil de protection(.+)Critères d\'évaluation et version(.+)Niveau d\'évaluation(.+)Développeur\(s\)(.+)Centre d\'évaluation(.+)Accords de reconnaissance applicables'),
- (HEADER_TYPE.HEADER_FULL, 'Référence du rapport de certification(.+)Nom du produit \(référence/version\)(.+)Nom de la TOE \(référence/version\)(.+)Conformité à un profil de protection(.+)Critères d\'évaluation et version(.+)Niveau d\'évaluation(.+)Développeurs(.+)Centre d\'évaluation(.+)Accords de reconnaissance applicables'),
- (HEADER_TYPE.HEADER_FULL, 'Référence du rapport de certification(.+)Nom du produit(.+)Référence du produit(.+)Conformité à un profil de protection(.+)Critères d\'évaluation et version(.+)Niveau d\'évaluation(.+)Développeurs(.+)Centre d\'évaluation(.+)Accords de reconnaissance applicables'),
- (HEADER_TYPE.HEADER_FULL, 'Référence du rapport de certification(.+)Nom du produit(.+)Référence/version du produit(.+)Conformité aux profils de protection(.+)Critères d\'évaluation et version(.+)Niveau d\'évaluation(.+)Développeurs(.+)Centre d\'évaluation(.+)Accords de reconnaissance applicables'),
+ (HEADER_TYPE.HEADER_FULL,
+ 'Référence du rapport de certification(.+)Nom du produit(.+)Référence/version du produit(.*)Conformité à un profil de protection(.+)Critères d\'évaluation et version(.+)Niveau d\'évaluation(.+)Développeurs(.+)Centre d\'évaluation(.+)Accords de reconnaissance applicables'),
+ (HEADER_TYPE.HEADER_FULL,
+ 'Référence du rapport de certification(.+)Nom du produit(.+)Référence/version du produit(.*)Conformité à un profil de protection(.+)Critères d’évaluation et version(.+)Niveau d’évaluation(.+)Développeurs(.+)Centre d’évaluation(.+)Accords de reconnaissance applicables'),
+ (HEADER_TYPE.HEADER_FULL,
+ 'Référence du rapport de certification(.+)Nom du produit(.+)()Conformité à un profil de protection(.+)Critères d\'évaluation et version(.+)Niveau d\'évaluation(.+)Développeur (.+)Centre d\'évaluation(.+)Accords de reconnaissance applicables'),
+ (HEADER_TYPE.HEADER_FULL,
+ 'Référence du rapport de certification(.+)Nom des produits(.+)Référence/version des produits(.+)Conformité à un profil de protection(.+)Critères d\'évaluation et version(.+)Niveau d\'évaluation(.+)Développeur\(s\)(.+)Centre d\'évaluation(.+)Accords de reconnaissance applicables'),
+ (HEADER_TYPE.HEADER_FULL,
+ 'Référence du rapport de certification(.+)Nom des produits(.+)Référence/version des produits(.+)Conformité à un profil de protection(.+)Critères d\'évaluation et version(.+)Niveau d\'évaluation(.+)Développeur (.+)Centre d\'évaluation(.+)Accords de reconnaissance'),
+ (HEADER_TYPE.HEADER_FULL,
+ 'Référence du rapport de certification(.+)Nom du produit(.+)Référence/version du produit(.+)Conformité aux profils de protection(.+)Critères d’évaluation et version(.+)Niveau d’évaluation(.+)Développeur\(s\)(.+)Centre d’évaluation(.+)Accords de reconnaissance applicables'),
+ (HEADER_TYPE.HEADER_FULL,
+ 'Référence du rapport de certification(.+)Nom du produit(.+)Référence/version du produit(.+)Conformité à un profil de protection(.+)Critères d’évaluation et version(.+)Niveau d’évaluation(.+)Développeur\(s\)(.+)Centre d’évaluation(.+)Accords de reconnaissance applicables'),
+ (HEADER_TYPE.HEADER_FULL,
+ 'Référence du rapport de certification(.+)Nom du produit(.+)Référence/version du produit(.+)Conformité à un profil de protection(.+)Critères d’évaluation et version(.+)Niveau d’évaluation(.+)Développeur (.+)Centre d’évaluation(.+)Accords de reconnaissance applicables'),
+ (HEADER_TYPE.HEADER_FULL,
+ 'Référence du rapport de certification(.+)Nom du produit(.+)Référence/version du produit(.+)Conformité à des profils de protection(.+)Critères d’évaluation et version(.+)Niveau d’évaluation(.+)Développeurs(.+)Centre d’évaluation(.+)Accords de reconnaissance applicables'),
+ (HEADER_TYPE.HEADER_FULL,
+ 'Référence du rapport de certification(.+)Nom du produit(.+)Référence/version du produit(.+)Conformité aux profils de protection(.+)Critères d\’évaluation et version(.+)Niveau d\’évaluation(.+)Développeurs(.+)Centre d\’évaluation(.+)Accords de reconnaissance applicables'),
+ (HEADER_TYPE.HEADER_FULL,
+ 'Référence du rapport de certification(.+)Nom du produit \(référence/version\)(.+)Nom de la TOE \(référence/version\)(.+)Conformité à un profil de protection(.+)Critères d\’évaluation et version(.+)Niveau d\’évaluation(.+)Développeurs(.+)Centre d’évaluation(.+)Accords de reconnaissance applicables'),
+ (HEADER_TYPE.HEADER_FULL,
+ 'Référence du rapport de certification(.+)Nom du produit(.+)Référence/version du produit(.+)Conformité aux profil de protection(.+)Critères d’évaluation et version(.+)Niveau d’évaluation(.+)Développeur\(s\)(.+)Centre d’évaluation(.+)Accords de reconnaissance applicables'),
+ (HEADER_TYPE.HEADER_FULL,
+ 'Référence du rapport de certification(.+)Nom du produit(.+)Référence/version du produit(.+)Conformité à un profil de protection(.+)Critères d\'évaluation et version(.+)Niveau d\'évaluation(.+)Développeur\(s\)(.+)Centre d\'évaluation(.+)Accords de reconnaissance applicables'),
+ (HEADER_TYPE.HEADER_FULL,
+ 'Référence du rapport de certification(.+)Nom du produit \(référence/version\)(.+)Nom de la TOE \(référence/version\)(.+)Conformité à un profil de protection(.+)Critères d\'évaluation et version(.+)Niveau d\'évaluation(.+)Développeurs(.+)Centre d\'évaluation(.+)Accords de reconnaissance applicables'),
+ (HEADER_TYPE.HEADER_FULL,
+ 'Référence du rapport de certification(.+)Nom du produit(.+)Référence du produit(.+)Conformité à un profil de protection(.+)Critères d\'évaluation et version(.+)Niveau d\'évaluation(.+)Développeurs(.+)Centre d\'évaluation(.+)Accords de reconnaissance applicables'),
+ (HEADER_TYPE.HEADER_FULL,
+ 'Référence du rapport de certification(.+)Nom du produit(.+)Référence/version du produit(.+)Conformité aux profils de protection(.+)Critères d\'évaluation et version(.+)Niveau d\'évaluation(.+)Développeurs(.+)Centre d\'évaluation(.+)Accords de reconnaissance applicables'),
- (HEADER_TYPE.HEADER_FULL, 'Référence du rapport de certification(.+)Nom du produit(.+)Référence/version du produit(.+)Conformité à un profil de protection(.+)Critères d’évaluation et version(.+)Niveau d’évaluation(.+)Développeurs(.+)Centre d’évaluation(.+)Accords de reconnaissance applicables'),
- (HEADER_TYPE.HEADER_FULL, 'Référence du rapport de certification(.+)Nom du produit(.+)Référence/version du produit(.+)Conformité à un profil de protection(.+)Critères d’évaluation et version(.+)Niveau d’évaluation(.+)Développeur\(s\)(.+)d’évaluation(.+)Accords de reconnaissance applicables'),
- (HEADER_TYPE.HEADER_FULL, 'Référence du rapport de certification(.+)Nom du produit(.+)Référence/version du produit(.+)Conformité à un profil de protection(.+)Critères d’évaluation et version(.+)Niveau d’évaluation(.+)Développeur (.+)Centre d’évaluation(.+)Accords de reconnaissance applicables'),
- (HEADER_TYPE.HEADER_FULL, 'Référence du rapport de certification(.+)Nom du produit(.+)Référence/version du produit(.+)Conformité à des profils de protection(.+)Critères d’évaluation et version(.+)Niveau d’évaluation(.+)Développeurs(.+)Centre d’évaluation(.+)Accords de reconnaissance applicables'),
- (HEADER_TYPE.HEADER_FULL, 'Référence du rapport de certification(.+)Nom du produit \(référence/version\)(.+)Nom de la TOE \(référence/version\)(.+)Conformité à un profil de protection(.+)Critères d’évaluation et version(.+)Niveau d’évaluation(.+)Développeurs(.+)Centre d’évaluation(.+)Accords de reconnaissance applicables'),
- (HEADER_TYPE.HEADER_FULL, 'Certification Report(.+)Nom du produit(.+)Référence/version du produit(.*)Conformité à un profil de protection(.+)Critères d\'évaluation et version(.+)Niveau d\'évaluation(.+)Développeurs(.+)Centre d\'évaluation(.+)Accords de reconnaissance applicables'),
- (HEADER_TYPE.HEADER_FULL, 'Référence du rapport de certification(.+)Nom du produit(.+)Référence/version du produit(.+)Conformité aux profisl de protection(.+)Critères d’évaluation et version(.+)Niveau d’évaluation(.+)Développeurs(.+)Centre d’évaluation(.+)Accords de reconnaissance applicables'),
- (HEADER_TYPE.HEADER_FULL, 'Référence du rapport de certification(.+)Nom du produit(.+)Référence/version du produit(.+)Conformité à un profil de protection(.+)Critères d’évaluation et version(.+)Niveau d’évaluation(.+)Développeur (.+)Centres d’évaluation(.+)Accords de reconnaissance applicables'),
- (HEADER_TYPE.HEADER_FULL, 'Référence du rapport de certification(.+)Nom du produit(.+)Version du produit(.+)Conformité à un profil de protection(.+)Critères d’évaluation et version(.+)Niveau d’évaluation(.+)Développeur (.+)Centre d’évaluation(.+)Accords de reconnaissance applicables'),
- (HEADER_TYPE.HEADER_FULL, 'Référence du rapport de certification(.+)Nom du produit(.+)Référence/version du produit(.+)Conformité aux profils de protection(.+)Critères d’évaluation et version(.+)Niveau d’évaluation(.+)Développeur\(s\)(.+)Centre d’évaluation(.+)Accords de reconnaissance applicables'),
- (HEADER_TYPE.HEADER_FULL, 'Référence du rapport de certification(.+)Nom du produit(.+)Versions du produit(.+)Conformité à un profil de protection(.+)Critères d’évaluation et version(.+)Niveau d’évaluation(.+)Développeur (.+)Centre d’évaluation(.+)Accords de reconnaissance applicables'),
- (HEADER_TYPE.HEADER_FULL, 'Référence du rapport de certification(.+)Nom du produit(.+)Référence du produit(.+)Conformité à un profil de protection(.+)Critères d’évaluation et version(.+)Niveau d’évaluation(.+)Développeurs(.+)Centre d’évaluation(.+)Accords de reconnaissance applicables'),
- (HEADER_TYPE.HEADER_FULL, 'Certification report reference(.+)Product name(.+)Product reference(.+)Protection profile conformity(.+)Evaluation criteria and version(.+)Evaluation level(.+)Developer (.+)Evaluation facility(.+)Recognition arrangements'),
- (HEADER_TYPE.HEADER_FULL, 'Certification report reference(.+)Product name(.+)Product reference(.+)Protection profile conformity(.+)Evaluation criteria and version(.+)Evaluation level(.+)Developer (.+)Evaluation facility(.+)Mutual Recognition Agreements'),
- (HEADER_TYPE.HEADER_FULL, 'Certification report reference(.+)Product name(.+)Product reference(.+)Protection profile conformity(.+)Evaluation criteria and version(.+)Evaluation level(.+)Developers(.+)Evaluation facility(.+)Recognition arrangements'),
- (HEADER_TYPE.HEADER_FULL, 'Certification report reference(.+)Product name(.+)Product reference(.+)Protection profile conformity(.+)Evaluation criteria and version(.+)Evaluation level(.+)Developer\(s\)(.+)Evaluation facility(.+)Recognition arrangements'),
- (HEADER_TYPE.HEADER_FULL, 'Certification report reference(.+)Products names(.+)Products references(.+)protection profile conformity(.+)Evaluation criteria and version(.+)Evaluation level(.+)Developers(.+)Evaluation facility(.+)Recognition arrangements'),
- (HEADER_TYPE.HEADER_FULL, 'Certification report reference(.+)Product name \(reference / version\)(.+)TOE name \(reference / version\)(.+)Protection profile conformity(.+)Evaluation criteria and version(.+)Evaluation level(.+)Developers(.+)Evaluation facility(.+)Recognition arrangements'),
- (HEADER_TYPE.HEADER_FULL, 'Certification report reference(.+)TOE name(.+)Product\'s reference/ version(.+)TOE\'s reference/ version(.+)Conformité à un profil de protection(.+)Evaluation criteria and version(.+)Evaluation level(.+)Developer (.+)Evaluation facility(.+)Recognition arrangements'),
+ (HEADER_TYPE.HEADER_FULL,
+ 'Référence du rapport de certification(.+)Nom du produit(.+)Référence/version du produit(.+)Conformité à un profil de protection(.+)Critères d’évaluation et version(.+)Niveau d’évaluation(.+)Développeurs(.+)Centre d’évaluation(.+)Accords de reconnaissance applicables'),
+ (HEADER_TYPE.HEADER_FULL,
+ 'Référence du rapport de certification(.+)Nom du produit(.+)Référence/version du produit(.+)Conformité à un profil de protection(.+)Critères d’évaluation et version(.+)Niveau d’évaluation(.+)Développeur\(s\)(.+)d’évaluation(.+)Accords de reconnaissance applicables'),
+ (HEADER_TYPE.HEADER_FULL,
+ 'Référence du rapport de certification(.+)Nom du produit(.+)Référence/version du produit(.+)Conformité à un profil de protection(.+)Critères d’évaluation et version(.+)Niveau d’évaluation(.+)Développeur (.+)Centre d’évaluation(.+)Accords de reconnaissance applicables'),
+ (HEADER_TYPE.HEADER_FULL,
+ 'Référence du rapport de certification(.+)Nom du produit(.+)Référence/version du produit(.+)Conformité à des profils de protection(.+)Critères d’évaluation et version(.+)Niveau d’évaluation(.+)Développeurs(.+)Centre d’évaluation(.+)Accords de reconnaissance applicables'),
+ (HEADER_TYPE.HEADER_FULL,
+ 'Référence du rapport de certification(.+)Nom du produit \(référence/version\)(.+)Nom de la TOE \(référence/version\)(.+)Conformité à un profil de protection(.+)Critères d’évaluation et version(.+)Niveau d’évaluation(.+)Développeurs(.+)Centre d’évaluation(.+)Accords de reconnaissance applicables'),
+ (HEADER_TYPE.HEADER_FULL,
+ 'Certification Report(.+)Nom du produit(.+)Référence/version du produit(.*)Conformité à un profil de protection(.+)Critères d\'évaluation et version(.+)Niveau d\'évaluation(.+)Développeurs(.+)Centre d\'évaluation(.+)Accords de reconnaissance applicables'),
+ (HEADER_TYPE.HEADER_FULL,
+ 'Référence du rapport de certification(.+)Nom du produit(.+)Référence/version du produit(.+)Conformité aux profisl de protection(.+)Critères d’évaluation et version(.+)Niveau d’évaluation(.+)Développeurs(.+)Centre d’évaluation(.+)Accords de reconnaissance applicables'),
+ (HEADER_TYPE.HEADER_FULL,
+ 'Référence du rapport de certification(.+)Nom du produit(.+)Référence/version du produit(.+)Conformité à un profil de protection(.+)Critères d’évaluation et version(.+)Niveau d’évaluation(.+)Développeur (.+)Centres d’évaluation(.+)Accords de reconnaissance applicables'),
+ (HEADER_TYPE.HEADER_FULL,
+ 'Référence du rapport de certification(.+)Nom du produit(.+)Version du produit(.+)Conformité à un profil de protection(.+)Critères d’évaluation et version(.+)Niveau d’évaluation(.+)Développeur (.+)Centre d’évaluation(.+)Accords de reconnaissance applicables'),
+ (HEADER_TYPE.HEADER_FULL,
+ 'Référence du rapport de certification(.+)Nom du produit(.+)Référence/version du produit(.+)Conformité aux profils de protection(.+)Critères d’évaluation et version(.+)Niveau d’évaluation(.+)Développeur\(s\)(.+)Centre d’évaluation(.+)Accords de reconnaissance applicables'),
+ (HEADER_TYPE.HEADER_FULL,
+ 'Référence du rapport de certification(.+)Nom du produit(.+)Versions du produit(.+)Conformité à un profil de protection(.+)Critères d’évaluation et version(.+)Niveau d’évaluation(.+)Développeur (.+)Centre d’évaluation(.+)Accords de reconnaissance applicables'),
+ (HEADER_TYPE.HEADER_FULL,
+ 'Référence du rapport de certification(.+)Nom du produit(.+)Référence du produit(.+)Conformité à un profil de protection(.+)Critères d’évaluation et version(.+)Niveau d’évaluation(.+)Développeurs(.+)Centre d’évaluation(.+)Accords de reconnaissance applicables'),
+ (HEADER_TYPE.HEADER_FULL,
+ 'Certification report reference(.+)Product name(.+)Product reference(.+)Protection profile conformity(.+)Evaluation criteria and version(.+)Evaluation level(.+)Developer (.+)Evaluation facility(.+)Recognition arrangements'),
+ (HEADER_TYPE.HEADER_FULL,
+ 'Certification report reference(.+)Product name(.+)Product reference(.+)Protection profile conformity(.+)Evaluation criteria and version(.+)Evaluation level(.+)Developer (.+)Evaluation facility(.+)Mutual Recognition Agreements'),
+ (HEADER_TYPE.HEADER_FULL,
+ 'Certification report reference(.+)Product name(.+)Product reference(.+)Protection profile conformity(.+)Evaluation criteria and version(.+)Evaluation level(.+)Developers(.+)Evaluation facility(.+)Recognition arrangements'),
+ (HEADER_TYPE.HEADER_FULL,
+ 'Certification report reference(.+)Product name(.+)Product reference(.+)Protection profile conformity(.+)Evaluation criteria and version(.+)Evaluation level(.+)Developer\(s\)(.+)Evaluation facility(.+)Recognition arrangements'),
+ (HEADER_TYPE.HEADER_FULL,
+ 'Certification report reference(.+)Products names(.+)Products references(.+)protection profile conformity(.+)Evaluation criteria and version(.+)Evaluation level(.+)Developers(.+)Evaluation facility(.+)Recognition arrangements'),
+ (HEADER_TYPE.HEADER_FULL,
+ 'Certification report reference(.+)Product name \(reference / version\)(.+)TOE name \(reference / version\)(.+)Protection profile conformity(.+)Evaluation criteria and version(.+)Evaluation level(.+)Developers(.+)Evaluation facility(.+)Recognition arrangements'),
+ (HEADER_TYPE.HEADER_FULL,
+ 'Certification report reference(.+)TOE name(.+)Product\'s reference/ version(.+)TOE\'s reference/ version(.+)Conformité à un profil de protection(.+)Evaluation criteria and version(.+)Evaluation level(.+)Developer (.+)Evaluation facility(.+)Recognition arrangements'),
# corrupted text (duplicities)
- (HEADER_TYPE.HEADER_DUPLICITIES, 'Référencce du rapport de d certification n(.+)Nom du p produit(.+)Référencce/version du produit(.+)Conformiité à un profil de d protection(.+)Critères d d’évaluation ett version(.+)Niveau d’’évaluation(.+)Développ peurs(.+)Centre d’’évaluation(.+)Accords d de reconnaisssance applicab bles'),
+ (HEADER_TYPE.HEADER_DUPLICITIES,
+ 'Référencce du rapport de d certification n(.+)Nom du p produit(.+)Référencce/version du produit(.+)Conformiité à un profil de d protection(.+)Critères d d’évaluation ett version(.+)Niveau d’’évaluation(.+)Développ peurs(.+)Centre d’’évaluation(.+)Accords d de reconnaisssance applicab bles'),
# rules without product version
- (HEADER_TYPE.HEADER_MISSING_CERT_ITEM_VERSION, 'Référence du rapport de certification(.+)Nom et version du produit(.+)Conformité à un profil de protection(.+)Critères d\'évaluation et version(.+)Niveau d\'évaluation(.+)Développeurs(.+)Centre d\'évaluation(.+)Accords de reconnaissance applicables'),
- (HEADER_TYPE.HEADER_MISSING_CERT_ITEM_VERSION, 'Référence du rapport de certification(.+)Nom et version du produit(.+)Conformité à un profil de protection(.+)Critères d\'évaluation et version(.+)Niveau d\'évaluation(.+)Développeur (.+)Centre d\'évaluation(.+)Accords de reconnaissance applicables'),
- (HEADER_TYPE.HEADER_MISSING_CERT_ITEM_VERSION, 'Référence du rapport de certification(.+)Nom du produit(.+)Conformité à un profil de protection(.+)Critères d\'évaluation et version(.+)Niveau d\'évaluation(.+)Développeurs(.+)Centre d\'évaluation(.+)Accords de reconnaissance applicables'),
+ (HEADER_TYPE.HEADER_MISSING_CERT_ITEM_VERSION,
+ 'Référence du rapport de certification(.+)Nom et version du produit(.+)Conformité à un profil de protection(.+)Critères d\'évaluation et version(.+)Niveau d\'évaluation(.+)Développeurs(.+)Centre d\'évaluation(.+)Accords de reconnaissance applicables'),
+ (HEADER_TYPE.HEADER_MISSING_CERT_ITEM_VERSION,
+ 'Référence du rapport de certification(.+)Nom et version du produit(.+)Conformité à un profil de protection(.+)Critères d\'évaluation et version(.+)Niveau d\'évaluation(.+)Développeur (.+)Centre d\'évaluation(.+)Accords de reconnaissance applicables'),
+ (HEADER_TYPE.HEADER_MISSING_CERT_ITEM_VERSION,
+ 'Référence du rapport de certification(.+)Nom du produit(.+)Conformité à un profil de protection(.+)Critères d\'évaluation et version(.+)Niveau d\'évaluation(.+)Développeurs(.+)Centre d\'évaluation(.+)Accords de reconnaissance applicables'),
# rules without protection profile
- (HEADER_TYPE.HEADER_MISSING_PROTECTION_PROFILES, 'Référence du rapport de certification(.+)Nom du produit(.+)Référence/version du produit(.+)Critères d\'évaluation et version(.+)Niveau d\'évaluation(.+)Développeurs(.+)Centre d\'évaluation(.+)Accords de reconnaissance applicables'),
+ (HEADER_TYPE.HEADER_MISSING_PROTECTION_PROFILES,
+ 'Référence du rapport de certification(.+)Nom du produit(.+)Référence/version du produit(.+)Critères d\'évaluation et version(.+)Niveau d\'évaluation(.+)Développeurs(.+)Centre d\'évaluation(.+)Accords de reconnaissance applicables'),
]
-# rules_certificate_preface = [
-# (HEADER_TYPE.HEADER_FULL, 'ddddd'),
-# ]
+ # rules_certificate_preface = [
+ # (HEADER_TYPE.HEADER_FULL, 'ddddd'),
+ # ]
# statistics about rules success rate
num_rules_hits = {}
for rule in rules_certificate_preface:
num_rules_hits[rule[1]] = 0
+ print('***ANSSI HEADER SEARCH***')
items_found_all = {}
files_without_match = []
for file_name in search_files(walk_dir):
@@ -509,9 +597,10 @@ def search_only_headers_anssi(walk_dir):
file_ext = file_name[file_name.rfind('.'):]
if file_ext != '.txt':
continue
- print('*** {} ***'.format(file_name))
+ # print('*** {} ***'.format(file_name))
- whole_text, whole_text_with_newlines, was_unicode_decode_error = load_cert_file(file_name)
+ whole_text, whole_text_with_newlines, was_unicode_decode_error = load_cert_file(
+ file_name)
# for ANSII and DCSSI certificates, front page starts only on third page after 2 newpage signs
pos = whole_text.find(' ')
@@ -544,7 +633,8 @@ def search_only_headers_anssi(walk_dir):
other_rule_already_match = True
other_rule = rule
else:
- print('WARNING: multiple rules are matching same certification document: ' + file_name)
+ print(
+ 'WARNING: multiple rules are matching same certification document: ' + file_name)
num_rules_hits[rule[1]] += 1 # add hit to this rule
@@ -552,34 +642,42 @@ def search_only_headers_anssi(walk_dir):
index_next_item = 0
- items_found[TAG_CERT_ID] = normalize_match_string(match_groups[index_next_item])
+ items_found[TAG_CERT_ID] = normalize_match_string(
+ match_groups[index_next_item])
index_next_item += 1
- items_found[TAG_CERT_ITEM] = normalize_match_string(match_groups[index_next_item])
+ items_found[TAG_CERT_ITEM] = normalize_match_string(
+ match_groups[index_next_item])
index_next_item += 1
if rule[0] == HEADER_TYPE.HEADER_MISSING_CERT_ITEM_VERSION:
items_found[TAG_CERT_ITEM_VERSION] = ''
else:
- items_found[TAG_CERT_ITEM_VERSION] = normalize_match_string(match_groups[index_next_item])
+ items_found[TAG_CERT_ITEM_VERSION] = normalize_match_string(
+ match_groups[index_next_item])
index_next_item += 1
if rule[0] == HEADER_TYPE.HEADER_MISSING_PROTECTION_PROFILES:
items_found[TAG_REFERENCED_PROTECTION_PROFILES] = ''
else:
- items_found[TAG_REFERENCED_PROTECTION_PROFILES] = normalize_match_string(match_groups[index_next_item])
+ items_found[TAG_REFERENCED_PROTECTION_PROFILES] = normalize_match_string(
+ match_groups[index_next_item])
index_next_item += 1
- items_found[TAG_CC_VERSION] = normalize_match_string(match_groups[index_next_item])
+ items_found[TAG_CC_VERSION] = normalize_match_string(
+ match_groups[index_next_item])
index_next_item += 1
- items_found[TAG_CC_SECURITY_LEVEL] = normalize_match_string(match_groups[index_next_item])
+ items_found[TAG_CC_SECURITY_LEVEL] = normalize_match_string(
+ match_groups[index_next_item])
index_next_item += 1
- items_found[TAG_DEVELOPER] = normalize_match_string(match_groups[index_next_item])
+ items_found[TAG_DEVELOPER] = normalize_match_string(
+ match_groups[index_next_item])
index_next_item += 1
- items_found[TAG_CERT_LAB] = normalize_match_string(match_groups[index_next_item])
+ items_found[TAG_CERT_LAB] = normalize_match_string(
+ match_groups[index_next_item])
index_next_item += 1
if no_match_yet:
@@ -600,7 +698,8 @@ def search_only_headers_anssi(walk_dir):
if True:
print('# hits for rule')
- sorted_rules = sorted(num_rules_hits.items(), key=operator.itemgetter(1), reverse=True)
+ sorted_rules = sorted(num_rules_hits.items(),
+ key=operator.itemgetter(1), reverse=True)
used_rules = []
for rule in sorted_rules:
print('{:4d} : {}'.format(rule[1], rule[0]))
@@ -610,12 +709,15 @@ def search_only_headers_anssi(walk_dir):
return items_found_all, files_without_match
-def extract_certificates_frontpage(walk_dir, write_output_file = True):
- anssi_items_found, anssi_files_without_match = search_only_headers_anssi(walk_dir)
- bsi_items_found, bsi_files_without_match = search_only_headers_bsi(walk_dir)
+def extract_certificates_frontpage(walk_dir, write_output_file=True):
+ anssi_items_found, anssi_files_without_match = search_only_headers_anssi(
+ walk_dir)
+ bsi_items_found, bsi_files_without_match = search_only_headers_bsi(
+ walk_dir)
print('*** Files without detected header')
- files_without_match = list(set(anssi_files_without_match) & set(bsi_files_without_match))
+ files_without_match = list(
+ set(anssi_files_without_match) & set(bsi_files_without_match))
for file_name in files_without_match:
print(file_name)
print('Total no hits files: {}'.format(len(files_without_match)))
@@ -625,7 +727,8 @@ def extract_certificates_frontpage(walk_dir, write_output_file = True):
if write_output_file:
with open("certificate_data_frontpage_all.json", "w", errors=FILE_ERRORS_STRATEGY) as write_file:
- write_file.write(json.dumps(items_found_all, indent=4, sort_keys=True))
+ write_file.write(json.dumps(
+ items_found_all, indent=4, sort_keys=True))
return items_found_all
@@ -654,7 +757,6 @@ def search_pp_only_headers(walk_dir):
ANSSI_TYPE2 = 42
ANSSI_TYPE3 = 43
-
rules_pp_third = [
(HEADER_TYPE.BSI_TYPE1,
'PP Reference .+?Title (.+)?CC Version (.+)?Assurance Level (.+)?General Status (.+)?Version Number (.+)?Registration (.+)?Keywords (.+)?TOE Overview'),
@@ -672,18 +774,19 @@ def search_pp_only_headers(walk_dir):
'Protection profile reference[ ]*Title: (.+)?Author: (.+)?Version: (.+)?Context'),
(HEADER_TYPE.FRONT_DCSSI_TYPE3,
'Direction centrale de la sécurité des systèmes d\’information(.+)?(?:Creation date|Date)[ ]*[:]*(.+)?Reference[ ]*[:]*(.+)?Version[ ]*[:]*(.+)?Courtesy Translation[ ]*Courtesy translation.+?under the reference (DCSSI-PP-[0-9/]+)?\.[ ]*Page'),
-# (HEADER_TYPE.FRONT_DCSSI_TYPE4,
-# 'Direction centrale de la sécurité des systèmes d\’information(.+)?Date[ ]*:(.+)?Reference[ ]*:(.+)?Version[ ]*:(.+)?Courtesy Translation[ ]*Courtesy translation.+?under the reference (DCSSI-PP-[0-9/]+)?\.[ ]*Page'),
+ # (HEADER_TYPE.FRONT_DCSSI_TYPE4,
+ # 'Direction centrale de la sécurité des systèmes d\’information(.+)?Date[ ]*:(.+)?Reference[ ]*:(.+)?Version[ ]*:(.+)?Courtesy Translation[ ]*Courtesy translation.+?under the reference (DCSSI-PP-[0-9/]+)?\.[ ]*Page'),
(HEADER_TYPE.FRONT_DCSSI_TYPE4,
'Direction centrale de la sécurité des systèmes d’information (.+)?(?:Creation date|Date)[ ]*:(.+)?Reference[ ]*:(.+)?Version[ ]*:(.+)?Courtesy Translation[ ]*Courtesy translation.+?under the reference (DCSSI-PP-[0-9/]+)?\.[ ]*Page'),
- #'Direction centrale de la sécurité des systèmes d’information Time-stamping System Protection Profile Date : July 18, 2008 Reference : PP-SH-CCv3.1 Version : 1.7 Courtesy Translation Courtesy translation of the protection profile registered and certified by the French Certification Body under the reference DCSSI-PP-2008/07. Page'
+ # 'Direction centrale de la sécurité des systèmes d’information Time-stamping System Protection Profile Date : July 18, 2008 Reference : PP-SH-CCv3.1 Version : 1.7 Courtesy Translation Courtesy translation of the protection profile registered and certified by the French Certification Body under the reference DCSSI-PP-2008/07. Page'
(HEADER_TYPE.DCSSI_TYPE5,
'Protection Profile identification[ ]*Title[ ]*[:]*(.+)?Author[ ]*[:]*(.+)?Version[ ]*[:]*(.+)?,(.+)?Sponsor[ ]*[:]*(.+)?CC version[ ]*[:]*(.+)?(?:Context|Protection Profile introduction)'),
(HEADER_TYPE.DCSSI_TYPE6,
'PP reference.+?Title[ ]*:(.+)?Author[ ]*:(.+)?Version[ ]*:(.+)?Date[ ]*:(.+)?Sponsor[ ]*:(.+)?CC version[ ]*:(.+)?This protection profile.+?The evaluation assurance level required by this protection profile is (.+)?specified by the DCSSI qualification process'),
-# (HEADER_TYPE.DCSSI_TYPE7,
-# 'Protection Profile identification.+?Title[ ]*[:]*(.+)?Author[ ]*[:]*(.+)?Version[ ]*[:]*(.+)?,(.+)?Sponsor[ ]*[:]*(.+)?CC version[ ]*[:]*(.+)?Protection Profile introduction')
+ # (HEADER_TYPE.DCSSI_TYPE7,
+ # 'Protection Profile identification.+?Title[ ]*[:]*(.+)?Author[ ]*[:]*(.+)?Version[ ]*[:]*(.+)?,(.+)?Sponsor[ ]*[:]*(.+)?CC version[ ]*[:]*(.+)?Protection Profile introduction')
]
+ print("***PP HEADER SEARCH***")
items_found_all = {}
files_without_match = []
for file_name in search_files(walk_dir):
@@ -692,13 +795,14 @@ def search_pp_only_headers(walk_dir):
file_ext = file_name[file_name.rfind('.'):]
if file_ext != '.txt':
continue
- print('*** {} ***'.format(file_name))
+ # print('*** {} ***'.format(file_name))
#
# Process page with more detailed protection profile info
# PP Reference
- whole_text, whole_text_with_newlines, was_unicode_decode_error = load_cert_file(file_name)
+ whole_text, whole_text_with_newlines, was_unicode_decode_error = load_cert_file(
+ file_name)
no_match_yet = True
for rule in rules_pp_third:
@@ -720,180 +824,253 @@ def search_pp_only_headers(walk_dir):
index = 0
if rule[0] == HEADER_TYPE.BSI_TYPE1:
- set_match_string(items_found, TAG_PP_TITLE, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_PP_TITLE,
+ normalize_match_string(match_groups[index]))
index += 1
- set_match_string(items_found, TAG_CC_VERSION, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_CC_VERSION,
+ normalize_match_string(match_groups[index]))
index += 1
- set_match_string(items_found, TAG_CC_SECURITY_LEVEL, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_CC_SECURITY_LEVEL,
+ normalize_match_string(match_groups[index]))
index += 1
- set_match_string(items_found, TAG_PP_GENERAL_STATUS, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_PP_GENERAL_STATUS,
+ normalize_match_string(match_groups[index]))
index += 1
- set_match_string(items_found, TAG_PP_VERSION_NUMBER, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_PP_VERSION_NUMBER,
+ normalize_match_string(match_groups[index]))
index += 1
- set_match_string(items_found, TAG_PP_ID, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_PP_ID,
+ normalize_match_string(match_groups[index]))
index += 1
keywords = match_groups[index].lstrip(' ')
- set_match_string(items_found, TAG_KEYWORDS, normalize_match_string(keywords[0:keywords.find(' ')]))
+ set_match_string(items_found, TAG_KEYWORDS, normalize_match_string(
+ keywords[0:keywords.find(' ')]))
index += 1
set_match_string(items_found, TAG_PP_AUTHORS, 'BSI')
- set_match_string(items_found, TAG_PP_REGISTRATOR_SIMPLIFIED, 'BSI')
+ set_match_string(
+ items_found, TAG_PP_REGISTRATOR_SIMPLIFIED, 'BSI')
if rule[0] == HEADER_TYPE.BSI_TYPE2:
- set_match_string(items_found, TAG_PP_TITLE, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_PP_TITLE,
+ normalize_match_string(match_groups[index]))
index += 1
- set_match_string(items_found, TAG_PP_VERSION_NUMBER, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_PP_VERSION_NUMBER,
+ normalize_match_string(match_groups[index]))
index += 1
- set_match_string(items_found, TAG_PP_DATE, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_PP_DATE,
+ normalize_match_string(match_groups[index]))
index += 1
- set_match_string(items_found, TAG_PP_AUTHORS, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_PP_AUTHORS,
+ normalize_match_string(match_groups[index]))
index += 1
- set_match_string(items_found, TAG_PP_REGISTRATOR, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_PP_REGISTRATOR,
+ normalize_match_string(match_groups[index]))
index += 1
- set_match_string(items_found, TAG_PP_ID, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_PP_ID,
+ normalize_match_string(match_groups[index]))
index += 1
- set_match_string(items_found, TAG_CC_SECURITY_LEVEL, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_CC_SECURITY_LEVEL,
+ normalize_match_string(match_groups[index]))
index += 1
- set_match_string(items_found, TAG_CC_VERSION, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_CC_VERSION,
+ normalize_match_string(match_groups[index]))
index += 1
keywords = match_groups[index].lstrip(' ')
- set_match_string(items_found, TAG_KEYWORDS, normalize_match_string(keywords[0:keywords.find(' ')]))
+ set_match_string(items_found, TAG_KEYWORDS, normalize_match_string(
+ keywords[0:keywords.find(' ')]))
index += 1
- set_match_string(items_found, TAG_PP_REGISTRATOR_SIMPLIFIED, 'BSI')
+ set_match_string(
+ items_found, TAG_PP_REGISTRATOR_SIMPLIFIED, 'BSI')
if rule[0] == HEADER_TYPE.ANSSI_TYPE1:
- set_match_string(items_found, TAG_PP_TITLE, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_PP_TITLE,
+ normalize_match_string(match_groups[index]))
index += 1
- set_match_string(items_found, TAG_PP_VERSION_NUMBER, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_PP_VERSION_NUMBER,
+ normalize_match_string(match_groups[index]))
index += 1
- set_match_string(items_found, TAG_PP_DATE, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_PP_DATE,
+ normalize_match_string(match_groups[index]))
index += 1
- set_match_string(items_found, TAG_PP_REGISTRATOR, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_PP_REGISTRATOR,
+ normalize_match_string(match_groups[index]))
index += 1
- set_match_string(items_found, TAG_PP_SPONSOR, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_PP_SPONSOR,
+ normalize_match_string(match_groups[index]))
index += 1
- set_match_string(items_found, TAG_PP_EDITOR, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_PP_EDITOR,
+ normalize_match_string(match_groups[index]))
index += 1
- set_match_string(items_found, TAG_PP_REVIEWER, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_PP_REVIEWER,
+ normalize_match_string(match_groups[index]))
index += 1
- set_match_string(items_found, TAG_CC_VERSION, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_CC_VERSION,
+ normalize_match_string(match_groups[index]))
index += 1
level = match_groups[index].lstrip(' ')
- set_match_string(items_found, TAG_CC_SECURITY_LEVEL, normalize_match_string(level[0:level.find(' ')]))
+ set_match_string(items_found, TAG_CC_SECURITY_LEVEL, normalize_match_string(
+ level[0:level.find(' ')]))
index += 1
- set_match_string(items_found, TAG_PP_REGISTRATOR_SIMPLIFIED, 'ANSSI')
+ set_match_string(
+ items_found, TAG_PP_REGISTRATOR_SIMPLIFIED, 'ANSSI')
if rule[0] == HEADER_TYPE.ANSSI_TYPE2:
- set_match_string(items_found, TAG_PP_TITLE, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_PP_TITLE,
+ normalize_match_string(match_groups[index]))
index += 1
- set_match_string(items_found, TAG_PP_VERSION_NUMBER, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_PP_VERSION_NUMBER,
+ normalize_match_string(match_groups[index]))
index += 1
- set_match_string(items_found, TAG_PP_AUTHORS, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_PP_AUTHORS,
+ normalize_match_string(match_groups[index]))
index += 1
- set_match_string(items_found, TAG_CC_SECURITY_LEVEL, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_CC_SECURITY_LEVEL,
+ normalize_match_string(match_groups[index]))
index += 1
- set_match_string(items_found, TAG_PP_REGISTRATOR, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_PP_REGISTRATOR,
+ normalize_match_string(match_groups[index]))
index += 1
- set_match_string(items_found, TAG_CC_VERSION, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_CC_VERSION,
+ normalize_match_string(match_groups[index]))
index += 1
- set_match_string(items_found, TAG_KEYWORDS, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_KEYWORDS,
+ normalize_match_string(match_groups[index]))
index += 1
- set_match_string(items_found, TAG_PP_REGISTRATOR_SIMPLIFIED, 'ANSSI')
+ set_match_string(
+ items_found, TAG_PP_REGISTRATOR_SIMPLIFIED, 'ANSSI')
if rule[0] == HEADER_TYPE.ANSSI_TYPE3:
- set_match_string(items_found, TAG_PP_TITLE, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_PP_TITLE,
+ normalize_match_string(match_groups[index]))
index += 1
# todo: parse if multiple pp ids are present
- set_match_string(items_found, TAG_PP_ID, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_PP_ID,
+ normalize_match_string(match_groups[index]))
index += 1
- set_match_string(items_found, TAG_PP_EDITOR, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_PP_EDITOR,
+ normalize_match_string(match_groups[index]))
index += 1
- set_match_string(items_found, TAG_PP_DATE, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_PP_DATE,
+ normalize_match_string(match_groups[index]))
index += 1
- set_match_string(items_found, TAG_PP_VERSION_NUMBER, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_PP_VERSION_NUMBER,
+ normalize_match_string(match_groups[index]))
index += 1
- set_match_string(items_found, TAG_PP_SPONSOR, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_PP_SPONSOR,
+ normalize_match_string(match_groups[index]))
index += 1
ccversion = match_groups[index].lstrip(' ')
- set_match_string(items_found, TAG_CC_VERSION, normalize_match_string(ccversion[0:ccversion.find(' ')]))
+ set_match_string(items_found, TAG_CC_VERSION, normalize_match_string(
+ ccversion[0:ccversion.find(' ')]))
index += 1
- set_match_string(items_found, TAG_PP_REGISTRATOR_SIMPLIFIED, 'ANSSI')
+ set_match_string(
+ items_found, TAG_PP_REGISTRATOR_SIMPLIFIED, 'ANSSI')
if rule[0] == HEADER_TYPE.DCSSI_TYPE1:
- set_match_string(items_found, TAG_PP_TITLE, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_PP_TITLE,
+ normalize_match_string(match_groups[index]))
index += 1
- set_match_string(items_found, TAG_PP_ID, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_PP_ID,
+ normalize_match_string(match_groups[index]))
index += 1
- set_match_string(items_found, TAG_PP_VERSION_NUMBER, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_PP_VERSION_NUMBER,
+ normalize_match_string(match_groups[index]))
index += 1
- set_match_string(items_found, TAG_PP_DATE, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_PP_DATE,
+ normalize_match_string(match_groups[index]))
index += 1
author = match_groups[index].lstrip(' ')
- set_match_string(items_found, TAG_PP_AUTHORS, normalize_match_string(author[0:author.find(' ')]))
+ set_match_string(items_found, TAG_PP_AUTHORS, normalize_match_string(
+ author[0:author.find(' ')]))
index += 1
- set_match_string(items_found, TAG_PP_REGISTRATOR_SIMPLIFIED, 'DCSSI')
+ set_match_string(
+ items_found, TAG_PP_REGISTRATOR_SIMPLIFIED, 'DCSSI')
if rule[0] == HEADER_TYPE.DCSSI_TYPE2:
- set_match_string(items_found, TAG_PP_TITLE, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_PP_TITLE,
+ normalize_match_string(match_groups[index]))
index += 1
- set_match_string(items_found, TAG_PP_AUTHORS, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_PP_AUTHORS,
+ normalize_match_string(match_groups[index]))
index += 1
version = match_groups[index].lstrip(' ')
- set_match_string(items_found, TAG_PP_VERSION_NUMBER, normalize_match_string(version[0:version.find(' ')]))
+ set_match_string(items_found, TAG_PP_VERSION_NUMBER, normalize_match_string(
+ version[0:version.find(' ')]))
index += 1
- set_match_string(items_found, TAG_PP_REGISTRATOR_SIMPLIFIED, 'DCSSI')
+ set_match_string(
+ items_found, TAG_PP_REGISTRATOR_SIMPLIFIED, 'DCSSI')
if rule[0] == HEADER_TYPE.FRONT_DCSSI_TYPE3 or rule[0] == HEADER_TYPE.FRONT_DCSSI_TYPE4:
- set_match_string(items_found, TAG_PP_TITLE, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_PP_TITLE,
+ normalize_match_string(match_groups[index]))
index += 1
- set_match_string(items_found, TAG_PP_DATE, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_PP_DATE,
+ normalize_match_string(match_groups[index]))
index += 1
- set_match_string(items_found, TAG_PP_ID, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_PP_ID,
+ normalize_match_string(match_groups[index]))
index += 1
- set_match_string(items_found, TAG_PP_VERSION_NUMBER, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_PP_VERSION_NUMBER,
+ normalize_match_string(match_groups[index]))
index += 1
- set_match_string(items_found, TAG_PP_ID_REGISTRATOR, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_PP_ID_REGISTRATOR,
+ normalize_match_string(match_groups[index]))
index += 1
- set_match_string(items_found, TAG_PP_REGISTRATOR_SIMPLIFIED, 'DCSSI')
+ set_match_string(
+ items_found, TAG_PP_REGISTRATOR_SIMPLIFIED, 'DCSSI')
if rule[0] == HEADER_TYPE.DCSSI_TYPE5:
- set_match_string(items_found, TAG_PP_TITLE, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_PP_TITLE,
+ normalize_match_string(match_groups[index]))
index += 1
- set_match_string(items_found, TAG_PP_AUTHORS, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_PP_AUTHORS,
+ normalize_match_string(match_groups[index]))
index += 1
- set_match_string(items_found, TAG_PP_VERSION_NUMBER, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_PP_VERSION_NUMBER,
+ normalize_match_string(match_groups[index]))
index += 1
- set_match_string(items_found, TAG_PP_DATE, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_PP_DATE,
+ normalize_match_string(match_groups[index]))
index += 1
- set_match_string(items_found, TAG_PP_SPONSOR, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_PP_SPONSOR,
+ normalize_match_string(match_groups[index]))
index += 1
ccversion = match_groups[index].lstrip(' ')
- set_match_string(items_found, TAG_CC_VERSION, normalize_match_string(ccversion[0:ccversion.find(' ')]))
+ set_match_string(items_found, TAG_CC_VERSION, normalize_match_string(
+ ccversion[0:ccversion.find(' ')]))
index += 1
if rule[0] == HEADER_TYPE.DCSSI_TYPE6:
- set_match_string(items_found, TAG_PP_TITLE, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_PP_TITLE,
+ normalize_match_string(match_groups[index]))
index += 1
- set_match_string(items_found, TAG_PP_AUTHORS, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_PP_AUTHORS,
+ normalize_match_string(match_groups[index]))
index += 1
- set_match_string(items_found, TAG_PP_VERSION_NUMBER, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_PP_VERSION_NUMBER,
+ normalize_match_string(match_groups[index]))
index += 1
- set_match_string(items_found, TAG_PP_DATE, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_PP_DATE,
+ normalize_match_string(match_groups[index]))
index += 1
- set_match_string(items_found, TAG_PP_SPONSOR, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_PP_SPONSOR,
+ normalize_match_string(match_groups[index]))
index += 1
- set_match_string(items_found, TAG_CC_VERSION, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_CC_VERSION,
+ normalize_match_string(match_groups[index]))
index += 1
- set_match_string(items_found, TAG_CC_SECURITY_LEVEL, normalize_match_string(match_groups[index]))
+ set_match_string(items_found, TAG_CC_SECURITY_LEVEL,
+ normalize_match_string(match_groups[index]))
index += 1
-
- set_match_string(items_found, TAG_PP_REGISTRATOR_SIMPLIFIED, 'DCSSI')
+ set_match_string(
+ items_found, TAG_PP_REGISTRATOR_SIMPLIFIED, 'DCSSI')
if no_match_yet:
files_without_match.append(file_name)
@@ -913,7 +1090,7 @@ def search_pp_only_headers(walk_dir):
return items_found_all, files_without_match
-def extract_protectionprofiles_frontpage(walk_dir, write_output_file = True):
+def extract_protectionprofiles_frontpage(walk_dir, write_output_file=True):
pp_items_found, pp_files_without_match = search_pp_only_headers(walk_dir)
print('*** Files without detected protection profiles header')
@@ -924,18 +1101,20 @@ def extract_protectionprofiles_frontpage(walk_dir, write_output_file = True):
# store results into file with fixed name and also with time appendix
if write_output_file:
with open("pp_data_frontpage_all.json", "w", errors=FILE_ERRORS_STRATEGY) as write_file:
- write_file.write(json.dumps(pp_items_found, indent=4, sort_keys=True))
+ write_file.write(json.dumps(
+ pp_items_found, indent=4, sort_keys=True))
return pp_items_found
-def extract_certificates_keywords(walk_dir, fragments_dir, file_prefix, write_output_file = True):
+def extract_certificates_keywords(walk_dir, fragments_dir, file_prefix, write_output_file=True,
+ should_censure_right_away=False, fips_items=None):
# ensure existence of fragments folder
if not os.path.exists(fragments_dir):
os.makedirs(fragments_dir)
-
+ print("***EXTRACT KEYWORDS***")
all_items_found = {}
- cert_id = {}
+ # cert_id = {}
for file_name in search_files(walk_dir):
if not os.path.isfile(file_name):
continue
@@ -943,32 +1122,39 @@ def extract_certificates_keywords(walk_dir, fragments_dir, file_prefix, write_ou
if file_ext != '.txt':
continue
- print('*** {} ***'.format(file_name))
+ # print('*** {} ***'.format(file_name))
+ file_cert_name = os.path.splitext(
+ os.path.splitext(os.path.basename(file_name))[0])[0]
# parse certificate, return all matches
- all_items_found[file_name], modified_cert_file = parse_cert_file(file_name, rules, -1)
+ all_items_found[file_cert_name], modified_cert_file = parse_cert_file(
+ file_name, fips_rules if fips_items else rules, -1, should_censure_right_away=should_censure_right_away,
+ fips_items=fips_items)
# try to establish the certificate id of the current certificate
- cert_id[file_name] = estimate_cert_id(None, all_items_found[file_name], file_name)
+ # cert_id[file_cert_name] = estimate_cert_id(
+ # None, all_items_found[file_cert_name], file_name)
# save report text with highlighted/replaced matches into \\fragments\\ directory
- base_path = file_name[:file_name.rfind('\\')]
- file_name_short = file_name[file_name.rfind('\\') + 1:]
- target_file = '{}\\{}'.format(fragments_dir, file_name_short)
- save_modified_cert_file(target_file, modified_cert_file[0], modified_cert_file[1])
+ base_path = file_name[:file_name.rfind(os.sep)]
+ file_name_short = file_name[file_name.rfind(os.sep) + 1:]
+ target_file = '{}{}{}'.format(fragments_dir, os.sep, file_name_short)
+ save_modified_cert_file(
+ target_file, modified_cert_file[0], modified_cert_file[1])
# store results into file with fixed name and also with time appendix
if write_output_file:
with open("{}_data_keywords_all.json".format(file_prefix), "w", errors=FILE_ERRORS_STRATEGY) as write_file:
- write_file.write(json.dumps(all_items_found, indent=4, sort_keys=True))
+ write_file.write(json.dumps(
+ all_items_found, indent=4, sort_keys=True))
- print('\nTotal matches found in separate files:')
+ # print('\nTotal matches found in separate files:')
# print_total_matches_in_files(all_items_found_count)
- print('\nFile name and estimated certificate ID:')
+ # print('\nFile name and estimated certificate ID:')
# print_guessed_cert_id(cert_id)
- #depricated_print_dot_graph_keywordsonly(['rules_cert_id'], all_items_found, cert_id, walk_dir, 'certid_graph_from_keywords.dot', True)
+ # depricated_print_dot_graph_keywordsonly(['rules_cert_id'], all_items_found, cert_id, walk_dir, 'certid_graph_from_keywords.dot', True)
total_items_found = 0
for file_name in all_items_found:
@@ -978,16 +1164,18 @@ def extract_certificates_keywords(walk_dir, fragments_dir, file_prefix, write_ou
if PRINT_MATCHES:
all_matches = []
for file_name in all_items_found:
+ print('*' * 10, "FILENAME:", file_name, '*' * 10)
for rule_group in all_items_found[file_name].keys():
items_found = all_items_found[file_name][rule_group]
for rule in items_found.keys():
for match in items_found[rule]:
if match not in all_matches:
- all_matches.append(match)
+ print(match)
+ # all_matches.append(match)
sorted_all_matches = sorted(all_matches)
- for match in sorted_all_matches:
- print(match)
+ # for match in sorted_all_matches:
+ # print(match)
# verify total matches found
print('\nTotal matches found: {}'.format(total_items_found))
@@ -995,8 +1183,7 @@ def extract_certificates_keywords(walk_dir, fragments_dir, file_prefix, write_ou
return all_items_found
-
-def extract_certificates_pdfmeta(walk_dir, file_prefix, write_output_file = True):
+def extract_certificates_pdfmeta(walk_dir, file_prefix, write_output_file=True):
all_items_found = {}
counter = 0
for file_name in search_files(walk_dir):
@@ -1006,7 +1193,8 @@ def extract_certificates_pdfmeta(walk_dir, file_prefix, write_output_file = True
if file_ext != '.pdf':
continue
- print('*** {} ***'.format(file_name))
+ print("***EXTRACT PDFMETA***")
+ # print('*** {} ***'.format(file_name))
item = {}
item['pdf_file_size_bytes'] = os.path.getsize(file_name)
@@ -1036,15 +1224,17 @@ def extract_certificates_pdfmeta(walk_dir, file_prefix, write_output_file = True
if counter % 100 == 0:
# store results into file with fixed name
- with open("{}_data_pdfmeta_{}.json".format(file_prefix, counter), "w", errors=FILE_ERRORS_STRATEGY) as write_file:
- write_file.write(json.dumps(all_items_found, indent=4, sort_keys=True))
+ with open("{}_data_pdfmeta_{}.json".format(file_prefix, counter), "w",
+ errors=FILE_ERRORS_STRATEGY) as write_file:
+ write_file.write(json.dumps(
+ all_items_found, indent=4, sort_keys=True))
counter += 1
-
# store allresults into file with fixed name
if write_output_file:
with open("{}_data_pdfmeta_all.json".format(file_prefix), "w", errors=FILE_ERRORS_STRATEGY) as write_file:
- write_file.write(json.dumps(all_items_found, indent=4, sort_keys=True))
+ write_file.write(json.dumps(
+ all_items_found, indent=4, sort_keys=True))
return all_items_found
@@ -1059,11 +1249,10 @@ def parse_product_updates(updates_chunk, link_files_updates):
maintenance_reports = []
rule_with_maintainance_ST = '.*?([0-9]+?-[0-9]+?-[0-9]+?) (.+?)\<br style=' \
- '.*?\<a href="(.+?)" title="Maintenance Report' \
- '.*?\<a href="(.+?)" title="Maintenance ST'
+ '.*?\<a href="(.+?)" title="Maintenance Report' \
+ '.*?\<a href="(.+?)" title="Maintenance ST'
rule_without_maintainance_ST = '.*?([0-9]+?-[0-9]+?-[0-9]+?) (.+?)\<br style=' \
- '.*?\<a href="(.+?)" title="Maintenance Report'\
-
+ '.*?\<a href="(.+?)" title="Maintenance Report'
if updates_chunk.find('Maintenance Report(s)') != -1:
start_pos = updates_chunk.find('Maintenance Report(s)</div>')
start_pos = updates_chunk.find('<li>', start_pos)
@@ -1083,24 +1272,32 @@ def parse_product_updates(updates_chunk, link_files_updates):
for m in re.finditer(rule, report_chunk):
match_groups = m.groups()
index_next_item = 0
- items_found['maintenance_date'] = normalize_match_string(match_groups[index_next_item])
+ items_found['maintenance_date'] = normalize_match_string(
+ match_groups[index_next_item])
index_next_item += 1
- items_found['maintenance_item_name'] = normalize_match_string(match_groups[index_next_item])
+ items_found['maintenance_item_name'] = normalize_match_string(
+ match_groups[index_next_item])
index_next_item += 1
- items_found['maintenance_link_cert_report'] = normalize_match_string(match_groups[index_next_item])
+ items_found['maintenance_link_cert_report'] = normalize_match_string(
+ match_groups[index_next_item])
index_next_item += 1
if len(match_groups) > index_next_item:
- items_found['maintenance_link_security_target'] = normalize_match_string(match_groups[index_next_item])
+ items_found['maintenance_link_security_target'] = normalize_match_string(
+ match_groups[index_next_item])
index_next_item += 1
else:
items_found['maintenance_link_security_target'] = ""
- cert_file_name = extract_file_name_from_url(items_found['maintenance_link_cert_report'])
+ cert_file_name = extract_file_name_from_url(
+ items_found['maintenance_link_cert_report'])
items_found['link_cert_report_file_name'] = cert_file_name
- st_file_name = extract_file_name_from_url(items_found['maintenance_link_security_target'])
+ st_file_name = extract_file_name_from_url(
+ items_found['maintenance_link_security_target'])
items_found['link_security_target_file_name'] = st_file_name
- link_files_updates.append((items_found['maintenance_link_cert_report'], cert_file_name, items_found['maintenance_link_security_target'], st_file_name))
+ link_files_updates.append(
+ (items_found['maintenance_link_cert_report'], cert_file_name,
+ items_found['maintenance_link_security_target'], st_file_name))
maintenance_reports.append(items_found)
@@ -1116,7 +1313,8 @@ def parse_security_level(security_level):
# some augmented items found
augm_chunk = security_level[start_pos:]
augm_chunk += ' '
- rule = '\<br\>(.+?) ' # items are in form of <br>AVA_VLA.4 <br>AVA_MSU.3 ...
+ # items are in form of <br>AVA_VLA.4 <br>AVA_MSU.3 ...
+ rule = '\<br\>(.+?) '
for m in re.finditer(rule, augm_chunk):
match_groups = m.groups()
@@ -1126,10 +1324,12 @@ def parse_security_level(security_level):
def extract_certificates_metadata_html(file_name):
+ print("***HTML METADATA***")
+ print(file_name)
items_found_all = {}
download_files_certs = []
download_files_updates = []
- print('*** {} ***'.format(file_name))
+ # print('*** {} ***'.format(file_name))
whole_text = load_cert_html_file(file_name)
@@ -1166,31 +1366,33 @@ def extract_certificates_metadata_html(file_name):
# IMPORTANT: order regexes based on their specificity - the most specific goes first
rules_cc_html = [
- (HEADER_TYPE.HEADER_FULL, '\<tr class=(?:""|"even")\>[ ]+\<td class="b"\>(.+?)\<a name="(.+?)" style=.+?\<!-- \<a href="(.+?)" title="Vendor\'s web site" target="_blank"\>(.+?)</a> -->'
- '.+?\<a href="(.+?)" title="Certification Report:.+?" target="_blank" class="button2"\>Certification Report\</a\>'
- '.+?\<a href="(.+?)" title="Security Target:.+?" target="_blank" class="button2">Security Target</a>'
- '.+?\<!-- ------ ------ ------ Product Updates ------ ------ ------ --\>'
- '(.+?)<!-- ------ ------ ------ END Product Updates ------ ------ ------ --\>'
- '.+?\<!--end-product-cell--\>'
- '.+?\<td style="text-align:center"\>\<span title=".+?"\>(.+?)\</span\>\</td\>'
- '.+?\<td style="text-align:center"\>(.*?)\</td\>'
- '[ ]+?\<td>(.+?)\</td\>'),
+ (HEADER_TYPE.HEADER_FULL,
+ '\<tr class=(?:""|"even")\>[ ]+\<td class="b"\>(.+?)\<a name="(.+?)" style=.+?\<!-- \<a href="(.+?)" title="Vendor\'s web site" target="_blank"\>(.+?)</a> -->'
+ '.+?\<a href="(.+?)" title="Certification Report:.+?" target="_blank" class="button2"\>Certification Report\</a\>'
+ '.+?\<a href="(.+?)" title="Security Target:.+?" target="_blank" class="button2">Security Target</a>'
+ '.+?\<!-- ------ ------ ------ Product Updates ------ ------ ------ --\>'
+ '(.+?)<!-- ------ ------ ------ END Product Updates ------ ------ ------ --\>'
+ '.+?\<!--end-product-cell--\>'
+ '.+?\<td style="text-align:center"\>\<span title=".+?"\>(.+?)\</span\>\</td\>'
+ '.+?\<td style="text-align:center"\>(.*?)\</td\>'
+ '[ ]+?\<td>(.+?)\</td\>'),
- (HEADER_TYPE.HEADER_MISSING_VENDOR_WEB,'\<tr class=(?:""|"even")\>[ ]+\<td class="b"\>(.+?)\<a name="(.+?)" style=.+?'
- '.+?\<a href="(.+?)" title="Certification Report:.+?" target="_blank" class="button2"\>Certification Report\</a\>'
- '.+?\<a href="(.+?)" title="Security Target:.+?" target="_blank" class="button2">Security Target</a>'
- '.+?\<!-- ------ ------ ------ Product Updates ------ ------ ------ --\>'
- '(.+?)<!-- ------ ------ ------ END Product Updates ------ ------ ------ --\>'
- '.+?\<!--end-product-cell--\>'
- '.+?\<td style="text-align:center"\>\<span title=".+?"\>(.+?)\</span\>\</td\>'
- '.+?\<td style="text-align:center"\>(.*?)\</td\>'
- '[ ]+?\<td>(.+?)\</td\>'),
+ (HEADER_TYPE.HEADER_MISSING_VENDOR_WEB,
+ '\<tr class=(?:""|"even")\>[ ]+\<td class="b"\>(.+?)\<a name="(.+?)" style=.+?'
+ '.+?\<a href="(.+?)" title="Certification Report:.+?" target="_blank" class="button2"\>Certification Report\</a\>'
+ '.+?\<a href="(.+?)" title="Security Target:.+?" target="_blank" class="button2">Security Target</a>'
+ '.+?\<!-- ------ ------ ------ Product Updates ------ ------ ------ --\>'
+ '(.+?)<!-- ------ ------ ------ END Product Updates ------ ------ ------ --\>'
+ '.+?\<!--end-product-cell--\>'
+ '.+?\<td style="text-align:center"\>\<span title=".+?"\>(.+?)\</span\>\</td\>'
+ '.+?\<td style="text-align:center"\>(.*?)\</td\>'
+ '[ ]+?\<td>(.+?)\</td\>'),
]
no_match_yet = True
for rule in rules_cc_html:
if not no_match_yet:
- continue # search only the first match
+ continue # search only the first match
rule_and_sep = rule[1]
@@ -1198,50 +1400,67 @@ def extract_certificates_metadata_html(file_name):
if no_match_yet:
chunks_matched += 1
items_found = {}
- #items_found_all.append(items_found)
+ # items_found_all.append(items_found)
items_found[TAG_HEADER_MATCH_RULES] = []
no_match_yet = False
# insert rule if at least one match for it was found
- #if rule not in items_found[TAG_HEADER_MATCH_RULES]:
- # items_found[TAG_HEADER_MATCH_RULES].append(rule[1])
+ # if rule not in items_found[TAG_HEADER_MATCH_RULES]:
+ # items_found[TAG_HEADER_MATCH_RULES].append(rule[1])
match_groups = m.groups()
index_next_item = 0
- items_found['cert_item_name'] = normalize_match_string(match_groups[index_next_item])
+ items_found['cert_item_name'] = normalize_match_string(
+ match_groups[index_next_item])
index_next_item += 1
- items_found['cc_cert_item_html_id'] = normalize_match_string(match_groups[index_next_item])
+ items_found['cc_cert_item_html_id'] = normalize_match_string(
+ match_groups[index_next_item])
cert_item_id = items_found['cc_cert_item_html_id']
index_next_item += 1
if not rule[0] == HEADER_TYPE.HEADER_MISSING_VENDOR_WEB:
- items_found['company_site'] = normalize_match_string(match_groups[index_next_item])
+ items_found['company_site'] = normalize_match_string(
+ match_groups[index_next_item])
index_next_item += 1
- items_found['company_name'] = normalize_match_string(match_groups[index_next_item])
+ items_found['company_name'] = normalize_match_string(
+ match_groups[index_next_item])
index_next_item += 1
- items_found['link_cert_report'] = normalize_match_string(match_groups[index_next_item])
- cert_file_name = extract_file_name_from_url(items_found['link_cert_report'])
+ items_found['link_cert_report'] = normalize_match_string(
+ match_groups[index_next_item])
+ cert_file_name = extract_file_name_from_url(
+ items_found['link_cert_report'])
items_found['link_cert_report_file_name'] = cert_file_name
index_next_item += 1
- items_found['link_security_target'] = normalize_match_string(match_groups[index_next_item])
- st_file_name = extract_file_name_from_url(items_found['link_security_target'])
+ items_found['link_security_target'] = normalize_match_string(
+ match_groups[index_next_item])
+ st_file_name = extract_file_name_from_url(
+ items_found['link_security_target'])
items_found['link_security_target_file_name'] = st_file_name
- download_files_certs.append((items_found['link_cert_report'], cert_file_name, items_found['link_security_target'], st_file_name))
+ download_files_certs.append(
+ (
+ items_found['link_cert_report'], cert_file_name, items_found['link_security_target'],
+ st_file_name))
index_next_item += 1
- items_found['maintainance_updates'] = parse_product_updates(match_groups[index_next_item], download_files_updates)
+ items_found['maintainance_updates'] = parse_product_updates(
+ match_groups[index_next_item], download_files_updates)
index_next_item += 1
- items_found['date_cert_issued'] = normalize_match_string(match_groups[index_next_item])
+ items_found['date_cert_issued'] = normalize_match_string(
+ match_groups[index_next_item])
index_next_item += 1
- items_found['date_cert_expiration'] = normalize_match_string(match_groups[index_next_item])
+ items_found['date_cert_expiration'] = normalize_match_string(
+ match_groups[index_next_item])
index_next_item += 1
- cc_security_level = normalize_match_string(match_groups[index_next_item])
- items_found['cc_security_level'], items_found['cc_security_level_augmented'] = parse_security_level(cc_security_level)
+ cc_security_level = normalize_match_string(
+ match_groups[index_next_item])
+ items_found['cc_security_level'], items_found['cc_security_level_augmented'] = parse_security_level(
+ cc_security_level)
index_next_item += 1
# prepare unique name for dictionary (file name is not enough as multiple records reference same cert)
- item_unique_name = '{}__{}'.format(cert_file_name, cert_item_id)
+ item_unique_name = '{}__{}'.format(
+ cert_file_name, cert_item_id)
if item_unique_name not in items_found_all.keys():
items_found_all[item_unique_name] = {}
items_found_all[item_unique_name]['html_scan'] = items_found
@@ -1253,7 +1472,8 @@ def extract_certificates_metadata_html(file_name):
if no_match_yet:
print('No match found in block #{}'.format(chunks_found))
- print('Chunks found: {}, Chunks matched: {}'.format(chunks_found, chunks_matched))
+ print('Chunks found: {}, Chunks matched: {}'.format(
+ chunks_found, chunks_matched))
if chunks_found != chunks_matched:
print('WARNING: not all chunks found were matched')
@@ -1264,21 +1484,24 @@ def check_if_new_or_same(target_dict, target_key, new_value):
if target_key in target_dict.keys():
if target_dict[target_key] != new_value:
if STOP_ON_UNEXPECTED_NUMS:
- raise ValueError('ERROR: Stopping on unexpected intermediate numbers')
+ raise ValueError(
+ 'ERROR: Stopping on unexpected intermediate numbers')
def extract_certificates_metadata_csv(file_name):
+ print("***CSV METADATA***")
+ print(file_name)
items_found_all = {}
expected_columns = -1
with open(file_name, errors=FILE_ERRORS_STRATEGY) as csv_file:
- print('*** {} ***'.format(file_name))
+ # print('*** {} ***'.format(file_name))
csv_reader = csv.reader(csv_file, delimiter=',')
line_count = 0
no_further_maintainance = True
for row in csv_reader:
if line_count == 0:
expected_columns = len(row)
- #print(f'Column names are {", ".join(row)}')
+ # print(f'Column names are {", ".join(row)}')
line_count += 1
else:
if no_further_maintainance:
@@ -1286,12 +1509,14 @@ def extract_certificates_metadata_csv(file_name):
if len(row) == 0:
break
if len(row) != expected_columns:
- print('WARNING: Incorrect number of columns in row {} (likely separator , in item name), going to fix...'.format(line_count))
+ print(
+ 'WARNING: Incorrect number of columns in row {} (likely separator , in item name), going to fix...'.format(
+ line_count))
# trying to fix
if row[4].find('EAL') == -1:
- row[1] = row[1] + row[2] # fix name
- row.remove(row[2]) # remove second part of name
- if len(row[11]) > 0: # test if reassesment is filled
+ row[1] = row[1] + row[2] # fix name
+ row.remove(row[2]) # remove second part of name
+ if len(row[11]) > 0: # test if reassesment is filled
if row[13].find('http://') != -1:
# name
row[11] = row[11] + row[12]
@@ -1306,42 +1531,65 @@ def extract_certificates_metadata_csv(file_name):
items_found['raw_csv_line'] = str(row)
index_next_item = 0
- check_if_new_or_same(items_found, 'cc_category', normalize_match_string(row[index_next_item]))
- items_found['cc_category'] = normalize_match_string(row[index_next_item])
+ check_if_new_or_same(
+ items_found, 'cc_category', normalize_match_string(row[index_next_item]))
+ items_found['cc_category'] = normalize_match_string(
+ row[index_next_item])
index_next_item += 1
- check_if_new_or_same(items_found, 'cert_item_name', normalize_match_string(row[index_next_item]))
- items_found['cert_item_name'] = normalize_match_string(row[index_next_item])
+ check_if_new_or_same(
+ items_found, 'cert_item_name', normalize_match_string(row[index_next_item]))
+ items_found['cert_item_name'] = normalize_match_string(
+ row[index_next_item])
index_next_item += 1
- check_if_new_or_same(items_found, 'cc_manufacturer', normalize_match_string(row[index_next_item]))
- items_found['cc_manufacturer'] = normalize_match_string(row[index_next_item])
+ check_if_new_or_same(
+ items_found, 'cc_manufacturer', normalize_match_string(row[index_next_item]))
+ items_found['cc_manufacturer'] = normalize_match_string(
+ row[index_next_item])
index_next_item += 1
- check_if_new_or_same(items_found, 'cc_scheme', normalize_match_string(row[index_next_item]))
- items_found['cc_scheme'] = normalize_match_string(row[index_next_item])
+ check_if_new_or_same(
+ items_found, 'cc_scheme', normalize_match_string(row[index_next_item]))
+ items_found['cc_scheme'] = normalize_match_string(
+ row[index_next_item])
index_next_item += 1
- check_if_new_or_same(items_found, 'cc_security_level', normalize_match_string(row[index_next_item]))
- items_found['cc_security_level'] = normalize_match_string(row[index_next_item])
+ check_if_new_or_same(
+ items_found, 'cc_security_level', normalize_match_string(row[index_next_item]))
+ items_found['cc_security_level'] = normalize_match_string(
+ row[index_next_item])
index_next_item += 1
- check_if_new_or_same(items_found, 'cc_protection_profiles', normalize_match_string(row[index_next_item]))
- items_found['cc_protection_profiles'] = normalize_match_string(row[index_next_item])
+ check_if_new_or_same(
+ items_found, 'cc_protection_profiles', normalize_match_string(row[index_next_item]))
+ items_found['cc_protection_profiles'] = normalize_match_string(
+ row[index_next_item])
index_next_item += 1
- check_if_new_or_same(items_found, 'cc_certification_date', normalize_match_string(row[index_next_item]))
- items_found['cc_certification_date'] = normalize_match_string(row[index_next_item])
+ check_if_new_or_same(
+ items_found, 'cc_certification_date', normalize_match_string(row[index_next_item]))
+ items_found['cc_certification_date'] = normalize_match_string(
+ row[index_next_item])
index_next_item += 1
- check_if_new_or_same(items_found, 'cc_archived_date', normalize_match_string(row[index_next_item]))
- items_found['cc_archived_date'] = normalize_match_string(row[index_next_item])
+ check_if_new_or_same(
+ items_found, 'cc_archived_date', normalize_match_string(row[index_next_item]))
+ items_found['cc_archived_date'] = normalize_match_string(
+ row[index_next_item])
index_next_item += 1
- check_if_new_or_same(items_found, 'link_cert_report', normalize_match_string(row[index_next_item]))
- items_found['link_cert_report'] = normalize_match_string(row[index_next_item])
+ check_if_new_or_same(
+ items_found, 'link_cert_report', normalize_match_string(row[index_next_item]))
+ items_found['link_cert_report'] = normalize_match_string(
+ row[index_next_item])
link_cert_report = items_found['link_cert_report']
- cert_file_name = extract_file_name_from_url(items_found['link_cert_report'])
- check_if_new_or_same(items_found, 'link_cert_report_file_name', cert_file_name)
+ cert_file_name = extract_file_name_from_url(
+ items_found['link_cert_report'])
+ check_if_new_or_same(
+ items_found, 'link_cert_report_file_name', cert_file_name)
items_found['link_cert_report_file_name'] = cert_file_name
cert_file_name = items_found['link_cert_report_file_name']
index_next_item += 1
- check_if_new_or_same(items_found, 'link_security_target', normalize_match_string(row[index_next_item]))
- items_found['link_security_target'] = normalize_match_string(row[index_next_item])
- st_file_name = extract_file_name_from_url(items_found['link_security_target'])
+ check_if_new_or_same(
+ items_found, 'link_security_target', normalize_match_string(row[index_next_item]))
+ items_found['link_security_target'] = normalize_match_string(
+ row[index_next_item])
+ st_file_name = extract_file_name_from_url(
+ items_found['link_security_target'])
items_found['link_security_target_file_name'] = st_file_name
index_next_item += 1
@@ -1349,13 +1597,17 @@ def extract_certificates_metadata_csv(file_name):
items_found['maintainance_updates'] = []
maintainance = {}
- maintainance['cc_maintainance_date'] = normalize_match_string(row[index_next_item])
+ maintainance['cc_maintainance_date'] = normalize_match_string(
+ row[index_next_item])
index_next_item += 1
- maintainance['cc_maintainance_title'] = normalize_match_string(row[index_next_item])
+ maintainance['cc_maintainance_title'] = normalize_match_string(
+ row[index_next_item])
index_next_item += 1
- maintainance['cc_maintainance_report_link'] = normalize_match_string(row[index_next_item])
+ maintainance['cc_maintainance_report_link'] = normalize_match_string(
+ row[index_next_item])
index_next_item += 1
- maintainance['cc_maintainance_st_link'] = normalize_match_string(row[index_next_item])
+ maintainance['cc_maintainance_st_link'] = normalize_match_string(
+ row[index_next_item])
index_next_item += 1
# add this maintainance to parent item only when not empty
if len(maintainance['cc_maintainance_title']) > 0:
@@ -1365,14 +1617,16 @@ def extract_certificates_metadata_csv(file_name):
# prepare unique name for dictionary (file name is not enough as multiple records reference same cert)
cert_file_name = cert_file_name.replace('%20', ' ')
item_unique_name = cert_file_name
- item_unique_name = '{}__{}'.format(cert_file_name, line_count)
+ item_unique_name = '{}__{}'.format(
+ cert_file_name, line_count)
if item_unique_name not in items_found_all.keys():
items_found_all[item_unique_name] = {}
items_found_all[item_unique_name]['csv_scan'] = items_found
else:
print(' ERROR: {} already in'.format(cert_file_name))
if STOP_ON_UNEXPECTED_NUMS:
- raise ValueError('ERROR: Stopping as value is not unique')
+ raise ValueError(
+ 'ERROR: Stopping as value is not unique')
line_count += 1
@@ -1380,7 +1634,8 @@ def extract_certificates_metadata_csv(file_name):
def fix_pp_url(original_url):
- if original_url.find('/epfiles/') != -1: # links to pp are incorrect - epfiles instead ppfiles
+ # links to pp are incorrect - epfiles instead ppfiles
+ if original_url.find('/epfiles/') != -1:
original_url = original_url.replace('/epfiles/', '/ppfiles/')
original_url = original_url.replace('http://', 'https://')
original_url = original_url.replace(':443', '')
@@ -1406,7 +1661,9 @@ def extract_pp_metadata_csv(file_name):
if len(row) == 0:
break
if len(row) != expected_columns:
- print('WARNING: Incorrect number of columns in row {} (likely separator , in item name), going to fix...'.format(line_count))
+ print(
+ 'WARNING: Incorrect number of columns in row {} (likely separator , in item name), going to fix...'.format(
+ line_count))
# trying to fix
if len(row) == expected_columns + 2:
row[9] = row[9] + row[10] + row[11]
@@ -1425,45 +1682,69 @@ def extract_pp_metadata_csv(file_name):
items_found['raw_csv_line'] = str(row)
index_next_item = 0
- check_if_new_or_same(items_found, 'cc_category', normalize_match_string(row[index_next_item]))
- items_found['cc_category'] = normalize_match_string(row[index_next_item])
+ check_if_new_or_same(
+ items_found, 'cc_category', normalize_match_string(row[index_next_item]))
+ items_found['cc_category'] = normalize_match_string(
+ row[index_next_item])
index_next_item += 1
- check_if_new_or_same(items_found, 'cc_pp_name', normalize_match_string(row[index_next_item]))
- items_found['cc_pp_name'] = normalize_match_string(row[index_next_item])
+ check_if_new_or_same(
+ items_found, 'cc_pp_name', normalize_match_string(row[index_next_item]))
+ items_found['cc_pp_name'] = normalize_match_string(
+ row[index_next_item])
index_next_item += 1
- check_if_new_or_same(items_found, 'cc_pp_version', normalize_match_string(row[index_next_item]))
- items_found['cc_pp_version'] = normalize_match_string(row[index_next_item])
+ check_if_new_or_same(
+ items_found, 'cc_pp_version', normalize_match_string(row[index_next_item]))
+ items_found['cc_pp_version'] = normalize_match_string(
+ row[index_next_item])
index_next_item += 1
- check_if_new_or_same(items_found, 'cc_security_level', normalize_match_string(row[index_next_item]))
- items_found['cc_security_level'] = normalize_match_string(row[index_next_item])
+ check_if_new_or_same(
+ items_found, 'cc_security_level', normalize_match_string(row[index_next_item]))
+ items_found['cc_security_level'] = normalize_match_string(
+ row[index_next_item])
index_next_item += 1
- check_if_new_or_same(items_found, 'cc_certification_date', normalize_match_string(row[index_next_item]))
- items_found['cc_certification_date'] = normalize_match_string(row[index_next_item])
+ check_if_new_or_same(
+ items_found, 'cc_certification_date', normalize_match_string(row[index_next_item]))
+ items_found['cc_certification_date'] = normalize_match_string(
+ row[index_next_item])
index_next_item += 1
- check_if_new_or_same(items_found, 'cc_archived_date', normalize_match_string(row[index_next_item]))
- items_found['cc_archived_date'] = normalize_match_string(row[index_next_item])
+ check_if_new_or_same(
+ items_found, 'cc_archived_date', normalize_match_string(row[index_next_item]))
+ items_found['cc_archived_date'] = normalize_match_string(
+ row[index_next_item])
index_next_item += 1
- check_if_new_or_same(items_found, 'link_pp_report', normalize_match_string(row[index_next_item]))
- items_found['link_pp_report'] = normalize_match_string(row[index_next_item])
- items_found['link_pp_report'] = fix_pp_url(items_found['link_pp_report'])
+ check_if_new_or_same(
+ items_found, 'link_pp_report', normalize_match_string(row[index_next_item]))
+ items_found['link_pp_report'] = normalize_match_string(
+ row[index_next_item])
+ items_found['link_pp_report'] = fix_pp_url(
+ items_found['link_pp_report'])
index_next_item += 1
- pp_report_file_name = extract_file_name_from_url(items_found['link_pp_report'])
- check_if_new_or_same(items_found, 'link_pp_document', normalize_match_string(row[index_next_item]))
- items_found['link_pp_document'] = normalize_match_string(row[index_next_item])
- items_found['link_pp_document'] = fix_pp_url(items_found['link_pp_document'])
+ pp_report_file_name = extract_file_name_from_url(
+ items_found['link_pp_report'])
+ check_if_new_or_same(
+ items_found, 'link_pp_document', normalize_match_string(row[index_next_item]))
+ items_found['link_pp_document'] = normalize_match_string(
+ row[index_next_item])
+ items_found['link_pp_document'] = fix_pp_url(
+ items_found['link_pp_document'])
index_next_item += 1
- pp_document_file_name = extract_file_name_from_url(items_found['link_pp_document'])
+ pp_document_file_name = extract_file_name_from_url(
+ items_found['link_pp_document'])
if 'maintainance_updates' not in items_found:
items_found['maintainance_updates'] = []
maintainance = {}
- maintainance['cc_pp_maintainance_date'] = normalize_match_string(row[index_next_item])
+ maintainance['cc_pp_maintainance_date'] = normalize_match_string(
+ row[index_next_item])
index_next_item += 1
- maintainance['cc_pp_maintainance_title'] = normalize_match_string(row[index_next_item])
+ maintainance['cc_pp_maintainance_title'] = normalize_match_string(
+ row[index_next_item])
index_next_item += 1
- maintainance['cc_maintainance_report_link'] = normalize_match_string(row[index_next_item])
- maintainance['cc_maintainance_report_link'] = fix_pp_url(maintainance['cc_maintainance_report_link'])
+ maintainance['cc_maintainance_report_link'] = normalize_match_string(
+ row[index_next_item])
+ maintainance['cc_maintainance_report_link'] = fix_pp_url(
+ maintainance['cc_maintainance_report_link'])
index_next_item += 1
# add this maintainance to parent item only when not empty
@@ -1472,16 +1753,20 @@ def extract_pp_metadata_csv(file_name):
if no_further_maintainance:
# prepare unique name for dictionary (file name is not enough as multiple records reference same cert)
- pp_document_file_name = pp_document_file_name.replace('%20', ' ')
+ pp_document_file_name = pp_document_file_name.replace(
+ '%20', ' ')
item_unique_name = pp_document_file_name
- item_unique_name = '{}__{}'.format(pp_document_file_name, line_count)
+ item_unique_name = '{}__{}'.format(
+ pp_document_file_name, line_count)
if item_unique_name not in items_found_all.keys():
items_found_all[item_unique_name] = {}
items_found_all[item_unique_name]['csv_scan'] = items_found
else:
- print(' ERROR: {} already in'.format(pp_document_file_name))
+ print(' ERROR: {} already in'.format(
+ pp_document_file_name))
if STOP_ON_UNEXPECTED_NUMS:
- raise ValueError('ERROR: Stopping as value is not unique')
+ raise ValueError(
+ 'ERROR: Stopping as value is not unique')
# save download links for basic protection profile
download_files_certs.append((items_found['link_pp_report'], pp_report_file_name,
@@ -1489,8 +1774,10 @@ def extract_pp_metadata_csv(file_name):
# save download links for maintainance updates protection profile
for item in items_found['maintainance_updates']:
if item['cc_maintainance_report_link'] != "":
- pp_maintainainace_file_name = extract_file_name_from_url(item['cc_maintainance_report_link'])
- download_files_maintainance.append((item['cc_maintainance_report_link'], pp_maintainainace_file_name))
+ pp_maintainainace_file_name = extract_file_name_from_url(
+ item['cc_maintainance_report_link'])
+ download_files_maintainance.append(
+ (item['cc_maintainance_report_link'], pp_maintainainace_file_name))
line_count += 1
@@ -1509,10 +1796,12 @@ def generate_download_script(file_name, certs_dir, targets_dir, base_url, downlo
if file_name_short_web.find(base_url) != -1:
# base url already included
- write_file.write('curl \"{}\" -o \"{}\"\n'.format(file_name_short_web, cert[1]))
+ write_file.write(
+ 'curl \"{}\" -o \"{}\"\n'.format(file_name_short_web, cert[1]))
else:
# insert base url
- write_file.write('curl \"{}{}\" -o \"{}\"\n'.format(base_url, file_name_short_web, cert[1]))
+ write_file.write(
+ 'curl \"{}{}\" -o \"{}\"\n'.format(base_url, file_name_short_web, cert[1]))
write_file.write('{} \"{}\"\n\n'.format(PDF2TEXT_CONVERT, cert[1]))
if len(download_files_certs) > 0 and len(cert) > 2:
@@ -1526,48 +1815,60 @@ def generate_download_script(file_name, certs_dir, targets_dir, base_url, downlo
file_name_short_web = cert[2].replace(' ', '%%20')
if file_name_short_web.find(base_url) != -1:
# base url already included
- write_file.write('curl \"{}\" -o \"{}\"\n'.format(file_name_short_web, cert[3]))
+ write_file.write(
+ 'curl \"{}\" -o \"{}\"\n'.format(file_name_short_web, cert[3]))
else:
# insert base url
- write_file.write('curl \"{}{}\" -o \"{}\"\n'.format(base_url, file_name_short_web, cert[3]))
- write_file.write('{} \"{}\"\n\n'.format(PDF2TEXT_CONVERT, cert[3]))
+ write_file.write(
+ 'curl \"{}{}\" -o \"{}\"\n'.format(base_url, file_name_short_web, cert[3]))
+ write_file.write('{} \"{}\"\n\n'.format(
+ PDF2TEXT_CONVERT, cert[3]))
-def extract_certificates_html(base_dir, write_output_file = True):
+def extract_certificates_html(base_dir, write_output_file=True):
file_name = '{}cc_products_active.html'.format(base_dir)
- items_found_all_active, download_files_certs, download_files_updates = extract_certificates_metadata_html(file_name)
+ items_found_all_active, download_files_certs, download_files_updates = extract_certificates_metadata_html(
+ file_name)
for item in items_found_all_active.keys():
items_found_all_active[item]['html_scan']['cert_status'] = 'active'
if write_output_file:
with open("certificate_data_html_active.json", "w", errors=FILE_ERRORS_STRATEGY) as write_file:
- write_file.write(json.dumps(items_found_all_active, indent=4, sort_keys=True))
+ write_file.write(json.dumps(
+ items_found_all_active, indent=4, sort_keys=True))
- generate_download_script('download_active_certs.bat', 'certs', 'targets', CC_WEB_URL, download_files_certs)
- generate_download_script('download_active_updates.bat', 'certs', 'targets', CC_WEB_URL, download_files_updates)
+ generate_download_script('download_active_certs.bat',
+ 'certs', 'targets', CC_WEB_URL, download_files_certs)
+ generate_download_script('download_active_updates.bat',
+ 'certs', 'targets', CC_WEB_URL, download_files_updates)
file_name = '{}cc_products_archived.html'.format(base_dir)
- items_found_all_archived, download_files_certs, download_files_updates = extract_certificates_metadata_html(file_name)
+ items_found_all_archived, download_files_certs, download_files_updates = extract_certificates_metadata_html(
+ file_name)
for item in items_found_all_archived.keys():
items_found_all_archived[item]['html_scan']['cert_status'] = 'archived'
if write_output_file:
with open("certificate_data_html_archived.json", "w", errors=FILE_ERRORS_STRATEGY) as write_file:
- write_file.write(json.dumps(items_found_all_archived, indent=4, sort_keys=True))
+ write_file.write(json.dumps(
+ items_found_all_archived, indent=4, sort_keys=True))
- generate_download_script('download_archived_certs.bat', 'certs', 'targets', CC_WEB_URL, download_files_certs)
- generate_download_script('download_archived_updates.bat', 'certs', 'targets', CC_WEB_URL, download_files_updates)
+ generate_download_script('download_archived_certs.bat',
+ 'certs', 'targets', CC_WEB_URL, download_files_certs)
+ generate_download_script('download_archived_updates.bat',
+ 'certs', 'targets', CC_WEB_URL, download_files_updates)
items_found_all = {**items_found_all_active, **items_found_all_archived}
if write_output_file:
with open("certificate_data_html_all.json", "w", errors=FILE_ERRORS_STRATEGY) as write_file:
- write_file.write(json.dumps(items_found_all, indent=4, sort_keys=True))
+ write_file.write(json.dumps(
+ items_found_all, indent=4, sort_keys=True))
return items_found_all
-def extract_certificates_csv(base_dir, write_output_file = True):
+def extract_certificates_csv(base_dir, write_output_file=True):
file_name = '{}cc_products_active.csv'.format(base_dir)
items_found_all_active = extract_certificates_metadata_csv(file_name)
for item in items_found_all_active.keys():
@@ -1582,34 +1883,41 @@ def extract_certificates_csv(base_dir, write_output_file = True):
if write_output_file:
with open("certificate_data_csv_all.json", "w", errors=FILE_ERRORS_STRATEGY) as write_file:
- write_file.write(json.dumps(items_found_all, indent=4, sort_keys=True))
+ write_file.write(json.dumps(
+ items_found_all, indent=4, sort_keys=True))
return items_found_all
-def extract_protectionprofiles_csv(base_dir, write_output_file = True):
+def extract_protectionprofiles_csv(base_dir, write_output_file=True):
file_name = '{}cc_pp_active.csv'.format(base_dir)
- items_found_all_active, download_files_pp, download_files_pp_updates = extract_pp_metadata_csv(file_name)
+ items_found_all_active, download_files_pp, download_files_pp_updates = extract_pp_metadata_csv(
+ file_name)
for item in items_found_all_active.keys():
items_found_all_active[item]['csv_scan']['cert_status'] = 'active'
- generate_download_script('download_active_pp.bat', 'pp_report', 'pp', CC_WEB_URL, download_files_pp)
- generate_download_script('download_active_pp_updates.bat', 'pp_updates', '', CC_WEB_URL, download_files_pp_updates)
-
+ generate_download_script('download_active_pp.bat',
+ 'pp_report', 'pp', CC_WEB_URL, download_files_pp)
+ generate_download_script('download_active_pp_updates.bat',
+ 'pp_updates', '', CC_WEB_URL, download_files_pp_updates)
file_name = '{}cc_pp_archived.csv'.format(base_dir)
- items_found_all_archived, download_files_pp, download_files_pp_updates = extract_pp_metadata_csv(file_name)
+ items_found_all_archived, download_files_pp, download_files_pp_updates = extract_pp_metadata_csv(
+ file_name)
for item in items_found_all_archived.keys():
items_found_all_archived[item]['csv_scan']['cert_status'] = 'archived'
- generate_download_script('download_archived_pp.bat', 'pp_report', 'pp', CC_WEB_URL, download_files_pp)
- generate_download_script('download_archived_pp_updates.bat', 'pp_updates', '', CC_WEB_URL, download_files_pp_updates)
+ generate_download_script('download_archived_pp.bat',
+ 'pp_report', 'pp', CC_WEB_URL, download_files_pp)
+ generate_download_script('download_archived_pp_updates.bat',
+ 'pp_updates', '', CC_WEB_URL, download_files_pp_updates)
items_found_all = {**items_found_all_active, **items_found_all_archived}
if write_output_file:
with open("pp_data_csv_all.json", "w", errors=FILE_ERRORS_STRATEGY) as write_file:
- write_file.write(json.dumps(items_found_all, indent=4, sort_keys=True))
+ write_file.write(json.dumps(
+ items_found_all, indent=4, sort_keys=True))
return items_found_all
@@ -1621,9 +1929,11 @@ def check_expected_cert_results(all_html, all_csv, all_front, all_keywords, all_
MIN_ITEMS_FOUND_CSV = 4105
num_items = len(all_csv)
if MIN_ITEMS_FOUND_CSV != num_items:
- print('SANITY: different than expected number of CSV records found! ({} vs. {} expected)'.format(num_items, MIN_ITEMS_FOUND_CSV))
+ print('SANITY: different than expected number of CSV records found! ({} vs. {} expected)'.format(
+ num_items, MIN_ITEMS_FOUND_CSV))
if STOP_ON_UNEXPECTED_NUMS:
- raise ValueError('ERROR: Stopping on unexpected intermediate numbers')
+ raise ValueError(
+ 'ERROR: Stopping on unexpected intermediate numbers')
#
# HTML
@@ -1631,9 +1941,11 @@ def check_expected_cert_results(all_html, all_csv, all_front, all_keywords, all_
MIN_ITEMS_FOUND_HTML = 4103
num_items = len(all_html)
if MIN_ITEMS_FOUND_HTML != num_items:
- print('SANITY: different than expected number of HTML records found! ({} vs. {} expected)'.format(num_items, MIN_ITEMS_FOUND_HTML))
+ print('SANITY: different than expected number of HTML records found! ({} vs. {} expected)'.format(
+ num_items, MIN_ITEMS_FOUND_HTML))
if STOP_ON_UNEXPECTED_NUMS:
- raise ValueError('ERROR: Stopping on unexpected intermediate numbers')
+ raise ValueError(
+ 'ERROR: Stopping on unexpected intermediate numbers')
#
# FRONTPAGE
@@ -1641,9 +1953,11 @@ def check_expected_cert_results(all_html, all_csv, all_front, all_keywords, all_
MIN_ITEMS_FOUND_FRONTPAGE = 1369
num_items = len(all_front)
if MIN_ITEMS_FOUND_FRONTPAGE != num_items:
- print('SANITY: different than expected number of frontpage records found! ({} vs. {} expected)'.format(num_items, MIN_ITEMS_FOUND_FRONTPAGE))
+ print('SANITY: different than expected number of frontpage records found! ({} vs. {} expected)'.format(
+ num_items, MIN_ITEMS_FOUND_FRONTPAGE))
if STOP_ON_UNEXPECTED_NUMS:
- raise ValueError('ERROR: Stopping on unexpected intermediate numbers')
+ raise ValueError(
+ 'ERROR: Stopping on unexpected intermediate numbers')
#
# KEYWORDS
@@ -1653,9 +1967,11 @@ def check_expected_cert_results(all_html, all_csv, all_front, all_keywords, all_
for file_name in all_keywords.keys():
total_items_found += count_num_items_found(all_keywords[file_name])
if MIN_ITEMS_FOUND_KEYWORDS != total_items_found:
- print('SANITY: different than expected number of keywords found! ({} vs. {} expected)'.format(total_items_found, MIN_ITEMS_FOUND_KEYWORDS))
+ print('SANITY: different than expected number of keywords found! ({} vs. {} expected)'.format(
+ total_items_found, MIN_ITEMS_FOUND_KEYWORDS))
if STOP_ON_UNEXPECTED_NUMS:
- raise ValueError('ERROR: Stopping on unexpected intermediate numbers')
+ raise ValueError(
+ 'ERROR: Stopping on unexpected intermediate numbers')
def check_expected_pp_results(all_html, all_csv, all_front, all_keywords):
@@ -1665,9 +1981,11 @@ def check_expected_pp_results(all_html, all_csv, all_front, all_keywords):
MIN_ITEMS_FOUND_CSV = 4105
num_items = len(all_csv)
if MIN_ITEMS_FOUND_CSV != num_items:
- print('SANITY: different than expected number of CSV records found! ({} vs. {} expected)'.format(num_items, MIN_ITEMS_FOUND_CSV))
+ print('SANITY: different than expected number of CSV records found! ({} vs. {} expected)'.format(
+ num_items, MIN_ITEMS_FOUND_CSV))
if STOP_ON_UNEXPECTED_NUMS:
- raise ValueError('ERROR: Stopping on unexpected intermediate numbers')
+ raise ValueError(
+ 'ERROR: Stopping on unexpected intermediate numbers')
#
# HTML
@@ -1675,9 +1993,11 @@ def check_expected_pp_results(all_html, all_csv, all_front, all_keywords):
MIN_ITEMS_FOUND_HTML = 4103
num_items = len(all_html)
if MIN_ITEMS_FOUND_HTML != num_items:
- print('SANITY: different than expected number of HTML records found! ({} vs. {} expected)'.format(num_items, MIN_ITEMS_FOUND_HTML))
+ print('SANITY: different than expected number of HTML records found! ({} vs. {} expected)'.format(
+ num_items, MIN_ITEMS_FOUND_HTML))
if STOP_ON_UNEXPECTED_NUMS:
- raise ValueError('ERROR: Stopping on unexpected intermediate numbers')
+ raise ValueError(
+ 'ERROR: Stopping on unexpected intermediate numbers')
#
# FRONTPAGE
@@ -1685,9 +2005,11 @@ def check_expected_pp_results(all_html, all_csv, all_front, all_keywords):
MIN_ITEMS_FOUND_FRONTPAGE = 1369
num_items = len(all_front)
if MIN_ITEMS_FOUND_FRONTPAGE != num_items:
- print('SANITY: different than expected number of frontpage records found! ({} vs. {} expected)'.format(num_items, MIN_ITEMS_FOUND_FRONTPAGE))
+ print('SANITY: different than expected number of frontpage records found! ({} vs. {} expected)'.format(
+ num_items, MIN_ITEMS_FOUND_FRONTPAGE))
if STOP_ON_UNEXPECTED_NUMS:
- raise ValueError('ERROR: Stopping on unexpected intermediate numbers')
+ raise ValueError(
+ 'ERROR: Stopping on unexpected intermediate numbers')
#
# KEYWORDS
@@ -1697,10 +2019,11 @@ def check_expected_pp_results(all_html, all_csv, all_front, all_keywords):
for file_name in all_keywords.keys():
total_items_found += count_num_items_found(all_keywords[file_name])
if MIN_ITEMS_FOUND_KEYWORDS != total_items_found:
- print('SANITY: different than expected number of keywords found! ({} vs. {} expected)'.format(total_items_found, MIN_ITEMS_FOUND_KEYWORDS))
+ print('SANITY: different than expected number of keywords found! ({} vs. {} expected)'.format(
+ total_items_found, MIN_ITEMS_FOUND_KEYWORDS))
if STOP_ON_UNEXPECTED_NUMS:
- raise ValueError('ERROR: Stopping on unexpected intermediate numbers')
-
+ raise ValueError(
+ 'ERROR: Stopping on unexpected intermediate numbers')
def collate_certificates_data(all_html, all_csv, all_front, all_keywords, all_pdf_meta, file_name_key):
@@ -1708,29 +2031,29 @@ def collate_certificates_data(all_html, all_csv, all_front, all_keywords, all_pd
file_name_to_html_name_mapping = {}
for long_file_name in all_html.keys():
- short_file_name = long_file_name[long_file_name.rfind('\\') + 1:]
+ short_file_name = long_file_name[long_file_name.rfind(os.sep) + 1:]
if short_file_name != '':
file_name_to_html_name_mapping[short_file_name] = long_file_name
file_name_to_front_name_mapping = {}
for long_file_name in all_front.keys():
- short_file_name = long_file_name[long_file_name.rfind('\\') + 1:]
+ short_file_name = long_file_name[long_file_name.rfind(os.sep) + 1:]
if short_file_name != '':
file_name_to_front_name_mapping[short_file_name] = long_file_name
file_name_to_keywords_name_mapping = {}
for long_file_name in all_keywords.keys():
- short_file_name = long_file_name[long_file_name.rfind('\\') + 1:]
+ short_file_name = long_file_name[long_file_name.rfind(os.sep) + 1:]
if short_file_name != '':
- file_name_to_keywords_name_mapping[short_file_name] = [long_file_name, 0]
+ file_name_to_keywords_name_mapping[short_file_name] = [
+ long_file_name, 0]
file_name_to_pdfmeta_name_mapping = {}
for long_file_name in all_pdf_meta.keys():
- short_file_name = long_file_name[long_file_name.rfind('\\') + 1:]
+ short_file_name = long_file_name[long_file_name.rfind(os.sep) + 1:]
if short_file_name != '':
- file_name_to_pdfmeta_name_mapping[short_file_name] = [long_file_name, 0]
-
-
+ file_name_to_pdfmeta_name_mapping[short_file_name] = [
+ long_file_name, 0]
all_cert_items = all_csv
# pair html data, csv data, front pages and keywords
@@ -1739,9 +2062,10 @@ def collate_certificates_data(all_html, all_csv, all_front, all_keywords, all_pd
file_name_pdf = file_name[:file_name.rfind('__')]
file_name_txt = file_name_pdf[:file_name_pdf.rfind('.')] + '.txt'
- #file_name_st = all_csv[file_name]['csv_scan']['link_security_target_file_name']
+ # file_name_st = all_csv[file_name]['csv_scan']['link_security_target_file_name']
if is_in_dict(all_csv, [file_name, 'csv_scan', 'link_security_target']):
- file_name_st = extract_file_name_from_url(all_csv[file_name]['csv_scan']['link_security_target'])
+ file_name_st = extract_file_name_from_url(
+ all_csv[file_name]['csv_scan']['link_security_target'])
file_name_st_txt = file_name_st[:file_name_st.rfind('.')] + '.txt'
else:
file_name_st_txt = 'security_target_which_doesnt_exists'
@@ -1757,25 +2081,33 @@ def collate_certificates_data(all_html, all_csv, all_front, all_keywords, all_pd
if file_name_txt in file_name_to_html_name_mapping.keys():
all_cert_items[file_name]['html_scan'] = all_html[file_name_to_html_name_mapping[file_name_txt][0]]
- file_name_to_html_name_mapping[file_name_txt][1] = 1 # was paired
+ file_name_to_html_name_mapping[file_name_txt][1] = 1 # was paired
else:
- print('WARNING: Corresponding HTML report not found for CSV item {}'.format(file_name))
+ print('WARNING: Corresponding HTML report not found for CSV item {}'.format(
+ file_name))
if file_name_txt in file_name_to_front_name_mapping.keys():
all_cert_items[file_name]['frontpage_scan'] = all_front[file_name_to_front_name_mapping[file_name_txt]]
frontpage_scan = all_front[file_name_to_front_name_mapping[file_name_txt]]
if file_name_txt in file_name_to_keywords_name_mapping.keys():
- all_cert_items[file_name]['keywords_scan'] = all_keywords[file_name_to_keywords_name_mapping[file_name_txt][0]]
- file_name_to_keywords_name_mapping[file_name_txt][1] = 1 # was paired
+ all_cert_items[file_name]['keywords_scan'] = all_keywords[
+ file_name_to_keywords_name_mapping[file_name_txt][0]]
+ # was paired
+ file_name_to_keywords_name_mapping[file_name_txt][1] = 1
keywords_scan = all_keywords[file_name_to_keywords_name_mapping[file_name_txt][0]]
if file_name_st_txt in file_name_to_keywords_name_mapping.keys():
- all_cert_items[file_name]['st_keywords_scan'] = all_keywords[file_name_to_keywords_name_mapping[file_name_st_txt][0]]
- file_name_to_keywords_name_mapping[file_name_st_txt][1] = 1 # was paired
+ all_cert_items[file_name]['st_keywords_scan'] = all_keywords[
+ file_name_to_keywords_name_mapping[file_name_st_txt][0]]
+ # was paired
+ file_name_to_keywords_name_mapping[file_name_st_txt][1] = 1
if file_name_pdf in file_name_to_pdfmeta_name_mapping.keys():
- all_cert_items[file_name]['pdfmeta_scan'] = all_pdf_meta[file_name_to_pdfmeta_name_mapping[file_name_pdf][0]]
- file_name_to_pdfmeta_name_mapping[file_name_pdf][1] = 1 # was paired
+ all_cert_items[file_name]['pdfmeta_scan'] = all_pdf_meta[
+ file_name_to_pdfmeta_name_mapping[file_name_pdf][0]]
+ # was paired
+ file_name_to_pdfmeta_name_mapping[file_name_pdf][1] = 1
else:
print('ERROR: File {} not found in pdfmeta scan'.format(file_name_pdf))
- all_cert_items[file_name]['processed']['cert_id'] = estimate_cert_id(frontpage_scan, keywords_scan, file_name)
+ all_cert_items[file_name]['processed']['cert_id'] = estimate_cert_id(
+ frontpage_scan, keywords_scan, file_name)
# pair pairing in maintainance updates
for file_name in all_csv.keys():
@@ -1784,66 +2116,81 @@ def collate_certificates_data(all_html, all_csv, all_front, all_keywords, all_pd
# process all maintainance updates
for update in all_cert_items[file_name]['csv_scan']['maintainance_updates']:
- file_name_pdf = extract_file_name_from_url(update['cc_maintainance_report_link'])
+ file_name_pdf = extract_file_name_from_url(
+ update['cc_maintainance_report_link'])
file_name_txt = file_name_pdf[:file_name_pdf.rfind('.')] + '.txt'
if is_in_dict(update, ['cc_maintainance_st_link']):
- file_name_st = extract_file_name_from_url(update['cc_maintainance_st_link'])
+ file_name_st = extract_file_name_from_url(
+ update['cc_maintainance_st_link'])
file_name_st_pdf = file_name_st
file_name_st_txt = ''
if len(file_name_st) > 0:
- file_name_st_txt = file_name_st[:file_name_st.rfind('.')] + '.txt'
+ file_name_st_txt = file_name_st[:file_name_st.rfind(
+ '.')] + '.txt'
else:
file_name_st_pdf = 'file_name_which_doesnt_exists'
file_name_st_txt = 'file_name_which_doesnt_exists'
for file_and_id in all_keywords.keys():
- file_name_keyword_txt = file_and_id[file_and_id.rfind('\\') + 1:]
+ file_name_keyword_txt = file_and_id[file_and_id.rfind(
+ os.sep) + 1:]
# in items extracted from html, names are in form of 'file_name.pdf__number'
if file_name_keyword_txt == file_name_txt:
pairing_found = True
if file_name_txt in file_name_to_keywords_name_mapping.keys():
update['keywords_scan'] = all_keywords[file_name_to_keywords_name_mapping[file_name_txt][0]]
if file_name_to_keywords_name_mapping[file_name_txt][1] == 1:
- print('WARNING: {} already paired'.format(file_name_to_keywords_name_mapping[file_name_txt][0]))
- file_name_to_keywords_name_mapping[file_name_txt][1] = 1 # was paired
+ print('WARNING: {} already paired'.format(
+ file_name_to_keywords_name_mapping[file_name_txt][0]))
+ # was paired
+ file_name_to_keywords_name_mapping[file_name_txt][1] = 1
if file_name_keyword_txt == file_name_st_txt:
if file_name_st_txt in file_name_to_keywords_name_mapping.keys():
- update['st_keywords_scan'] = all_keywords[file_name_to_keywords_name_mapping[file_name_st_txt][0]]
+ update['st_keywords_scan'] = all_keywords[
+ file_name_to_keywords_name_mapping[file_name_st_txt][0]]
if file_name_to_keywords_name_mapping[file_name_st_txt][1] == 1:
- print('WARNING: {} already paired'.format(file_name_to_keywords_name_mapping[file_name_st_txt][0]))
- file_name_to_keywords_name_mapping[file_name_st_txt][1] = 1 # was paired
+ print('WARNING: {} already paired'.format(
+ file_name_to_keywords_name_mapping[file_name_st_txt][0]))
+ # was paired
+ file_name_to_keywords_name_mapping[file_name_st_txt][1] = 1
if not pairing_found:
- print('WARNING: Corresponding keywords pairing not found for maintaince item {}'.format(file_name))
+ print('WARNING: Corresponding keywords pairing not found for maintaince item {}'.format(
+ file_name))
for file_and_id in file_name_to_pdfmeta_name_mapping.keys():
- file_name_pdf = file_and_id[file_and_id.rfind('\\') + 1:]
- file_name_pdfmeta_txt = file_name_pdf[:file_name_pdf.rfind('.')] + '.txt'
+ file_name_pdf = file_and_id[file_and_id.rfind(os.sep) + 1:]
+ file_name_pdfmeta_txt = file_name_pdf[:file_name_pdf.rfind(
+ '.')] + '.txt'
# in items extracted from html, names are in form of 'file_name.pdf__number'
if file_name_pdfmeta_txt == file_name_txt:
pairing_found = True
if file_name_pdf in file_name_to_pdfmeta_name_mapping.keys():
update['pdfmeta_scan'] = all_pdf_meta[file_name_to_pdfmeta_name_mapping[file_name_pdf][0]]
if file_name_to_pdfmeta_name_mapping[file_name_pdf][1] == 1:
- print('WARNING: {} already paired'.format(file_name_to_pdfmeta_name_mapping[file_name_pdf][0]))
- file_name_to_pdfmeta_name_mapping[file_name_pdf][1] = 1 # was paired
+ print('WARNING: {} already paired'.format(
+ file_name_to_pdfmeta_name_mapping[file_name_pdf][0]))
+ # was paired
+ file_name_to_pdfmeta_name_mapping[file_name_pdf][1] = 1
if file_name_pdfmeta_txt == file_name_st_txt:
if file_name_st_pdf in file_name_to_pdfmeta_name_mapping.keys():
update['st_pdfmeta_scan'] = all_pdf_meta[file_name_to_pdfmeta_name_mapping[file_name_st_pdf][0]]
if file_name_to_pdfmeta_name_mapping[file_name_st_pdf][1] == 1:
- print('WARNING: {} already paired'.format(file_name_to_pdfmeta_name_mapping[file_name_st_pdf][0]))
- file_name_to_pdfmeta_name_mapping[file_name_st_pdf][1] = 1 # was paired
+ print('WARNING: {} already paired'.format(
+ file_name_to_pdfmeta_name_mapping[file_name_st_pdf][0]))
+ # was paired
+ file_name_to_pdfmeta_name_mapping[file_name_st_pdf][1] = 1
if not pairing_found:
- print('WARNING: Corresponding pdfmeta pairing not found for maintaince item {}'.format(file_name))
-
+ print('WARNING: Corresponding pdfmeta pairing not found for maintaince item {}'.format(
+ file_name))
print('*** Files with keywords extracted, which were NOT matched to any CSV item:')
for item in file_name_to_keywords_name_mapping:
- if file_name_to_keywords_name_mapping[item][1] == 0: # not paired
+ if file_name_to_keywords_name_mapping[item][1] == 0: # not paired
print(' {}'.format(file_name_to_keywords_name_mapping[item][0]))
# display all record which were not paired
@@ -1871,7 +2218,8 @@ def collate_certificates_data(all_html, all_csv, all_front, all_keywords, all_pd
print('WARNING: {} no pdfmeta scan detected'.format(item))
num_pdfmeta_missing += 1
- print('Records without frontpage: {}\nRecords without keywords: {}\nRecords without pdfmeta: {}'.format(num_frontpage_missing, num_keywords_missing, num_pdfmeta_missing))
+ print('Records without frontpage: {}\nRecords without keywords: {}\nRecords without pdfmeta: {}'.format(
+ num_frontpage_missing, num_keywords_missing, num_pdfmeta_missing))
return all_cert_items
@@ -1914,7 +2262,7 @@ def process_certificates_data(all_cert_items, all_pp_items):
# Manufacturer can be single, multiple, separated by - / and ,
# heuristics: if separated candidate manufacturer can be found in original list (
# => is sole manufacturer on another certificate => assumption of correct separation)
- separators = [',', '/'] # , '/', ',', 'and']
+ separators = [',', '/'] # , '/', ',', 'and']
multiple_manuf_detected = False
for sep in separators:
list_manuf = manuf.split(sep)
@@ -1945,25 +2293,27 @@ def process_certificates_data(all_cert_items, all_pp_items):
manuf_starts = {}
already_reduced = {}
- for manuf1 in sorted_manufacturers: # we are processing from the shorter to longer
+ for manuf1 in sorted_manufacturers: # we are processing from the shorter to longer
if manuf1 == '':
continue
for manuf2 in sorted_manufacturers:
if manuf1 != manuf2:
if manuf2.startswith(manuf1):
- print('Potential consolidation of manufacturers: {} vs. {}'.format(manuf1, manuf2))
+ print('Potential consolidation of manufacturers: {} vs. {}'.format(
+ manuf1, manuf2))
if manuf1 not in manuf_starts:
manuf_starts[manuf1] = set()
manuf_starts[manuf1].add(manuf2)
if manuf2 not in already_reduced:
already_reduced[manuf2] = manuf1
else:
- print(' Warning: \'{}\' prefixed by \'{}\' already reduced to \'{}\''.format(manuf2, manuf1, already_reduced[manuf2]))
-
+ print(' Warning: \'{}\' prefixed by \'{}\' already reduced to \'{}\''.format(
+ manuf2, manuf1, already_reduced[manuf2]))
# try to find manufacturers with multiple names and draw the map
dot = Digraph(comment='Manufacturers naming simplifications')
- dot.attr('graph', label='Manufacturers naming simplifications', labelloc='t', fontsize='30')
+ dot.attr('graph', label='Manufacturers naming simplifications',
+ labelloc='t', fontsize='30')
dot.attr('node', style='filled')
already_inserted_edges = []
for file_name in all_cert_items.keys():
@@ -1972,11 +2322,13 @@ def process_certificates_data(all_cert_items, all_pp_items):
joint_manufacturer = cert['csv_scan']['cc_manufacturer']
if joint_manufacturer != '':
for manuf in mapping_csvmanuf_separated[joint_manufacturer]:
- simple_manuf = get_manufacturer_simple_name(manuf, already_reduced)
+ simple_manuf = get_manufacturer_simple_name(
+ manuf, already_reduced)
if simple_manuf != manuf:
edge_name = '{}<->{}'.format(simple_manuf, manuf)
if edge_name not in already_inserted_edges:
- dot.edge(simple_manuf, manuf, color='orange', style='solid')
+ dot.edge(simple_manuf, manuf,
+ color='orange', style='solid')
already_inserted_edges.append(edge_name)
# plot naming hierarchies
@@ -1984,7 +2336,6 @@ def process_certificates_data(all_cert_items, all_pp_items):
dot.render(file_name, view=False)
print('{} pdf rendered'.format(file_name))
-
# update dist with processed list of manufactures
all_cert_items_keys = list(all_cert_items.keys())
for file_name in all_cert_items_keys:
@@ -2003,10 +2354,12 @@ def process_certificates_data(all_cert_items, all_pp_items):
# insert extracted manufacturers by simplified name
simple_manufacturers = []
for manuf in mapping_csvmanuf_separated[manufacturer]:
- simple_manufacturers.append(get_manufacturer_simple_name(manuf, already_reduced))
+ simple_manufacturers.append(
+ get_manufacturer_simple_name(manuf, already_reduced))
cert['processed']['cc_manufacturer_simple_list'] = simple_manufacturers
- cert['processed']['cc_manufacturer_simple'] = get_manufacturer_simple_name(manufacturer, already_reduced)
+ cert['processed']['cc_manufacturer_simple'] = get_manufacturer_simple_name(
+ manufacturer, already_reduced)
# extract certification lab
if is_in_dict(cert, ['frontpage_scan', 'cert_lab']):
@@ -2035,20 +2388,30 @@ def process_certificates_data(all_cert_items, all_pp_items):
def generate_basic_download_script():
with open('download_cc_web.bat', 'w', errors=FILE_ERRORS_STRATEGY) as file:
- file.write('curl \"https://www.commoncriteriaportal.org/products/\" -o cc_products_active.html\n')
- file.write('curl \"https://www.commoncriteriaportal.org/products/index.cfm?archived=1\" -o cc_products_archived.html\n\n')
+ file.write(
+ 'curl \"https://www.commoncriteriaportal.org/products/\" -o cc_products_active.html\n')
+ file.write(
+ 'curl \"https://www.commoncriteriaportal.org/products/index.cfm?archived=1\" -o cc_products_archived.html\n\n')
- file.write('curl \"https://www.commoncriteriaportal.org/labs/\" -o cc_labs.html\n')
+ file.write(
+ 'curl \"https://www.commoncriteriaportal.org/labs/\" -o cc_labs.html\n')
- file.write('curl \"https://www.commoncriteriaportal.org/products/certified_products.csv\" -o cc_products_active.csv\n')
- file.write('curl \"https://www.commoncriteriaportal.org/products/certified_products-archived.csv\" -o cc_products_archived.csv\n\n')
+ file.write(
+ 'curl \"https://www.commoncriteriaportal.org/products/certified_products.csv\" -o cc_products_active.csv\n')
+ file.write(
+ 'curl \"https://www.commoncriteriaportal.org/products/certified_products-archived.csv\" -o cc_products_archived.csv\n\n')
- file.write('curl \"https://www.commoncriteriaportal.org/pps/\" -o cc_pp_active.html\n')
- file.write('curl \"https://www.commoncriteriaportal.org/pps/collaborativePP.cfm?cpp=1\" -o cc_pp_collaborative.html\n')
- file.write('curl \"https://www.commoncriteriaportal.org/pps/index.cfm?archived=1\" -o cc_pp_archived.html\n\n')
+ file.write(
+ 'curl \"https://www.commoncriteriaportal.org/pps/\" -o cc_pp_active.html\n')
+ file.write(
+ 'curl \"https://www.commoncriteriaportal.org/pps/collaborativePP.cfm?cpp=1\" -o cc_pp_collaborative.html\n')
+ file.write(
+ 'curl \"https://www.commoncriteriaportal.org/pps/index.cfm?archived=1\" -o cc_pp_archived.html\n\n')
- file.write('curl \"https://www.commoncriteriaportal.org/pps/pps.csv\" -o cc_pp_active.csv\n')
- file.write('curl \"https://www.commoncriteriaportal.org/pps/pps-archived.csv\" -o cc_pp_archived.csv\n\n')
+ file.write(
+ 'curl \"https://www.commoncriteriaportal.org/pps/pps.csv\" -o cc_pp_active.csv\n')
+ file.write(
+ 'curl \"https://www.commoncriteriaportal.org/pps/pps-archived.csv\" -o cc_pp_archived.csv\n\n')
def generate_failed_download_script(base_dir):
@@ -2064,7 +2427,7 @@ def generate_failed_download_script(base_dir):
MIN_CORRECT_CERT_SIZE = 5000
download_again = []
for sub_folder in sub_folders:
- target_dir = '{}\\{}'.format(base_dir, sub_folder)
+ target_dir = '{}{}{}'.format(base_dir, os.sep, sub_folder)
# obtain list of all downloaded pdf files and their size
files = search_files(target_dir)
for file_name in files:
@@ -2079,12 +2442,13 @@ def generate_failed_download_script(base_dir):
file_size = os.path.getsize(file_name)
if file_size < MIN_CORRECT_CERT_SIZE:
# too small file, likely failed download - retry
- file_name_short = file_name[file_name.rfind('\\') + 1:]
+ file_name_short = file_name[file_name.rfind(os.sep) + 1:]
# double %% is necessary to prevent replacement of %2 within script (second argument of script)
file_name_short_web = file_name_short.replace(' ', '%%20')
download_link = '/files/epfiles/{}'.format(file_name_short_web)
download_again.append((download_link, file_name))
- generate_download_script('download_failed_certs.bat', '', '', CC_WEB_URL, download_again)
- print('*** Number of files to be re-downloaded again (inside \'{}\'): {}'.format('download_failed_certs.bat', len(download_again)))
-
+ generate_download_script('download_failed_certs.bat',
+ '', '', CC_WEB_URL, download_again)
+ print('*** Number of files to be re-downloaded again (inside \'{}\'): {}'.format(
+ 'download_failed_certs.bat', len(download_again)))
diff --git a/src/fips_certificates.py b/src/fips_certificates.py
new file mode 100644
index 00000000..5d7380ee
--- /dev/null
+++ b/src/fips_certificates.py
@@ -0,0 +1,444 @@
+import json
+import os
+import re
+
+from graphviz import Digraph
+from PyPDF2 import PdfFileReader, utils
+import pikepdf
+# from camelot import read_pdf
+from tabula import read_pdf
+
+import extract_certificates
+from process_certificates import load_json_files
+from cert_rules import rules_fips_htmls as RE_FIPS_HTMLS
+
+import time
+
+FILE_ERRORS_STRATEGY = extract_certificates.FILE_ERRORS_STRATEGY
+FIPS_BASE_URL = 'https://csrc.nist.gov'
+FIPS_MODULE_URL = 'https://csrc.nist.gov/projects/cryptographic-module-validation-program/certificate/'
+FIPS_RESULTS_DIR = '/home/stan/sec-certs/fips_results/'
+FIPS_BASE_DIR = '/home/stan/sec-certs/files/fips/'
+SECURITY_POLICIES_DIR = '/home/stan/sec-certs/files/fips/security_policies/'
+
+
+def extract_filename(file):
+ return os.path.splitext(os.path.basename(file))[0]
+
+
+def parse_ul(text):
+ p = re.compile(r"<li>(.*?)<\/li>")
+ return p.findall(text)
+
+
+def parse_table(text):
+ items_found_all = []
+
+ # find <tr>, in that look for "text-nowrap" and look if there is a cert mentioned
+ tr_pattern = re.compile(r"<tr>([\s\S]*?)<\/tr>")
+ name_pattern = re.compile(r"wrap\">(?P<name>[\s\S]*?)<\/td>")
+ cert_pattern_found = re.compile(r"<td>[ \S]*?#[ \S]*?\d+[ \S]*?<\/td>")
+ cert_pattern_localize = re.compile(r"#?[ \S]*?(?P<cert>\d+)")
+
+ for tr_match in tr_pattern.finditer(text):
+ items_found = {}
+ current_tr = tr_match.group()
+ items_found['Name'] = name_pattern.search(current_tr).group('name')
+ cert_line = cert_pattern_found.search(current_tr)
+
+ if cert_line is None:
+ items_found['Certificate'] = ['Not found']
+ else:
+ items_found['Certificate'] = ['#' + x.group('cert') for x in cert_pattern_localize.finditer(
+ cert_line.group())]
+
+ items_found_all.append(items_found)
+
+ return items_found_all
+
+
+def parse_algorithms(text, in_table=False):
+ # print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
+ # print()
+ # print(text)
+ items_found = []
+ for m in re.finditer(r"(?:#{}\s?|Cert\.?[^. ]*?\s?)(?:[Cc]\s)?(?P<id>\d+)".format('?' if in_table else ''), text):
+ items_found.append({'Certificate': m.group()})
+
+ return items_found
+
+
+def parse_caveat(text):
+ items_found = []
+
+ for m in re.finditer(r"(?:#\s?|Cert\.?(?!.\s)\s?|Certificate\s?)(?P<id>\d+)", text):
+ items_found.append({r"(?:#\s?|Cert\.?(?!.\s)\s?|Certificate\s?)(?P<id>\d+?})": {m.group(): {'count': 1}}})
+
+ return items_found
+
+
+def initialize_entry(input_dictionary):
+ input_dictionary['fips_exceptions'] = []
+ input_dictionary['fips_tested_conf'] = []
+
+ input_dictionary['fips_algorithms'] = []
+ input_dictionary['fips_caveat'] = []
+ input_dictionary['tables_done'] = False
+
+
+def fips_search_html(base_dir, output_file, dump_to_file=False):
+ """fips_search_html.
+
+ :param base_dir: directory to search for html files
+ :param output_file: file to dump json to
+ :param dump_to_file: True/False
+ """
+
+ all_found_items = {}
+
+ for file in extract_certificates.search_files(base_dir):
+ items_found = {}
+ initialize_entry(items_found)
+ text = extract_certificates.load_cert_html_file(file)
+ filename = os.path.splitext(os.path.basename(file))[0]
+ all_found_items[filename] = items_found
+ items_found['cert_fips_id'] = filename
+
+ for rule in RE_FIPS_HTMLS:
+ m = re.search(rule, text)
+ if m is None:
+ # print("ERROR: For rule {} nothing found in file {}.".format(rule, file))
+ continue
+
+ group_dict = m.groupdict()
+ key = list(group_dict)
+
+ # <ul>
+ if key[0] == 'fips_exceptions' or key[0] == 'fips_tested_conf':
+ items_found[key[0]] = parse_ul(group_dict[key[0]])
+
+ # <table>
+ elif key[0] == 'fips_algorithms':
+ if 'fips_algorithms' not in items_found:
+ items_found['fips_algorithms'] = parse_table(group_dict[key[0]])
+ else:
+ items_found['fips_algorithms'] += parse_table(
+ group_dict[key[0]])
+
+ # allowed algorithms
+ elif key[0] == 'fips_allowed_algorithms':
+ if 'fips_algorithms' not in items_found:
+ items_found['fips_algorithms'] = parse_algorithms(
+ group_dict[key[0]])
+ else:
+ items_found['fips_algorithms'] += parse_algorithms(
+ group_dict[key[0]])
+
+ # certificates in Caveat
+ elif key[0] == 'fips_caveat':
+ items_found['fips_mentioned_certs'] = parse_caveat(group_dict[key[0]])
+
+ # there are usually multiple dates separated by ";"
+ elif 'date' in key[0]:
+ items_found[key[0]] = group_dict[key[0]].replace('\n', '').replace(
+ '\t', '').replace(' ', ' ').strip().split(';')
+
+ else:
+ items_found[key[0]] = group_dict[key[0]].replace(
+ '\n', '').replace('\t', '').replace(' ', ' ').strip()
+
+ if dump_to_file:
+ with open(output_file, 'w', errors=FILE_ERRORS_STRATEGY) as write_file:
+ write_file.write(json.dumps(
+ all_found_items, indent=4, sort_keys=True))
+
+ return all_found_items
+
+
+def get_dot_graph(found_items, output_file_name):
+ dot = Digraph(comment='Certificate ecosystem')
+ single_dot = Digraph(comment='Modules with no dependencies')
+ single_dot.attr('graph', label='Single nodes', labelloc='t', fontsize='30')
+ single_dot.attr('node', style='filled')
+ dot.attr('graph', label='Dependencies', labelloc='t', fontsize='30')
+ dot.attr('node', style='filled')
+
+ def found_interesting_cert(current_key):
+ if found_items[current_key]['fips_vendor'] == highlighted_vendor:
+ dot.attr('node', color='red')
+ if found_items[current_key]['fips_status'] == 'Revoked':
+ dot.attr('node', color='grey32')
+ if found_items[current_key]['fips_status'] == 'Historical':
+ dot.attr('node', color='gold3')
+ if found_items[current_key]['fips_vendor'] == "SUSE, LLC":
+ dot.attr('node', color='lightblue')
+
+ def color_check(current_key):
+ dot.attr('node', color='lightgreen')
+ if found_items[current_key]['fips_status'] == 'Revoked':
+ dot.attr('node', color='lightgrey')
+ if found_items[current_key]['fips_status'] == 'Historical':
+ dot.attr('node', color='gold')
+ found_interesting_cert(current_key)
+ dot.node(current_key, label=current_key + '\n' + found_items[current_key]['fips_vendor'] +
+ ('\n' + found_items[current_key]['fips_module_name']
+ if 'fips_module_name' in found_items[current_key] else ''))
+
+ keys = 0
+ edges = 0
+
+ highlighted_vendor = 'Red Hat®, Inc.'
+ for key in found_items:
+ if key != 'Not found' and found_items[key]['file_status']:
+ if found_items[key]['Connections']:
+ color_check(key)
+ keys += 1
+ else:
+ single_dot.attr('node', color='lightblue')
+ found_interesting_cert(key)
+ single_dot.node(key, label=key + '\n' + found_items[key]['fips_vendor'] + ('\n' + found_items[key][
+ 'fips_module_name'] if 'fips_module_name' in found_items[key] else ''))
+
+ for key in found_items:
+ if key != 'Not found' and found_items[key]['file_status']:
+ for conn in found_items[key]['Connections']:
+ color_check(conn)
+ dot.edge(key, conn)
+ edges += 1
+
+ print("rendering {} keys and {} edges".format(keys, edges))
+
+ dot.render(output_file_name + 'connections', view=True)
+ single_dot.render(output_file_name + 'single', view=True)
+
+
+def remove_algorithms_from_extracted_data(items, html):
+ for file_name in items:
+ items[file_name]['file_status'] = True
+ html[file_name]['file_status'] = True
+ if 'fips_mentioned_certs' in html[file_name]:
+ for item in html[file_name]['fips_mentioned_certs']:
+ items[file_name]['rules_cert_id'].update(item)
+
+ for rule in items[file_name]['rules_cert_id']:
+ to_pop = set()
+ rr = re.compile(rule)
+ for cert in items[file_name]['rules_cert_id'][rule]:
+ for alg in items[file_name]['rules_fips_algorithms']:
+ for found in items[file_name]['rules_fips_algorithms'][alg]:
+ if rr.search(found) and rr.search(cert) and rr.search(found).group('id') == rr.search(
+ cert).group('id'):
+ to_pop.add(cert)
+ for r in to_pop:
+ items[file_name]['rules_cert_id'][rule].pop(r, None)
+
+ items[file_name]['rules_cert_id'][rule].pop(
+ html[file_name]['cert_fips_id'], None)
+
+
+def validate_results(items, html):
+ broken_files = set()
+ for file_name in items:
+ for rule in items[file_name]['rules_cert_id']:
+ for cert in items[file_name]['rules_cert_id'][rule]:
+ cert_id = ''.join(filter(str.isdigit, cert))
+
+ if cert_id == '' or cert_id not in html:
+ broken_files.add(file_name)
+ items[file_name]['file_status'] = False
+ html[file_name]['file_status'] = False
+ break
+
+ print("WARNING: CERTIFICATE FILES WITH WRONG CERTIFICATES PARSED")
+ print(*sorted(list(broken_files)), sep='\n')
+ print("... skipping these...")
+ print("Total non-analyzable files:", len(broken_files))
+
+ for file_name in items:
+ html[file_name]['Connections'] = []
+ if not items[file_name]['file_status']:
+ continue
+ if items[file_name]['rules_cert_id'] == {}:
+ continue
+ for rule in items[file_name]['rules_cert_id']:
+ for cert in items[file_name]['rules_cert_id'][rule]:
+ cert_id = ''.join(filter(str.isdigit, cert))
+ if cert_id not in html[file_name]['Connections']:
+ html[file_name]['Connections'].append(cert_id)
+
+
+count = 0
+
+
+def parse_list_of_tables(txt):
+ """
+ Parses list of tables from function find_tables(), finds ones that mention algorithms
+ :param txt: chunk of text
+ :return: list of all pages mentioning algorithm table
+ """
+ rr = re.compile(r"^.+?(?:[Ff]unction|[Aa]lgorithm).+?(?P<page_num>\d+)$", re.MULTILINE)
+ pages = set()
+ for m in rr.finditer(txt):
+ pages.add(m.group('page_num'))
+ return pages
+
+
+def extract_page_number(txt):
+ """
+ Parses chunks of text that are supposed to be mentioning table and having a footer
+ :param txt: input chunk
+ :return: page number
+ """
+ # Page # of #
+ m = re.findall(r"(?P<pattern>(?:[Pp]age) (?P<page_num>\d+)(?: of \d+))", txt)
+ if m:
+ return m[-1][-1]
+ # Page #
+ m = re.findall(r"(?P<pattern>(?:[Pp]age) (?P<page_num>\d+)(?: of \d+)?)", txt)
+ if m:
+ return m[-1][-1]
+ # # of #
+ m = re.findall(r"(?P<pattern>(?:[Pp]age)? ?(?P<page_num>\d+)(?: of \d+))", txt)
+ if m:
+ return m[-1][-1]
+ # number alone
+ m = re.findall(r"(?P<pattern>(?:[Pp]age)? ?(?P<page_num>\d+)(?: of \d+)?)", txt)
+ return m[-1][-1] if m else None
+
+
+def find_tables(txt, file_name, num_pages):
+ global count
+
+ # Look for "List of Tables", where we can find exactly tables with page num
+ tables_regex = re.compile(r"^(?:(?:[Tt]able\s|[Ll]ist\s)(?:[Oo]f\s))[Tt]ables[\s\S]+?\f", re.MULTILINE)
+ table = tables_regex.search(txt)
+ if table:
+ count += 1
+ rb = parse_list_of_tables(table.group())
+ if rb:
+ return list(rb)
+ return None
+
+ # Otherwise look for "Table" in text and \f representing footer, then extract page number from footer
+ print("~" * 20, file_name, '~' * 20)
+ footer_regex = re.compile(r"(?:Table[^\f]*)(?P<first>^[\S\t ]*$)\n(?P<second>(\f[ \t\S]+)$)(?P<third>\n^[ \t\S]+?$)?",
+ re.MULTILINE)
+
+ # We have 2 groups, one is optional - trying to parse 2 lines (just in case)
+ footer1 = [m.group('first') for m in footer_regex.finditer(txt)]
+ footer2 = [m.group('second') for m in footer_regex.finditer(txt)]
+ footer3 = [m.group('third') for m in footer_regex.finditer(txt)]
+
+ # if len(footer2) < len(footer1):
+ # footer2 += [''] * (len(footer1) - len(footer2))
+
+ # zipping them together
+ footer_complete = [m[0] + m[1] + m[2] for m in zip(footer1, footer2, footer3) if m[0] is not None and m[1] is not None and m[2] is not None]
+
+ # removing None and duplicates
+ footers = [extract_page_number(x) for x in footer_complete]
+ footers = list(dict.fromkeys([x for x in footers if x is not None and 0 < int(x) < num_pages]))
+ print(footers)
+ if footers:
+ return footers
+
+
+def repair_pdf_page_count(file):
+ pdf = pikepdf.Pdf.open(file, allow_overwriting_input=True)
+ pdf.save(file)
+ return len(pdf.pages)
+
+
+def extract_certs_from_tables(list_of_files, html_items):
+ global count
+ list_of_files = json.loads(open(FIPS_RESULTS_DIR + 'bakup/broken_files.json').read())
+ not_decoded = []
+ for REDHAT_FILE in list_of_files:
+ if '.txt' not in REDHAT_FILE:
+ continue
+ #
+ # if html_items[extract_filename(REDHAT_FILE[:-8])]['tables_done']:
+ # continue
+
+ with open(REDHAT_FILE, 'r') as f:
+ try:
+ pages = repair_pdf_page_count(REDHAT_FILE[:-4])
+ except pikepdf._qpdf.PdfError:
+ not_decoded.append(REDHAT_FILE)
+ continue
+ tables = find_tables(f.read(), REDHAT_FILE, pages)
+
+ # If we find any tables with page numbers, we process them
+ if tables:
+ lst = []
+ print("~~~~~~~~~~~~~~~", REDHAT_FILE, "~~~~~~~~~~~~~~~~~~~~~~~")
+
+ try:
+ data = read_pdf(REDHAT_FILE[:-4], pages=tables, silent=True)
+ except Exception:
+ not_decoded.append(REDHAT_FILE)
+ continue
+
+ # find columns with cert numbers
+ for df in data:
+ for col in range(len(df.columns)):
+ if 'cert' in df.columns[col].lower() or 'algo' in df.columns[col].lower():
+ lst += parse_algorithms(df.iloc[:, col].to_string(index=False), True)
+
+ # Parse again if someone picks not so descriptive column names
+ lst += parse_algorithms(df.to_string(index=False))
+ if lst:
+ if 'fips_algorithms' not in html_items[extract_filename(REDHAT_FILE[:-8])]:
+ html_items[extract_filename(REDHAT_FILE[:-8])]['fips_algorithms'] = lst
+ else:
+ html_items[extract_filename(REDHAT_FILE[:-8])]['fips_algorithms'] += lst
+ print(lst)
+ html_items[extract_filename(REDHAT_FILE[:-8])]['tables_done'] = True
+ return not_decoded
+
+
+def main():
+ files_to_load = [
+ FIPS_RESULTS_DIR + 'fips_data_keywords_all.json',
+ FIPS_RESULTS_DIR + 'fips_html_all.json'
+ ]
+
+ for file in files_to_load:
+ if not os.path.isfile(file):
+ fips_items = fips_search_html(FIPS_BASE_DIR + 'html/',
+ FIPS_RESULTS_DIR + 'fips_html_all.json', True)
+ items = extract_certificates.extract_certificates_keywords(
+ FIPS_BASE_DIR + 'security_policies/',
+ FIPS_BASE_DIR + 'fragments/', 'fips', fips_items=fips_items,
+ should_censure_right_away=True, write_output_file=True)
+ with open(FIPS_RESULTS_DIR + 'fips_data_keywords_all.json', 'w') as f:
+ f.write(json.dumps(items, indent=4, sort_keys=True))
+ break
+
+ print("EXTRACTION DONE")
+ (items, html) = load_json_files(files_to_load)
+
+ print("FINDING TABLES")
+ not_decoded = extract_certs_from_tables(extract_certificates.search_files(SECURITY_POLICIES_DIR), html)
+
+ print("NOT DECODED:", not_decoded)
+ with open(FIPS_RESULTS_DIR + 'broken_files.json', 'w') as f:
+ f.write(json.dumps(not_decoded))
+
+ print("REMOVING ALGORITHMS")
+ remove_algorithms_from_extracted_data(items, html)
+
+ print("VALIDATING RESULTS")
+ validate_results(items, html)
+ with open(FIPS_RESULTS_DIR + 'fips_html_all.json', 'w') as f:
+ f.write(json.dumps(html, indent=4, sort_keys=True))
+ print("PLOTTING GRAPH")
+ get_dot_graph(html, 'output')
+
+
+if __name__ == '__main__':
+ start = time.time()
+ main()
+ end = time.time()
+ print("TIME:", end - start)
+ print("COUNT:", count)
diff --git a/src/process_certificates.py b/src/process_certificates.py
index 49c60c20..82d92d52 100644
--- a/src/process_certificates.py
+++ b/src/process_certificates.py
@@ -139,15 +139,18 @@ def main():
paths_20200904['id'] = '20200904'
paths_20200904['cc_html_files_dir'] = 'c:\\Certs\\cc_certs_20200904\\web\\'
paths_20200904['walk_dir'] = 'c:\\Certs\\cc_certs_20200904\\cc_certs\\'
- #paths_20200904['walk_dir'] = 'c:\\Certs\\cc_certs_20200904\\cc_certs_test\\'
paths_20200904['pp_dir'] = 'c:\\Certs\\cc_certs_20200904\\cc_pp\\'
paths_20200904['fragments_dir'] = 'c:\\Certs\\cc_certs_20200904\\cc_certs_txt_fragments\\'
paths_20200904['pp_fragments_dir'] = 'c:\\Certs\\cc_certs_20200904\\cc_pp_txt_fragments\\'
+ paths_20200904_test = paths_20200904
+ paths_20200904_test['walk_dir'] = 'c:\\Certs\\cc_certs_20200904\\cc_certs_test\\'
+
# initialize paths based on the profile used
#paths_used = paths_20191208
#paths_used = paths_20200225
- paths_used = paths_20200904
+ #paths_used = paths_20200904
+ paths_used = paths_20200904_test
#paths_used['id'] = 'temp' # change id for temporary debugging
cc_html_files_dir = paths_used['cc_html_files_dir']
@@ -177,12 +180,13 @@ def main():
# with open("pp_data_complete.json", "w") as write_file:
# write_file.write(json.dumps(all_pp_items, indent=4, sort_keys=True))
- do_complete_extraction = False
- do_extraction = False
- do_extraction_pp = False
- do_pairing = False
- do_processing = False
+ do_complete_extraction = True
+ do_extraction = True
+ do_extraction_pp = True
+ do_pairing = True
+ do_processing = True
do_analysis = True
+ do_analysis_filtered = False
# with open('certificate_data_complete_processed.json') as json_file:
# all_cert_items = json.load(json_file)
@@ -304,21 +308,24 @@ def main():
with open('certificate_data_complete_processed.json') as json_file:
all_cert_items = json.load(json_file)
- # analyze only smartcards
- do_analysis_only_filtered(all_cert_items, results_folder,
- ['csv_scan', 'cc_category'], 'ICs, Smart Cards and Smart Card-Related Devices and Systems')
- # analyze only operating systems
- do_analysis_only_filtered(all_cert_items, results_folder,
- ['csv_scan', 'cc_category'], 'Operating Systems')
+ if do_analysis_filtered:
+ # analyze only smartcards
+ do_analysis_only_filtered(all_cert_items, results_folder,
+ ['csv_scan', 'cc_category'], 'ICs, Smart Cards and Smart Card-Related Devices and Systems')
+ # analyze only operating systems
+ do_analysis_only_filtered(all_cert_items, results_folder,
+ ['csv_scan', 'cc_category'], 'Operating Systems')
+
+ # analyze separate manufacturers
+ do_analysis_manufacturers(all_cert_items, results_folder)
+
+ # archived on 09/01/2019
+ do_analysis_09_01_2019_archival(all_cert_items, results_folder)
- # analyze separate manufacturers
- do_analysis_manufacturers(all_cert_items, results_folder)
# analyze all certificates together
do_analysis_everything(all_cert_items, results_folder)
- # archived on 09/01/2019
- do_analysis_09_01_2019_archival(all_cert_items, results_folder)
with open("certificate_data_complete_processed_analyzed.json", "w") as write_file:
write_file.write(json.dumps(all_cert_items, indent=4, sort_keys=True))
@@ -328,7 +335,6 @@ def main():
# TODO
- # use os.sep to support properly Linux&Windows path separation
# add saving of logs into file
# include parsing from protection profiles repo
# add differential partial download of new files only + processing + combine