I am working on fixing
https://todo.sr.ht/~mcepl/m2crypto/9
(the current WIP patch is at
https://git.sr.ht/~mcepl/m2crypto/log/9_X509-new_extension ), but
I have hard time to fix the last test.
This is the key function `new_extension`:
```python
def new_extension(
name: str, value: str, critical: int = 0, _pyfree: int = 1
) -> X509_Extension:
"""
Create new X509_Extension instance.
"""
if not isinstance(name, str):
raise TypeError("Extension name must be a string.")
if not isinstance(critical, (int, bool)):
raise TypeError("Critical flag must be an integer or boolean.")
# This will be transformed for the final OpenSSL API call.
api_value = value
# This will be the value passed to the validator.
value_to_validate = value
log.debug(f"name = {name}")
log.debug(f"api_value before processing = {api_value}")
# Normalize value for specific extensions
if name == "authorityKeyIdentifier":
# The keyid prefix is required, and the colons in the hex
# string MUST be preserved for the OpenSSL parser.
if "keyid" not in api_value.lower():
formatted_value = "keyid:" + api_value
api_value = formatted_value
value_to_validate = formatted_value
elif name == "subjectKeyIdentifier":
# For SKI, the colons must be stripped.
if ":" in api_value:
api_value = api_value.replace(":", "")
log.debug(f"api_value after processing = {api_value}")
log.debug(f"value_to_validate = {value_to_validate}")
# Validate the value (after special handling)
validator = _EXTENSION_VALIDATORS.get(name)
if validator:
validator(value_to_validate)
# This C function now correctly initializes the context using X509V3_set_ctx_nodb
ctx = m2.x509v3_ctx_new()
if ctx is None:
raise X509Error("Failed to create X509V3_CTX")
conf = None
try:
# Create an empty CONF and bind it
conf = m2.conf_new()
if conf is None:
raise X509Error("Failed to allocate CONF")
m2.x509v3_set_nconf(ctx, conf)
# Create the extension
ext_nid = m2.obj_txt2nid(name)
if ext_nid == 0:
raise X509Error(f"Unknown extension name: {name}")
x509_ext_ptr: Optional[C.X509_EXTENSION]
# For authorityKeyIdentifier with a pre-computed key, we must use
# x509v3_ext_nconf_nid, which reads from the CONF object.
if name == "authorityKeyIdentifier" and "keyid:" in api_value.lower():
section = "default"
config_line = f"{name}={api_value}"
m2.conf_add_string(conf, section, config_line)
key_for_api = name
x509_ext_ptr = m2.x509v3_ext_nconf_nid(conf, ctx, ext_nid, key_for_api)
else:
# For all other extensions, use the original function
x509_ext_ptr = m2.x509v3_ext_conf_nid(ctx, ext_nid, api_value)
if x509_ext_ptr is None:
raise X509Error(f"Failed to create X509 extension for {name}")
x509_ext = X509_Extension(x509_ext_ptr, _pyfree)
if critical:
x509_ext.set_critical(1)
return x509_ext
finally:
if conf:
m2.conf_free(conf)
if ctx:
m2.x509v3_ctx_free(ctx)
```
when running this test (which is basically the reproducer for the bug being fixed):
```python
def test_multiple_extensions(self):
# Testing for
https://todo.sr.ht/~mcepl/m2crypto/9
sub_key_id = "1C:E6:F0:58:58:32:BC:7B:BA:8E:E0:23:1B:FF:17:99:B0:4D:CF:64"
auth_id = "1C:E6:F0:58:58:32:BC:7B:BA:8E:E0:23:1B:FF:17:99:B0:4D:CF:64"
cert_pem_string = textwrap.dedent(
"""\
-----BEGIN CERTIFICATE-----
MIIGFjCCA/6gAwIBAgIJAO7rHaO9YDQDMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNV
BAYTAlVTMQswCQYDVQQIDAJDQTESMBAGA1UEBwwJTG9zIEdhdG9zMRMwEQYDVQQK
DApOYUplRGEgTExDMSMwIQYDVQQLDBpOYUplRGEgR2VvY2FjaGluZyBTZXJ2aWNl
czERMA8GA1UEAwwIbG9jYWxfY2EwHhcNMTgwNTMxMTgwOTMwWhcNMzcxMjMxMTgw
OTMwWjB7MQswCQYDVQQGEwJVUzELMAkGA1UECAwCQ0ExEjAQBgNVBAcMCUxvcyBH
YXRvczETMBEGA1UECgwKTmFKZURhIExMQzEjMCEGA1UECwwaTmFKZURhIEdlb2Nh
Y2hpbmcgU2VydmljZXMxETAPBgNVBAMMCGxvY2FsX2NhMIICIjANBgkqhkiG9w0B
AQEFAAOCAg8AMIICCgKCAgEAwL4VBqghrv9DdUq+63Yty/kaNINIO+ldhY8GxrZd
KXdJqanZN0nMZaW4lys7OTGKml2TzL1JiOueChky5H+8vbmXF8Mp2j3DIQRlYQae
m/cijW4Q8QRiUNdsIcB6pB7Oa7JvyTxMsbwQC2MlE9ItNR2zJ1RMpzGvRoO+wheZ
8zPtXquo+/rJfzoxd2G6/L9Rrwo3Izgwb6NiXbQadg675o/0shmhD1LJT5DcmvjL
0shj+VasUKAOwgt/5GtkjjeE53VsExOkJKrH/RUodl6dXiXBq4ehtwdFGQnTDpyg
bKSXI8M3FPU/zYjt4HYDW5R+VlkKYEdMaOwQ4b9waArCZPSh6SoSZ8SyjRN1wKqn
da+vl5MrzPGTbnN8CXvs89+ti+iT+pdsCc/L3kdwqaV3HNE0pjTg3bChWJ/iNltF
E3lqTmnUcMfvhHpAcj6txB4YqzvQgh7DQ4KnKwFgXvrS7t2fdgFxVe/Bl7ApXi1t
Eg8AEjasuLqb/sTWLyvoWog1iJg7uWsv7F3DXloc7q80eAh610KtPTSzcCvOfd9I
i6+P9yxcOZv4vCbX7rrCJt/scL2/Hz1qqQYA/DcKtvitA2hUAx6AJlMvW14Dw3tc
nHny5lJ4Ty7ZiGN7Bg9Jj1uJusa0le2dkFwx5WjXZu2QMtjgJT8aBl3iM36jNtY7
v6cCAwEAAaOBnDCBmTAdBgNVHQ4EFgQUHObwWFgyvHu6juAjG/8XmbBNz2QwHwYD
VR0jBBgwFoAUHObwWFgyvHu6juAjG/8XmbBNz2QwDwYDVR0TAQH/BAUwAwEB/zAO
BgNVHQ8BAf8EBAMCAQYwNgYDVR0fBC8wLTAroCmgJ4YlaHR0cHM6Ly9jcmwuc29t
ZS51cmwuY29tL2xvY2FsX2NhLmNybDANBgkqhkiG9w0BAQsFAAOCAgEAepM/VwzI
N3aWc08IgF0+J3wYAjDzq2y/ixDXwL/B/XOHElySaiDakiT6HM52Ek/LkFK67Llp
TZIxCwViBxkkcTBS10ymGfsYY5R7lOx14SUIXPOS/Pvht1IZBuSp5J9woZjEZitk
InmWYSmA2Q85JtFs86pNQD9gCOCd5hnKK2LqOwrPAcnOJ06FhZFT/psI5MR8XFjD
/dJUfnkxbK6S77sCslALdsaYdWp6B4gnmZWF3tTxq1IkNKVJuGdcPLg33zFAXzmo
POzjrTmr+1DUEahBbY/9oGcQQh0Ir9lTdd0Uym40FN/7jDA8G1CeK8lsL+TZ5dTU
BPCI2LLd2p7c3SddMNM/GUZdoJ4LXKx3JnDu8lYpjOcL21QHjqfNSmAHzX8skery
jawwi0yijJYwsyrB629ek0p/v16uTojs6JGddOmnz9z1/pBctRw6w83d0jNQc2yY
g89xOl9q0Z7G6rThyNuJwworN5FaPJB2Pl7pHf2uJZEp0mq1SN3Lcfre2yXig8Tc
rWjDY8k9VrEJG0G3n9FVv9hKvob9ngUMkmyxE5E4VWyab5gVt2m0XXJjz5Sc3530
dQ9SXhFS7s3060/yl0BBWnTtfu9zGdKaz4lWo25Q0r7HD5y/MwUCbqpRVqXJxGHY
d3PEYaXkdwhAi3EbarF7R8r3hKzYCpXxfI4=
-----END CERTIFICATE-----"""
)
m2_x509_cert = X509.load_cert_string(cert_pem_string)
local_ski = m2_x509_cert.get_ext("subjectKeyIdentifier")
local_aki = m2_x509_cert.get_ext("authorityKeyIdentifier")
X509.new_extension("subjectKeyIdentifier", sub_key_id)
X509.new_extension("authorityKeyIdentifier", auth_id)
```
I get this:
```
mitmanek:m2crypto (9_X509-new_extension) $ python3 -munittest -v tests.test_x509.X509ExtTestCase.test_multiple_extensions
test_multiple_extensions (tests.test_x509.X509ExtTestCase.test_multiple_extensions) ... DEBUG:new_extension:name = subjectKeyIdentifier
DEBUG:new_extension:api_value before processing = 1C:E6:F0:58:58:32:BC:7B:BA:8E:E0:23:1B:FF:17:99:B0:4D:CF:64
DEBUG:new_extension:api_value after processing = 1CE6F0585832BC7BBA8EE0231BFF1799B04DCF64
DEBUG:new_extension:value_to_validate = 1C:E6:F0:58:58:32:BC:7B:BA:8E:E0:23:1B:FF:17:99:B0:4D:CF:64
DEBUG:validate_subject_key_identifier:value: 1C:E6:F0:58:58:32:BC:7B:BA:8E:E0:23:1B:FF:17:99:B0:4D:CF:64
DEBUG:validate_subject_key_identifier:cleaned_value: 1CE6F0585832BC7BBA8EE0231BFF1799B04DCF64
DEBUG:new_extension:name = authorityKeyIdentifier
DEBUG:new_extension:api_value before processing = 1C:E6:F0:58:58:32:BC:7B:BA:8E:E0:23:1B:FF:17:99:B0:4D:CF:64
DEBUG:new_extension:api_value after processing = keyid:1C:E6:F0:58:58:32:BC:7B:BA:8E:E0:23:1B:FF:17:99:B0:4D:CF:64
DEBUG:new_extension:value_to_validate = keyid:1C:E6:F0:58:58:32:BC:7B:BA:8E:E0:23:1B:FF:17:99:B0:4D:CF:64
DEBUG:validate_subject_key_identifier:value: 1C:E6:F0:58:58:32:BC:7B:BA:8E:E0:23:1B:FF:17:99:B0:4D:CF:64
DEBUG:validate_subject_key_identifier:cleaned_value: 1CE6F0585832BC7BBA8EE0231BFF1799B04DCF64
4076D136C37F0000:error:110000AC:X509 V3 routines:v2i_AUTHORITY_KEYID:unknown value:crypto/x509/v3_akid.c:142:name=authorityKeyIdentifier
ERROR
======================================================================
ERROR: test_multiple_extensions (tests.test_x509.X509ExtTestCase.test_multiple_extensions)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/matej/archiv/2014/projekty/m2crypto/tests/test_x509.py", line 845, in test_multiple_extensions
X509.new_extension("authorityKeyIdentifier", auth_id)
~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/matej/archiv/2014/projekty/m2crypto/build/lib.linux-x86_64-cpython-313/M2Crypto/X509.py", line 270, in new_extension
x509_ext_ptr = m2.x509v3_ext_nconf_nid(conf, ctx, ext_nid, key_for_api)
M2Crypto.X509.X509Error: Unknown error in function _wrap_x509v3_ext_nconf_nid.
----------------------------------------------------------------------
Ran 1 test in 0.004s
FAILED (errors=1)
mitmanek:m2crypto (9_X509-new_extension) $
```
What I am doing wrong? How can I correctly create that
`authorityKeyIdentifier` extension?
Any suggestion would be greatly appreciated.
Thank you,
Matěj
--
http://matej.ceplovi.cz/blog/, @mc...@en.osm.town
GPG Finger: 3C76 A027 CA45 AD70 98B5 BC1D 7920 5802 880B C9D8
Ask yourself whether you’ve really obtained fullness of the Holy
Spirit, followed by gifts needed for your service.
-- Francis MacNutt