@@ -162,6 +162,19 @@ def _get_asn1_time(timestamp):
162
162
return string_result
163
163
164
164
165
+ class _X509NameInvalidator (object ):
166
+ def __init__ (self ):
167
+ self ._names = []
168
+
169
+ def add (self , name ):
170
+ self ._names .append (name )
171
+
172
+ def clear (self ):
173
+ for name in self ._names :
174
+ # Breaks the object, but also prevents UAF!
175
+ del name ._name
176
+
177
+
165
178
class PKey (object ):
166
179
"""
167
180
A class representing an DSA or RSA public key or key pair.
@@ -1032,6 +1045,17 @@ def __init__(self):
1032
1045
_openssl_assert (x509 != _ffi .NULL )
1033
1046
self ._x509 = _ffi .gc (x509 , _lib .X509_free )
1034
1047
1048
+ self ._issuer_invalidator = _X509NameInvalidator ()
1049
+ self ._subject_invalidator = _X509NameInvalidator ()
1050
+
1051
+ @classmethod
1052
+ def _from_raw_x509_ptr (cls , x509 ):
1053
+ cert = cls .__new__ (cls )
1054
+ cert ._x509 = _ffi .gc (x509 , _lib .X509_free )
1055
+ cert ._issuer_invalidator = _X509NameInvalidator ()
1056
+ cert ._subject_invalidator = _X509NameInvalidator ()
1057
+ return cert
1058
+
1035
1059
def to_cryptography (self ):
1036
1060
"""
1037
1061
Export as a ``cryptography`` certificate.
@@ -1382,7 +1406,9 @@ def get_issuer(self):
1382
1406
:return: The issuer of this certificate.
1383
1407
:rtype: :class:`X509Name`
1384
1408
"""
1385
- return self ._get_name (_lib .X509_get_issuer_name )
1409
+ name = self ._get_name (_lib .X509_get_issuer_name )
1410
+ self ._issuer_invalidator .add (name )
1411
+ return name
1386
1412
1387
1413
def set_issuer (self , issuer ):
1388
1414
"""
@@ -1393,7 +1419,8 @@ def set_issuer(self, issuer):
1393
1419
1394
1420
:return: ``None``
1395
1421
"""
1396
- return self ._set_name (_lib .X509_set_issuer_name , issuer )
1422
+ self ._set_name (_lib .X509_set_issuer_name , issuer )
1423
+ self ._issuer_invalidator .clear ()
1397
1424
1398
1425
def get_subject (self ):
1399
1426
"""
@@ -1407,7 +1434,9 @@ def get_subject(self):
1407
1434
:return: The subject of this certificate.
1408
1435
:rtype: :class:`X509Name`
1409
1436
"""
1410
- return self ._get_name (_lib .X509_get_subject_name )
1437
+ name = self ._get_name (_lib .X509_get_subject_name )
1438
+ self ._subject_invalidator .add (name )
1439
+ return name
1411
1440
1412
1441
def set_subject (self , subject ):
1413
1442
"""
@@ -1418,7 +1447,8 @@ def set_subject(self, subject):
1418
1447
1419
1448
:return: ``None``
1420
1449
"""
1421
- return self ._set_name (_lib .X509_set_subject_name , subject )
1450
+ self ._set_name (_lib .X509_set_subject_name , subject )
1451
+ self ._subject_invalidator .clear ()
1422
1452
1423
1453
def get_extension_count (self ):
1424
1454
"""
@@ -1691,8 +1721,7 @@ def _exception_from_context(self):
1691
1721
# expect this call to never return :class:`None`.
1692
1722
_x509 = _lib .X509_STORE_CTX_get_current_cert (self ._store_ctx )
1693
1723
_cert = _lib .X509_dup (_x509 )
1694
- pycert = X509 .__new__ (X509 )
1695
- pycert ._x509 = _ffi .gc (_cert , _lib .X509_free )
1724
+ pycert = X509 ._from_raw_x509_ptr (_cert )
1696
1725
return X509StoreContextError (errors , pycert )
1697
1726
1698
1727
def set_store (self , store ):
@@ -1755,9 +1784,7 @@ def load_certificate(type, buffer):
1755
1784
if x509 == _ffi .NULL :
1756
1785
_raise_current_error ()
1757
1786
1758
- cert = X509 .__new__ (X509 )
1759
- cert ._x509 = _ffi .gc (x509 , _lib .X509_free )
1760
- return cert
1787
+ return X509 ._from_raw_x509_ptr (x509 )
1761
1788
1762
1789
1763
1790
def dump_certificate (type , cert ):
0 commit comments