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