Projekt

Obecné

Profil

Stáhnout (3.83 KB) Statistiky
| Větev: | Tag: | Revize:
1
from functools import cmp_to_key
2

    
3
# basic constraints
4
from typing import Dict
5

    
6
BASIC_CONSTRAINTS_KEY = "basicConstraints"
7

    
8
CRITICAL = "critical"
9
CA = "CA:TRUE"
10

    
11
# key usages
12
KEY_USAGES_KEY = "keyUsage"
13

    
14
DIGITAL_SIGNATURE = "digitalSignature"
15
NON_REPUDIATION = "nonRepudiation"
16
KEY_ENCIPHERMENT = "keyEncipherment"
17
DATA_ENCIPHERMENT = "dataEncipherment"
18
KEY_AGREEMENT = "keyAgreement"
19
KEY_CERT_SIGN = "keyCertSign"
20
CRL_SIGN = "cRLSign"
21
ENCIPHER_ONLY = "encipherOnly"
22
DECIPHER_ONLY = "decipherOnly"
23

    
24
# extended key usages
25
EXTENDED_KEY_USAGE_KEY = "extendedKeyUsage"
26

    
27
SERVER_AUTH = "serverAuth"
28
CLIENT_AUTH = "clientAuth"
29
CODE_SIGNING = "codeSigning"
30
EMAIL_PROTECTION = "emailProtection"
31
TIME_STAMPING = "timeStamping"
32
OCSP_SIGNING = "OCSPSigning"
33

    
34

    
35
class ExtensionFieldFlags:
36
    def __init__(self, key_usages_flags, extended_key_usages_flags, basic_constraints_flags):
37
        self.key_usages_flags = key_usages_flags
38
        self.extended_key_usages_flags = extended_key_usages_flags
39
        self.basic_constraints_flags = basic_constraints_flags
40

    
41

    
42
def __compare_with_critical_prioritized(item1, item2):
43
    # compare in such way, that the CRITICAL str is always considered to be "smaller" (put before) than any other string
44
    if item1 == CRITICAL:
45
        # first item is CRITICAL, return -1
46
        return -1
47
    elif item2 == CRITICAL:
48
        # second item is CRITICAL, return 2
49
        return 1
50
    elif item1 == item2:
51
        # items are same, return 0
52
        return 0
53
    else:
54
        # none of the items is CRITICAL and they are not equal, compare via < str overloaded operator
55
        return -1 if item1 < item2 else 1
56

    
57

    
58
def usages_to_extension_lines(usages, required_extension_flags:  Dict[int, ExtensionFieldFlags]):
59
    """
60
    Converts usages dictionary to a configuration lines to be put in the extensions section
61

    
62
    :param usages: a dictionary containing usages to be converted into ext. configuration lines
63
    :param required_extension_flags: an object containing an information about which flags are required to be present
64
    in the extension configuration lines to be generated
65
    :return: a list of configuration lines
66
    """
67
    # initialize sets that will represent values of all required fields (keyUsages, extendedKeyUsage, basicConstraints)
68
    key_usages = set()
69
    extended_key_usages = set()
70
    basic_constraints = set()
71

    
72
    # iterate over given usages
73
    for usage, value in usages.items():
74
        # check whether the usage is set to true
75
        if value:
76
            # load required extension fields
77
            key_usage = required_extension_flags[usage]
78

    
79
            # append the required keyUsage flags
80
            key_usages = key_usages.union(key_usage.key_usages_flags)
81

    
82
            # append the required extendedKeyUsage flags
83
            extended_key_usages = extended_key_usages.union(key_usage.extended_key_usages_flags)
84

    
85
            # append the required basicConstraints flags
86
            basic_constraints = basic_constraints.union(key_usage.basic_constraints_flags)
87

    
88
    lines = []
89

    
90
    # sort flags so their order is consistent and therefore testable
91
    # after sorting the flags generate an extension line joining the flags with "," character
92
    if len(basic_constraints) > 0:
93
        # "basicConstraints" (maybe) require the "critical" flag to be at the head of the list if present
94
        lines.append(
95
            f"""{BASIC_CONSTRAINTS_KEY}={",".join(sorted(basic_constraints, key=cmp_to_key(__compare_with_critical_prioritized)))}""")
96

    
97
    if len(key_usages) > 0:
98
        # "keyUsages" (maybe) require the "critical" flag to be at the head of the list if present
99
        lines.append(
100
            f"""{KEY_USAGES_KEY}={",".join(sorted(key_usages, key=cmp_to_key(__compare_with_critical_prioritized)))}""")
101

    
102
    if len(extended_key_usages) > 0:
103
        lines.append(f"""{EXTENDED_KEY_USAGE_KEY}={",".join(sorted(extended_key_usages))}""")
104

    
105
    return lines
(5-5/6)