Projekt

Obecné

Profil

« Předchozí | Další » 

Revize cc51ca2c

Přidáno uživatelem Stanislav Král před asi 4 roky(ů)

Re #8472 - Finished implementation of parse_cert_pem method that parses a subject out of a PEM formatted certificate

Added few unit tests testing this method.

Zobrazit rozdíly:

src/services/cryptography.py
2 2
import re
3 3

  
4 4
# encryption method to be used when generating private keys
5
from src.model.subject import Subject
5 6
from src.utils.temporary_file import TemporaryFile
6 7

  
7 8
PRIVATE_KEY_ENCRYPTION_METHOD = "-aes256"
......
227 228
            raise CryptographyException(OPENSSL_EXECUTABLE, args, err.decode())
228 229

  
229 230
    def parse_cert_pem(self, cert_pem):
231
        """
232
        Parses the given certificate in PEM format and returns the subject of the certificate
233
        :param cert_pem: a certificated in a PEM format to be parsed
234
        :return: a subject stored within the supplied certificate
235
        """
236
        # run openssl x509 to view certificate content
230 237
        args = ["x509", "-noout", "-text", "-in", "-"]
231

  
232 238
        result = self.__run_for_output(args, proc_input=bytes(cert_pem, encoding="utf-8")).decode()
239

  
240
        # find the line containing the subject
233 241
        match = re.search(r"Subject:\s(.*)", result)
234
        pass
235
        # TODO use logger
236 242
        if match is None:
243
            # TODO use logger
237 244
            print(f"Could not find subject to parse: {result}")
245
            return None
238 246
        else:
239
            found = re.findall(r"\s?([^=\s]+)\s?=\s?([^,\n]+)", match)
240
            print(found)
241
            for pair in found:
242
                print(pair)
243

  
247
            # find all attributes (key = value
248
            found = re.findall(r"\s?([^c=\s]+)\s?=\s?([^,\n]+)", match.group())
249
            subj = Subject()
250
            for key, value in found:
251
                if key == "C":
252
                    subj.country = value
253
                elif key == "ST":
254
                    subj.state = value
255
                elif key == "L":
256
                    subj.locality = value
257
                elif key == "O":
258
                    subj.organization = value
259
                elif key == "OU":
260
                    subj.organization_unit = value
261
                elif key == "CN":
262
                    subj.common_name = value
263
                elif key == "emailAddress":
264
                    subj.email_address = value
265
            return subj
244 266

  
245 267

  
246 268
class CryptographyException(Exception):
tests/services/cryptography/parse_cert_pem_test.py
1
from src.model.subject import Subject
2

  
3

  
1 4
def test_parse_cert_pem(service):
2 5
    cert_pem = """
3 6
-----BEGIN CERTIFICATE-----
......
38 41
-----END CERTIFICATE-----
39 42
    """
40 43

  
41
    # service.parse_cert_pem(cert_pem)
44
    # parse a certificate supplied in a PEM format
45
    subj = service.parse_cert_pem(cert_pem)
46

  
47
    assert "CZ" == subj.country
48
    assert "Pilsen Region" == subj.state
49
    assert "Pilsen" == subj.locality
50
    assert "Rooting Roots" == subj.organization
51
    assert "Department of ROots" == subj.organization_unit
52
    assert "Main Rooter" == subj.common_name
53
    assert "root@root.cz" == subj.email_address
54

  
55

  
56
def test_parse_cert_pen_2(service):
57
    cert_pem = """
58
-----BEGIN CERTIFICATE-----
59
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
89
-----END CERTIFICATE-----
90
    """
91

  
92
    # parse a certificate supplied in a PEM format
93
    subj = service.parse_cert_pem(cert_pem)
94

  
95
    assert "AU" == subj.country
96
    assert "Some-State" == subj.state
97
    assert "Internet Widgits Pty Ltd" == subj.organization
98
    assert "NCHILD_2" == subj.common_name
99
    assert None is subj.locality
100
    assert None is subj.organization_unit
101
    assert None is subj.email_address
102

  
103

  
104
def test_parse_cert_pen_empty(service):
105
    cert_pem = """
106
-----BEGIN CERTIFICATE-----
107
MIIDczCCAlugAwIBAgIUPM++Jj33iag4uaOMIzED4/rMTB4wDQYJKoZIhvcNAQEL
108
BQAwSTELMAkGA1UEBhMCICAxCzAJBgNVBAgMAiAgMQowCAYDVQQKDAEgMQswCQYD
109
VQQDDAIgIDEUMBIGCSqGSIb3DQEJARYFIGZvbyAwHhcNMjEwNDAzMjMzMDEwWhcN
110
MjEwNTAzMjMzMDEwWjBJMQswCQYDVQQGEwIgIDELMAkGA1UECAwCICAxCjAIBgNV
111
BAoMASAxCzAJBgNVBAMMAiAgMRQwEgYJKoZIhvcNAQkBFgUgZm9vIDCCASIwDQYJ
112
KoZIhvcNAQEBBQADggEPADCCAQoCggEBALI9Ksw85aFLBw2wAeRUoxMQarXkWWbw
113
FyvGCb426EcdKYEiax4BYsK+VLxJpJsIo4DnSM1c0EKNJmN4w+l93CBVhHvmA+qo
114
3LYShf/DgNeKZD7KJgAWwPHBnA1eOA/8kUX0YT9Z76JpJN46KFfqaY9Scb9GBU/m
115
Kr/Lm2Rkg/LehMObPfNQm3XGOvcRjHON9VoB7hZW8zt2lvWTkhia9t46p/kY90eg
116
3iw5JRR/MeYBiYeikjT4g5pMZDkymWUp7eahOsoR4kGYGLkpdXVN66evWzTikUKV
117
QSHdzUZOiTJ7GFJ70qqh+gAEMCf/Lx8EDbDcuz7ZH40Lr6knY2+9xe8CAwEAAaNT
118
MFEwHQYDVR0OBBYEFChHMZUZ2fyOrclVGjtopKn7f/mSMB8GA1UdIwQYMBaAFChH
119
MZUZ2fyOrclVGjtopKn7f/mSMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL
120
BQADggEBAETfyBYSS6drAyGY1/+z7fWKV3aS1Ocd8c/7oj1seFZ8AH+b0zktTynv
121
khprZhxRGRR6cHhyVmMexSWucWb7zlJZNcO9F0/FIgoqcKODtdNczTJyrC9raeuf
122
8pAqhaxXcNXXUSB8vNQKHLRtRnPCB3nZE7xSl5RRmSPyPGZyyAYygxRnLjMFgJEU
123
4c1FOpvRcfRS5yWviOS6dFv+cGA8hoUMXkpIW88GfwgdO6nMSQB1wUdqKoPnaIFc
124
3vjtLMWkuVZFYqvp3NN6GtyI5pw1O0FzjkLZsAeuHZyIkwpKkMsnGlGW8lz1svZ+
125
7AQMsDl5rA4ZVlnLXSQlq3YXVuXZlAI=
126
-----END CERTIFICATE-----
127
    """
128

  
129
    # parse a certificate supplied in a PEM format
130
    subj = service.parse_cert_pem(cert_pem)
131

  
132
    # TODO improve parsing of fields within quotes
133
    assert "\"  \"" == subj.country
134
    assert "\"  \"" == subj.state
135
    assert "\" \"" == subj.organization
136
    assert "\"  \"" == subj.common_name
137
    assert None is subj.locality
138
    assert None is subj.organization_unit
139
    assert "\" foo \"" == subj.email_address
140

  
141

  
142
def test_create_and_parse_cert(service):
143
    # create a private key
144
    key = service.create_private_key(passphrase="foobar")
145

  
146
    # create a certificate
147
    cert = service.create_sscrt(Subject(common_name="Foo CN", email_address="foo@bar.cz"), key, key_pass="foobar")
148

  
149
    # parse the subject
150
    parsed_subj = service.parse_cert_pem(cert)
151

  
152
    assert "Foo CN" == parsed_subj.common_name
153
    assert "foo@bar.cz" == parsed_subj.email_address

Také k dispozici: Unified diff