|
3 | 3 | import calendar |
4 | 4 | import datetime |
5 | 5 | import functools |
6 | | -import typing |
7 | | -import warnings |
8 | 6 | from base64 import b16encode |
9 | | -from collections.abc import Iterable, Sequence |
| 7 | +from collections.abc import Sequence |
10 | 8 | from functools import partial |
11 | 9 | from os import PathLike |
12 | 10 | from typing import ( |
|
52 | 50 | "X509", |
53 | 51 | "Error", |
54 | 52 | "PKey", |
55 | | - "X509Extension", |
56 | 53 | "X509Name", |
57 | 54 | "X509Req", |
58 | 55 | "X509Store", |
@@ -784,189 +781,6 @@ def get_components(self) -> list[tuple[bytes, bytes]]: |
784 | 781 | return result |
785 | 782 |
|
786 | 783 |
|
787 | | -class X509Extension: |
788 | | - """ |
789 | | - An X.509 v3 certificate extension. |
790 | | -
|
791 | | - .. deprecated:: 23.3.0 |
792 | | - Use cryptography's X509 APIs instead. |
793 | | - """ |
794 | | - |
795 | | - def __init__( |
796 | | - self, |
797 | | - type_name: bytes, |
798 | | - critical: bool, |
799 | | - value: bytes, |
800 | | - subject: X509 | None = None, |
801 | | - issuer: X509 | None = None, |
802 | | - ) -> None: |
803 | | - """ |
804 | | - Initializes an X509 extension. |
805 | | -
|
806 | | - :param type_name: The name of the type of extension_ to create. |
807 | | - :type type_name: :py:data:`bytes` |
808 | | -
|
809 | | - :param bool critical: A flag indicating whether this is a critical |
810 | | - extension. |
811 | | -
|
812 | | - :param value: The OpenSSL textual representation of the extension's |
813 | | - value. |
814 | | - :type value: :py:data:`bytes` |
815 | | -
|
816 | | - :param subject: Optional X509 certificate to use as subject. |
817 | | - :type subject: :py:class:`X509` |
818 | | -
|
819 | | - :param issuer: Optional X509 certificate to use as issuer. |
820 | | - :type issuer: :py:class:`X509` |
821 | | -
|
822 | | - .. _extension: https://www.openssl.org/docs/manmaster/man5/ |
823 | | - x509v3_config.html#STANDARD-EXTENSIONS |
824 | | - """ |
825 | | - ctx = _ffi.new("X509V3_CTX*") |
826 | | - |
827 | | - # A context is necessary for any extension which uses the r2i |
828 | | - # conversion method. That is, X509V3_EXT_nconf may segfault if passed |
829 | | - # a NULL ctx. Start off by initializing most of the fields to NULL. |
830 | | - _lib.X509V3_set_ctx(ctx, _ffi.NULL, _ffi.NULL, _ffi.NULL, _ffi.NULL, 0) |
831 | | - |
832 | | - # We have no configuration database - but perhaps we should (some |
833 | | - # extensions may require it). |
834 | | - _lib.X509V3_set_ctx_nodb(ctx) |
835 | | - |
836 | | - # Initialize the subject and issuer, if appropriate. ctx is a local, |
837 | | - # and as far as I can tell none of the X509V3_* APIs invoked here steal |
838 | | - # any references, so no need to mess with reference counts or |
839 | | - # duplicates. |
840 | | - if issuer is not None: |
841 | | - if not isinstance(issuer, X509): |
842 | | - raise TypeError("issuer must be an X509 instance") |
843 | | - ctx.issuer_cert = issuer._x509 |
844 | | - if subject is not None: |
845 | | - if not isinstance(subject, X509): |
846 | | - raise TypeError("subject must be an X509 instance") |
847 | | - ctx.subject_cert = subject._x509 |
848 | | - |
849 | | - if critical: |
850 | | - # There are other OpenSSL APIs which would let us pass in critical |
851 | | - # separately, but they're harder to use, and since value is already |
852 | | - # a pile of crappy junk smuggling a ton of utterly important |
853 | | - # structured data, what's the point of trying to avoid nasty stuff |
854 | | - # with strings? (However, X509V3_EXT_i2d in particular seems like |
855 | | - # it would be a better API to invoke. I do not know where to get |
856 | | - # the ext_struc it desires for its last parameter, though.) |
857 | | - value = b"critical," + value |
858 | | - |
859 | | - extension = _lib.X509V3_EXT_nconf(_ffi.NULL, ctx, type_name, value) |
860 | | - if extension == _ffi.NULL: |
861 | | - _raise_current_error() |
862 | | - self._extension = _ffi.gc(extension, _lib.X509_EXTENSION_free) |
863 | | - |
864 | | - @property |
865 | | - def _nid(self) -> Any: |
866 | | - return _lib.OBJ_obj2nid( |
867 | | - _lib.X509_EXTENSION_get_object(self._extension) |
868 | | - ) |
869 | | - |
870 | | - _prefixes: typing.ClassVar[dict[int, str]] = { |
871 | | - _lib.GEN_EMAIL: "email", |
872 | | - _lib.GEN_DNS: "DNS", |
873 | | - _lib.GEN_URI: "URI", |
874 | | - } |
875 | | - |
876 | | - def _subjectAltNameString(self) -> str: |
877 | | - names = _ffi.cast( |
878 | | - "GENERAL_NAMES*", _lib.X509V3_EXT_d2i(self._extension) |
879 | | - ) |
880 | | - |
881 | | - names = _ffi.gc(names, _lib.GENERAL_NAMES_free) |
882 | | - parts = [] |
883 | | - for i in range(_lib.sk_GENERAL_NAME_num(names)): |
884 | | - name = _lib.sk_GENERAL_NAME_value(names, i) |
885 | | - try: |
886 | | - label = self._prefixes[name.type] |
887 | | - except KeyError: |
888 | | - bio = _new_mem_buf() |
889 | | - _lib.GENERAL_NAME_print(bio, name) |
890 | | - parts.append(_bio_to_string(bio).decode("utf-8")) |
891 | | - else: |
892 | | - value = _ffi.buffer(name.d.ia5.data, name.d.ia5.length)[ |
893 | | - : |
894 | | - ].decode("utf-8") |
895 | | - parts.append(label + ":" + value) |
896 | | - return ", ".join(parts) |
897 | | - |
898 | | - def __str__(self) -> str: |
899 | | - """ |
900 | | - :return: a nice text representation of the extension |
901 | | - """ |
902 | | - if _lib.NID_subject_alt_name == self._nid: |
903 | | - return self._subjectAltNameString() |
904 | | - |
905 | | - bio = _new_mem_buf() |
906 | | - print_result = _lib.X509V3_EXT_print(bio, self._extension, 0, 0) |
907 | | - _openssl_assert(print_result != 0) |
908 | | - |
909 | | - return _bio_to_string(bio).decode("utf-8") |
910 | | - |
911 | | - def get_critical(self) -> bool: |
912 | | - """ |
913 | | - Returns the critical field of this X.509 extension. |
914 | | -
|
915 | | - :return: The critical field. |
916 | | - """ |
917 | | - return _lib.X509_EXTENSION_get_critical(self._extension) |
918 | | - |
919 | | - def get_short_name(self) -> bytes: |
920 | | - """ |
921 | | - Returns the short type name of this X.509 extension. |
922 | | -
|
923 | | - The result is a byte string such as :py:const:`b"basicConstraints"`. |
924 | | -
|
925 | | - :return: The short type name. |
926 | | - :rtype: :py:data:`bytes` |
927 | | -
|
928 | | - .. versionadded:: 0.12 |
929 | | - """ |
930 | | - obj = _lib.X509_EXTENSION_get_object(self._extension) |
931 | | - nid = _lib.OBJ_obj2nid(obj) |
932 | | - # OpenSSL 3.1.0 has a bug where nid2sn returns NULL for NIDs that |
933 | | - # previously returned UNDEF. This is a workaround for that issue. |
934 | | - # https://github.com/openssl/openssl/commit/908ba3ed9adbb3df90f76 |
935 | | - buf = _lib.OBJ_nid2sn(nid) |
936 | | - if buf != _ffi.NULL: |
937 | | - return _ffi.string(buf) |
938 | | - else: |
939 | | - return b"UNDEF" |
940 | | - |
941 | | - def get_data(self) -> bytes: |
942 | | - """ |
943 | | - Returns the data of the X509 extension, encoded as ASN.1. |
944 | | -
|
945 | | - :return: The ASN.1 encoded data of this X509 extension. |
946 | | - :rtype: :py:data:`bytes` |
947 | | -
|
948 | | - .. versionadded:: 0.12 |
949 | | - """ |
950 | | - octet_result = _lib.X509_EXTENSION_get_data(self._extension) |
951 | | - string_result = _ffi.cast("ASN1_STRING*", octet_result) |
952 | | - char_result = _lib.ASN1_STRING_get0_data(string_result) |
953 | | - result_length = _lib.ASN1_STRING_length(string_result) |
954 | | - return _ffi.buffer(char_result, result_length)[:] |
955 | | - |
956 | | - |
957 | | -_X509ExtensionInternal = X509Extension |
958 | | -utils.deprecated( |
959 | | - X509Extension, |
960 | | - __name__, |
961 | | - ( |
962 | | - "X509Extension support in pyOpenSSL is deprecated. You should use the " |
963 | | - "APIs in cryptography." |
964 | | - ), |
965 | | - DeprecationWarning, |
966 | | - name="X509Extension", |
967 | | -) |
968 | | - |
969 | | - |
970 | 784 | class X509Req: |
971 | 785 | """ |
972 | 786 | An X.509 certificate signing requests. |
@@ -1092,79 +906,6 @@ def get_subject(self) -> X509Name: |
1092 | 906 |
|
1093 | 907 | return name |
1094 | 908 |
|
1095 | | - def add_extensions( |
1096 | | - self, extensions: Iterable[_X509ExtensionInternal] |
1097 | | - ) -> None: |
1098 | | - """ |
1099 | | - Add extensions to the certificate signing request. |
1100 | | -
|
1101 | | - :param extensions: The X.509 extensions to add. |
1102 | | - :type extensions: iterable of :py:class:`X509Extension` |
1103 | | - :return: ``None`` |
1104 | | - """ |
1105 | | - warnings.warn( |
1106 | | - ( |
1107 | | - "This API is deprecated and will be removed in a future " |
1108 | | - "version of pyOpenSSL. You should use pyca/cryptography's " |
1109 | | - "X.509 APIs instead." |
1110 | | - ), |
1111 | | - DeprecationWarning, |
1112 | | - stacklevel=2, |
1113 | | - ) |
1114 | | - |
1115 | | - stack = _lib.sk_X509_EXTENSION_new_null() |
1116 | | - _openssl_assert(stack != _ffi.NULL) |
1117 | | - |
1118 | | - stack = _ffi.gc(stack, _lib.sk_X509_EXTENSION_free) |
1119 | | - |
1120 | | - for ext in extensions: |
1121 | | - if not isinstance(ext, _X509ExtensionInternal): |
1122 | | - raise ValueError("One of the elements is not an X509Extension") |
1123 | | - |
1124 | | - # TODO push can fail (here and elsewhere) |
1125 | | - _lib.sk_X509_EXTENSION_push(stack, ext._extension) |
1126 | | - |
1127 | | - add_result = _lib.X509_REQ_add_extensions(self._req, stack) |
1128 | | - _openssl_assert(add_result == 1) |
1129 | | - |
1130 | | - def get_extensions(self) -> list[_X509ExtensionInternal]: |
1131 | | - """ |
1132 | | - Get X.509 extensions in the certificate signing request. |
1133 | | -
|
1134 | | - :return: The X.509 extensions in this request. |
1135 | | - :rtype: :py:class:`list` of :py:class:`X509Extension` objects. |
1136 | | -
|
1137 | | - .. versionadded:: 0.15 |
1138 | | - """ |
1139 | | - warnings.warn( |
1140 | | - ( |
1141 | | - "This API is deprecated and will be removed in a future " |
1142 | | - "version of pyOpenSSL. You should use pyca/cryptography's " |
1143 | | - "X.509 APIs instead." |
1144 | | - ), |
1145 | | - DeprecationWarning, |
1146 | | - stacklevel=2, |
1147 | | - ) |
1148 | | - |
1149 | | - exts = [] |
1150 | | - native_exts_obj = _lib.X509_REQ_get_extensions(self._req) |
1151 | | - native_exts_obj = _ffi.gc( |
1152 | | - native_exts_obj, |
1153 | | - lambda x: _lib.sk_X509_EXTENSION_pop_free( |
1154 | | - x, |
1155 | | - _ffi.addressof(_lib._original_lib, "X509_EXTENSION_free"), |
1156 | | - ), |
1157 | | - ) |
1158 | | - |
1159 | | - for i in range(_lib.sk_X509_EXTENSION_num(native_exts_obj)): |
1160 | | - ext = _X509ExtensionInternal.__new__(_X509ExtensionInternal) |
1161 | | - extension = _lib.X509_EXTENSION_dup( |
1162 | | - _lib.sk_X509_EXTENSION_value(native_exts_obj, i) |
1163 | | - ) |
1164 | | - ext._extension = _ffi.gc(extension, _lib.X509_EXTENSION_free) |
1165 | | - exts.append(ext) |
1166 | | - return exts |
1167 | | - |
1168 | 909 | def sign(self, pkey: PKey, digest: str) -> None: |
1169 | 910 | """ |
1170 | 911 | Sign the certificate signing request with this key and digest type. |
@@ -1656,66 +1397,6 @@ def get_extension_count(self) -> int: |
1656 | 1397 | """ |
1657 | 1398 | return _lib.X509_get_ext_count(self._x509) |
1658 | 1399 |
|
1659 | | - def add_extensions( |
1660 | | - self, extensions: Iterable[_X509ExtensionInternal] |
1661 | | - ) -> None: |
1662 | | - """ |
1663 | | - Add extensions to the certificate. |
1664 | | -
|
1665 | | - :param extensions: The extensions to add. |
1666 | | - :type extensions: An iterable of :py:class:`X509Extension` objects. |
1667 | | - :return: ``None`` |
1668 | | - """ |
1669 | | - warnings.warn( |
1670 | | - ( |
1671 | | - "This API is deprecated and will be removed in a future " |
1672 | | - "version of pyOpenSSL. You should use pyca/cryptography's " |
1673 | | - "X.509 APIs instead." |
1674 | | - ), |
1675 | | - DeprecationWarning, |
1676 | | - stacklevel=2, |
1677 | | - ) |
1678 | | - |
1679 | | - for ext in extensions: |
1680 | | - if not isinstance(ext, _X509ExtensionInternal): |
1681 | | - raise ValueError("One of the elements is not an X509Extension") |
1682 | | - |
1683 | | - add_result = _lib.X509_add_ext(self._x509, ext._extension, -1) |
1684 | | - _openssl_assert(add_result == 1) |
1685 | | - |
1686 | | - def get_extension(self, index: int) -> _X509ExtensionInternal: |
1687 | | - """ |
1688 | | - Get a specific extension of the certificate by index. |
1689 | | -
|
1690 | | - Extensions on a certificate are kept in order. The index |
1691 | | - parameter selects which extension will be returned. |
1692 | | -
|
1693 | | - :param int index: The index of the extension to retrieve. |
1694 | | - :return: The extension at the specified index. |
1695 | | - :rtype: :py:class:`X509Extension` |
1696 | | - :raises IndexError: If the extension index was out of bounds. |
1697 | | -
|
1698 | | - .. versionadded:: 0.12 |
1699 | | - """ |
1700 | | - warnings.warn( |
1701 | | - ( |
1702 | | - "This API is deprecated and will be removed in a future " |
1703 | | - "version of pyOpenSSL. You should use pyca/cryptography's " |
1704 | | - "X.509 APIs instead." |
1705 | | - ), |
1706 | | - DeprecationWarning, |
1707 | | - stacklevel=2, |
1708 | | - ) |
1709 | | - |
1710 | | - ext = _X509ExtensionInternal.__new__(_X509ExtensionInternal) |
1711 | | - ext._extension = _lib.X509_get_ext(self._x509, index) |
1712 | | - if ext._extension == _ffi.NULL: |
1713 | | - raise IndexError("extension index out of bounds") |
1714 | | - |
1715 | | - extension = _lib.X509_EXTENSION_dup(ext._extension) |
1716 | | - ext._extension = _ffi.gc(extension, _lib.X509_EXTENSION_free) |
1717 | | - return ext |
1718 | | - |
1719 | 1400 |
|
1720 | 1401 | class X509StoreFlags: |
1721 | 1402 | """ |
|
0 commit comments