Skip to content

Commit c367480

Browse files
committed
feat(crypto): add functions necessary to generate the ari data
Add generate_ari_data, get_certificate_aki and get_certificate_serial functions to the project. Refs: #121
1 parent e4cd08a commit c367480

File tree

2 files changed

+74
-4
lines changed

2 files changed

+74
-4
lines changed

automatoes/crypto.py

+21-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
# -*- coding: UTF-8 -*-
2-
#
3-
# Copyright 2019-2023 Flávio Gonçalves Garcia
1+
# Copyright 2019-2025 Flavio Garcia
42
# Copyright 2016-2017 Veeti Paananen under MIT License
53
#
64
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -28,7 +26,7 @@
2826
with warnings.catch_warnings():
2927
warnings.simplefilter("ignore")
3028
from cryptography import x509
31-
from cryptography.x509 import NameOID, DNSName, SubjectAlternativeName
29+
from cryptography.x509 import NameOID, DNSName
3230
from cryptography.hazmat.backends import default_backend
3331
from cryptography.hazmat.primitives.asymmetric import padding
3432
from cryptography.hazmat.primitives.asymmetric.rsa import (
@@ -90,6 +88,13 @@ def certbot_key_data_to_int(key_data: dict) -> dict:
9088
return key_data_int
9189

9290

91+
def generate_ari_data(cert):
92+
aki_b64 = base64.urlsafe_b64encode(get_certificate_aki(cert).encode())
93+
serial_b64 = base64.urlsafe_b64encode(
94+
get_certificate_serial(cert).encode())
95+
return f"{aki_b64}.{serial_b64}"
96+
97+
9398
def generate_header(account_key):
9499
"""
95100
Creates a new request header for the specified account key.
@@ -234,6 +239,18 @@ def get_issuer_certificate_domain_name(cert):
234239
return cn.value
235240

236241

242+
def get_certificate_aki(cert):
243+
for ext in cert.extensions:
244+
if isinstance(ext.value, x509.AuthorityKeyIdentifier):
245+
hex = ext.value.key_identifier.hex()
246+
return ":".join(hex[i:i+2] for i in range(0, len(hex), 2))
247+
248+
249+
def get_certificate_serial(cert):
250+
hex = format(cert.serial_number, "x")
251+
return ":".join(hex[i:i+2] for i in range(0, len(hex), 2))
252+
253+
237254
def get_certificate_domain_name(cert):
238255
for ext in cert.extensions:
239256
if isinstance(ext.value, x509.SubjectAlternativeName):

tests/ari_test.py

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Copyright 2019-2025 Flavio Garcia
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from . import FIXTURES_ROOT
16+
from automatoes.crypto import (generate_ari_data,
17+
get_certificate_aki,
18+
get_certificate_serial,
19+
load_pem_certificate)
20+
import base64
21+
from cartola import fs
22+
import unittest
23+
import os
24+
25+
26+
class ARITestCase(unittest.TestCase):
27+
""" Tests the crypto module from automatoes
28+
"""
29+
30+
def test_aki(self):
31+
""" Test the strip_certificate function """
32+
key_directory = os.path.join(FIXTURES_ROOT, "keys", "candango.org",
33+
"another")
34+
35+
key_crt = fs.read(
36+
os.path.join(key_directory, "another.candango.org.crt"),
37+
True
38+
)
39+
40+
pem_crt = load_pem_certificate(key_crt)
41+
42+
aki = get_certificate_aki(pem_crt)
43+
serial = get_certificate_serial(pem_crt)
44+
expected_aki = ("c0:cc:03:46:b9:58:20:cc:5c:72:70:f3:e1:2e:cb:20:a6:"
45+
"f5:68:3a")
46+
expected_serial = ("fa:f3:97:73:26:ea:e8:44:e7:14:00:20:ae:90:60:af:"
47+
"ba:44")
48+
aki_b64 = base64.urlsafe_b64encode(expected_aki.encode())
49+
serial_b64 = base64.urlsafe_b64encode(expected_serial.encode())
50+
51+
self.assertEqual(expected_aki, aki)
52+
self.assertEqual(expected_serial, serial)
53+
self.assertEqual(f"{aki_b64}.{serial_b64}", generate_ari_data(pem_crt))

0 commit comments

Comments
 (0)