aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorPetr Svenda2021-02-05 15:04:48 +0100
committerPetr Svenda2021-02-05 15:04:48 +0100
commit7023bbc7808f42aa08f1a5cf771403cda0d8f52a (patch)
tree8afedabf9bb9706b6b89f864b67095652b4a255c
parent167354823d0e7bd1bf089576219023ffb743c6d3 (diff)
downloadsec-certs-7023bbc7808f42aa08f1a5cf771403cda0d8f52a.tar.gz
sec-certs-7023bbc7808f42aa08f1a5cf771403cda0d8f52a.tar.zst
sec-certs-7023bbc7808f42aa08f1a5cf771403cda0d8f52a.zip
add processing of data extracetd from fips certificates, add stacked graphs
-rwxr-xr-xprocess_certificates.py13
-rw-r--r--sec_certs/analyze_certificates.py139
2 files changed, 137 insertions, 15 deletions
diff --git a/process_certificates.py b/process_certificates.py
index d48f4d78..5307f523 100755
--- a/process_certificates.py
+++ b/process_certificates.py
@@ -18,11 +18,12 @@ from sec_certs.download import download_cc_web, download_cc
@click.option("--do-pairing", "do_pairing", is_flag=True, help="Whether to pair PP stuff.")
@click.option("--do-processing", "do_processing", is_flag=True, help="Whether to process certificates.")
@click.option("--do-analysis", "do_analysis", is_flag=True, help="Whether to analyse certificates.")
-@click.option("--do-find-affected", "do_find_affected", help="Find affected certs.", multiple=True, type=str, metavar="certifocate id")
+@click.option("--do-analysis-fips", "do_analysis_fips", is_flag=True, help="Whether to analyse fips certificates.")
+@click.option("--do-find-affected", "do_find_affected", help="Find affected certs.", multiple=True, type=str, metavar="certificate id")
@click.option("-t", "--threads", "threads", type=int, default=4, help="Amount of threads to use.")
def main(directory, do_complete_extraction: bool, do_download_meta: bool, do_extraction_meta: bool,
do_download_certs: bool, do_pdftotext: bool, do_extraction_certs: bool,
- do_pairing: bool, do_processing: bool, do_analysis: bool, do_find_affected: list, threads: int):
+ do_pairing: bool, do_processing: bool, do_analysis: bool, do_analysis_fips: bool, do_find_affected: list, threads: int):
directory = Path(directory)
web_dir = directory / "web"
@@ -222,6 +223,14 @@ def main(directory, do_complete_extraction: bool, do_download_meta: bool, do_ext
do_analysis_affected(all_cert_items, results_dir, do_find_affected)
+ # analysis of fips extracted data
+ if do_analysis_fips:
+ with open(results_dir / 'fips_full_dataset.json') as json_file:
+ all_cert_items = json.load(json_file)
+
+ # idea: transform into cc-like json then use same analysis functions
+ do_analysis_fips_certs(all_cert_items, results_dir)
+
if __name__ == "__main__":
main()
diff --git a/sec_certs/analyze_certificates.py b/sec_certs/analyze_certificates.py
index 2186f1ea..06b3ba48 100644
--- a/sec_certs/analyze_certificates.py
+++ b/sec_certs/analyze_certificates.py
@@ -16,7 +16,7 @@ from tabulate import tabulate
from . import sanity
from .constants import *
-
+import seaborn as sns
plt.rcdefaults()
@@ -423,8 +423,12 @@ def analyze_references_graph(filter_rules_group, all_items_found, filter_label):
compute_and_plot_hist(indirect_refs, bins, 'Number of certificates', fig_label('# certificates with specific number of indirect references', filter_label), 'cert_indirect_refs_frequency.png')
-def plot_schemes_multi_line_graph(x_ticks, data, prominent_data, x_label, y_label, title, file_name):
+def plot_schemes_multi_graph(x_ticks, data, prominent_data, x_label, y_label, title, file_name):
+ plot_schemes_multi_line_graph(x_ticks, data, prominent_data, x_label, y_label, title, file_name)
+ plot_schemes_stacked_graph(x_ticks, data, prominent_data, x_label, y_label, title, file_name + '_stacked')
+
+def plot_schemes_multi_line_graph(x_ticks, data, prominent_data, x_label, y_label, title, file_name):
figure(num=None, figsize=(16, 8), dpi=200, facecolor='w', edgecolor='k')
line_types = ['-', ':', '-.', '--']
@@ -456,6 +460,43 @@ def plot_schemes_multi_line_graph(x_ticks, data, prominent_data, x_label, y_labe
plt.close()
+def plot_schemes_stacked_graph(x_ticks, data, prominent_data, x_label, y_label, title, file_name):
+ figure(num=None, figsize=(16, 8), dpi=200, facecolor='w', edgecolor='k')
+
+ # x = range(1, 6)
+ # y = [[1, 4, 6, 8, 9], [2, 2, 7, 10, 12], [2, 8, 5, 10, 6]]
+ # plt.stackplot(x, y, labels=['A', 'B', 'C'])
+
+ data_stacked = []
+ line_types = ['-', ':', '-.', '--']
+ num_lines_plotted = 0
+ data_sorted = sorted(data.keys())
+ for group in data_sorted:
+ items_in_year = []
+ for item in sorted(data[group]):
+ num = len(data[group][item])
+ items_in_year.append(num)
+
+ data_stacked.append(items_in_year)
+
+ # if empty data, set as zero
+ if len(data_stacked) == 0:
+ data_stacked = [0] * len(x_ticks)
+
+ pal = sns.color_palette("tab20") # use palette with 20 different colors
+ plt.stackplot(x_ticks, data_stacked, colors=pal, labels=data_sorted)
+
+ plt.rcParams.update({'font.size': 16})
+ plt.legend(loc=2)
+ plt.xticks(x_ticks, rotation=45)
+ 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')
+ plt.close()
+
+
def filter_end_year(items: dict, end_year: int):
filtered_items = {}
@@ -480,7 +521,8 @@ def analyze_cert_years_frequency(all_cert_items, filter_label, force_plot_end_ye
valid_in_years = {}
manufacturer_date = {}
manufacturer_items = {}
- START_YEAR = 1997
+ # START_YEAR = 1997
+ START_YEAR = 1995
END_YEAR = datetime.datetime.now().year + 1
ARCHIVE_OFFSET = 10
@@ -498,13 +540,16 @@ def analyze_cert_years_frequency(all_cert_items, filter_label, force_plot_end_ye
if is_in_dict(cert, ['csv_scan', 'cc_certification_date']):
# extract year of certification
cert_date = cert['csv_scan']['cc_certification_date']
+ if cert_date is None or cert_date == '':
+ continue
+
parsed_date = parser.parse(cert_date)
cert_year = parsed_date.year
# try to extract year of archivation (if provided)
archived_year = None
if is_in_dict(cert, ['csv_scan', 'cc_archived_date']):
cert_archive_date = cert['csv_scan']['cc_archived_date']
- if cert_archive_date != '':
+ if cert_archive_date != '' and cert_archive_date is not None:
archived_year = parser.parse(cert_archive_date).year
# extract EAL level
@@ -645,17 +690,17 @@ def analyze_cert_years_frequency(all_cert_items, filter_label, force_plot_end_ye
'Athena Smartcard', 'Renesas', 'Philips Semiconductors GmbH', 'Oberthur Card Systems']
# plot graphs showing cert. scheme and EAL in years
- plot_schemes_multi_line_graph(years, plot_scheme_date, ['DE', 'JP', 'FR', 'US', 'CA'], 'Year of issuance', 'Number of certificates issued', fig_label('CC certificates issuance frequency per scheme and year', filter_label), 'num_certs_in_years')
- plot_schemes_multi_line_graph(years, plot_level_date, ['EAL4+', 'EAL5+','EAL2+', 'Protection Profile'], 'Year of issuance', 'Number of certificates issued', fig_label('Certificates issuance frequency per EAL and year', filter_label), 'num_certs_eal_in_years')
- plot_schemes_multi_line_graph(years, plot_category_date, [], 'Year of issuance', 'Number of certificates issued', fig_label('Category of certificates issued in given year', filter_label), 'num_certs_category_in_years')
- plot_schemes_multi_line_graph(years, plot_pp_date, [], 'Year of issuance', 'Number of certificates issued', fig_label('Certificates with/without conforming to Protection Profile', filter_label), 'num_certs_pp_in_years')
- plot_schemes_multi_line_graph(years, plot_labs_date, [], 'Year of issuance', 'Number of certificates issued', fig_label('Number of certificates certified by laboratory in given year', filter_label), 'num_certs_by_lab_in_years')
- plot_schemes_multi_line_graph(years, plot_top_manufacturers_date, sc_manufacturers, 'Year of issuance', 'Number of certificates issued', fig_label('Top 20 manufacturers of certified items per year', filter_label), 'manufacturer_in_years')
+ plot_schemes_multi_graph(years, plot_scheme_date, ['DE', 'JP', 'FR', 'US', 'CA'], 'Year of issuance', 'Number of certificates issued', fig_label('CC certificates issuance frequency per scheme and year', filter_label), 'num_certs_in_years')
+ plot_schemes_multi_graph(years, plot_level_date, ['EAL4+', 'EAL5+','EAL2+', 'Protection Profile'], 'Year of issuance', 'Number of certificates issued', fig_label('Certificates issuance frequency per level and year', filter_label), 'num_certs_level_in_years')
+ plot_schemes_multi_graph(years, plot_category_date, [], 'Year of issuance', 'Number of certificates issued', fig_label('Category of certificates issued in given year', filter_label), 'num_certs_category_in_years')
+ plot_schemes_multi_graph(years, plot_pp_date, [], 'Year of issuance', 'Number of certificates issued', fig_label('Certificates with/without conforming to Protection Profile', filter_label), 'num_certs_pp_in_years')
+ plot_schemes_multi_graph(years, plot_labs_date, [], 'Year of issuance', 'Number of certificates issued', fig_label('Number of certificates certified by laboratory in given year', filter_label), 'num_certs_by_lab_in_years')
+ plot_schemes_multi_graph(years, plot_top_manufacturers_date, sc_manufacturers, 'Year of issuance', 'Number of certificates issued', fig_label('Top 20 manufacturers of certified items per year', filter_label), 'manufacturer_in_years')
# plot stats with extended range
years_extended = np.arange(START_YEAR, END_YEAR + ARCHIVE_OFFSET)
- plot_schemes_multi_line_graph(years_extended, archive_date, [], 'Year of issuance', 'Number of certificates', fig_label('Number of certificates archived or planned for archival in a given year', filter_label), 'num_certs_archived_in_years')
- plot_schemes_multi_line_graph(years_extended, valid_in_years, [], 'Year', 'Number of certificates', fig_label('Number of certificates active and archived in given year', filter_label), 'num_certs_active_archived_in_years')
+ plot_schemes_multi_graph(years_extended, archive_date, [], 'Year of issuance', 'Number of certificates', fig_label('Number of certificates archived or planned for archival in a given year', filter_label), 'num_certs_archived_in_years')
+ plot_schemes_multi_graph(years_extended, valid_in_years, [], 'Year', 'Number of certificates', fig_label('Number of certificates active and archived in given year', filter_label), 'num_certs_active_archived_in_years')
# plot certificate validity lengths
print('### Certificates validity period lengths:')
@@ -995,4 +1040,72 @@ def do_analysis_only_smartcards(all_cert_items, current_dir: Path):
def do_analysis_only_operatingsystems(all_cert_items, current_dir: Path):
- do_analysis_only_category(all_cert_items, current_dir, 'Operating Systems') \ No newline at end of file
+ do_analysis_only_category(all_cert_items, current_dir, 'Operating Systems')
+
+
+def transform_fips_to_cc_dict(all_cert_items_fips):
+ all_cert_items_cc = {}
+
+ exceptions_items = {}
+ certs = all_cert_items_fips["certs"]
+ for cert_item_key in certs.keys():
+ fips_item = certs[cert_item_key]
+
+ cc_item = {}
+ cc_item["csv_scan"] = {}
+ cc_item["frontpage_scan"] = {}
+ cc_item["keywords_scan"] = {}
+ cc_item["pdfmeta_scan"] = {}
+ cc_item["processed"] = {}
+
+ cc_item["processed"]["cc_manufacturer_list"] = fips_item["vendor"]
+ cc_item['processed']['cc_manufacturer_simple_list'] = [fips_item["vendor"]]
+ cc_item["processed"]["cert_id"] = fips_item["cert_id"]
+ cc_item["processed"]["cert_lab"] = fips_item["lab"]
+ if fips_item["exceptions"] is None:
+ cc_item["processed"]["cc_security_level"] = 'Level ' + fips_item["level"]
+ else:
+ cc_item["processed"]["cc_security_level"] = 'Level ' + fips_item["level"] + '+'
+
+ cc_item['csv_scan']['cc_scheme'] = 'NIST'
+ cc_item["csv_scan"]["cc_certification_date"] = fips_item["date_validation"][0]
+ cc_item["csv_scan"]["cc_archived_date"] = fips_item["date_sunset"]
+ cc_item["csv_scan"]["cc_category"] = '{} {}'.format(fips_item["type"], fips_item["embodiment"])
+
+ cc_item["processed"]["cc_security_level_augments"] = []
+ if fips_item["exceptions"]:
+ for exception in fips_item["exceptions"]:
+ try:
+ ex_name, ex_level = exception.split(':')
+ ex_name = ex_name.strip()
+ ex_level = ex_level.strip()
+
+ # collect all items seen
+ exceptions_items[ex_name] = exceptions_items.get(ex_name, [])
+ exceptions_items[ex_name].append(ex_level)
+
+ # save augments
+ if ex_level.find("evel") != -1:
+ cc_item["processed"]["cc_security_level_augments"].append('{}.{}'.format(ex_name, ex_level))
+
+ except ValueError as e:
+ print(exception)
+
+ all_cert_items_cc[cert_item_key] = cc_item
+
+ return all_cert_items_cc
+
+
+def do_analysis_fips_certs(all_cert_items_fips, current_dir: Path):
+ all_cert_items = transform_fips_to_cc_dict(all_cert_items_fips)
+ with open(current_dir / "fips_transformed_cc.json", "w") as write_file:
+ json.dump(all_cert_items, write_file, indent=4, sort_keys=True)
+
+ target_folder = os.path.join(current_dir, 'fips')
+ if not os.path.exists(target_folder):
+ os.makedirs(target_folder)
+ os.chdir(target_folder)
+
+ #generate_dot_graphs(all_cert_items, '')
+ analyze_cert_years_frequency(all_cert_items, '')
+ do_analysis_force_end_date(all_cert_items, target_folder, 2020)