Welcome to mirror list, hosted at ThFree Co, Russian Federation.

dev.gajim.org/gajim/gajim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwurstsalat <mailtrash@posteo.de>2022-11-11 20:59:42 +0300
committerPhilipp Hörist <philipp@hoerist.com>2022-11-27 22:35:20 +0300
commit8da84be4c16bf26c34fa48dc22e520b684895ab4 (patch)
treeb18330d63ef0e05449a5bcbc79fb0005dc3a2a9b
parentbd8b229b474adb038903b65a373c910845af3062 (diff)
refactor: CertificateBox: Use cryptography module for certificate details
-rw-r--r--gajim/common/helpers.py12
-rw-r--r--gajim/gtk/certificate_dialog.py74
-rw-r--r--test/gtk/certificate_dialog.py12
-rw-r--r--test/gtk/util.py11
4 files changed, 62 insertions, 47 deletions
diff --git a/gajim/common/helpers.py b/gajim/common/helpers.py
index 575814d96..30b4cb8f7 100644
--- a/gajim/common/helpers.py
+++ b/gajim/common/helpers.py
@@ -62,6 +62,9 @@ from pathlib import Path
from packaging.version import Version as V
import unicodedata
+from cryptography import x509
+from cryptography.hazmat.backends import default_backend
+
from nbxmpp.namespaces import Namespace
from nbxmpp.const import Role
from nbxmpp.const import Chatstate
@@ -75,9 +78,6 @@ from nbxmpp.protocol import JID
from nbxmpp.protocol import InvalidJid
from nbxmpp.protocol import Iq
-from OpenSSL.crypto import X509, load_certificate
-from OpenSSL.crypto import FILETYPE_PEM
-
from gi.repository import Gio
from gi.repository import GLib
from gi.repository import GObject
@@ -1429,8 +1429,10 @@ def load_file_async(path: Path,
file.load_contents_async(None, _on_load_finished)
-def convert_gio_to_openssl_cert(cert: Gio.TlsCertificate) -> X509:
- return load_certificate(FILETYPE_PEM, cert.props.certificate_pem.encode())
+def get_x509_cert_from_gio_cert(cert: Gio.TlsCertificate) -> x509.Certificate:
+ glib_bytes = GLib.ByteArray.free_to_bytes(cert.props.certificate)
+ return x509.load_der_x509_certificate(
+ glib_bytes.get_data(), default_backend())
def get_custom_host(account: str) -> Optional[tuple[str,
diff --git a/gajim/gtk/certificate_dialog.py b/gajim/gtk/certificate_dialog.py
index 1a1469caf..0c2ca8f87 100644
--- a/gajim/gtk/certificate_dialog.py
+++ b/gajim/gtk/certificate_dialog.py
@@ -12,14 +12,14 @@
# You should have received a copy of the GNU General Public License
# along with Gajim. If not, see <http://www.gnu.org/licenses/>.
-from datetime import datetime
+from cryptography.hazmat.primitives import hashes
from gi.repository import Gdk
from gi.repository import Gio
from gi.repository import Gtk
from gajim.common import app
-from gajim.common.helpers import convert_gio_to_openssl_cert
+from gajim.common.helpers import get_x509_cert_from_gio_cert
from gajim.common.i18n import _
from .builder import get_builder
@@ -55,47 +55,55 @@ class CertificateDialog(Gtk.ApplicationWindow):
class CertificateBox(Gtk.Box):
- def __init__(self, account: str, cert: Gio.TlsCertificate) -> None:
+ def __init__(self, account: str, certificate: Gio.TlsCertificate) -> None:
Gtk.Box.__init__(self)
self._ui = get_builder('certificate.ui')
-
- certificate = convert_gio_to_openssl_cert(cert)
-
- issuer = certificate.get_issuer()
- subject = certificate.get_subject()
-
self._headline = _('Certificate for \n%s') % account
- self._it_common_name = subject.commonName or ''
- self._it_organization = subject.organizationName or ''
- self._it_org_unit = subject.organizationalUnitName or ''
- it_serial_no = str(certificate.get_serial_number())
+
+ cert = get_x509_cert_from_gio_cert(certificate)
+
+ self._it_common_name = ''
+ self._it_organization = ''
+ self._it_org_unit = ''
+ for attribute in cert.subject:
+ # See https://datatracker.ietf.org/doc/html/rfc4514.html
+ dotted_string = attribute.oid.dotted_string
+ if dotted_string == '2.5.4.3':
+ self._ib_common_name = str(attribute.value)
+ if dotted_string == '2.5.4.10':
+ self._ib_organization = str(attribute.value)
+ if dotted_string == '2.5.4.11':
+ self._ib_org_unit = str(attribute.value)
+
+ it_serial_no = str(cert.serial_number)
it_serial_no_half = int(len(it_serial_no) / 2)
self._it_serial_number = '%s\n%s' % (
it_serial_no[:it_serial_no_half],
it_serial_no[it_serial_no_half:])
- self._ib_common_name = issuer.commonName or ''
- self._ib_organization = issuer.organizationName or ''
- self._ib_org_unit = issuer.organizationalUnitName or ''
-
- before = certificate.get_notBefore()
- if before is None:
- self._issued = ''
- else:
- issued = datetime.strptime(before.decode('ascii'), '%Y%m%d%H%M%SZ')
- self._issued = issued.strftime('%c %Z')
-
- after = certificate.get_notAfter()
- if after is None:
- self._expires = ''
- else:
- expires = datetime.strptime(after.decode('ascii'), '%Y%m%d%H%M%SZ')
- self._expires = expires.strftime('%c %Z')
-
- sha1 = certificate.digest('sha1').decode('utf-8')
+
+ self._ib_common_name = ''
+ self._ib_organization = ''
+ self._ib_org_unit = ''
+ for attribute in cert.issuer:
+ # See https://datatracker.ietf.org/doc/html/rfc4514.html
+ dotted_string = attribute.oid.dotted_string
+ if dotted_string == '2.5.4.3':
+ self._ib_common_name = str(attribute.value)
+ if dotted_string == '2.5.4.10':
+ self._ib_organization = str(attribute.value)
+ if dotted_string == '2.5.4.11':
+ self._ib_org_unit = str(attribute.value)
+
+ self._issued = cert.not_valid_before.strftime('%c %Z')
+ self._expires = cert.not_valid_after.strftime('%c %Z')
+
+ sha1_bytes = cert.fingerprint(hashes.SHA1())
+ sha1 = ':'.join(f'{b:02X}' for b in sha1_bytes)
self._sha1 = '%s\n%s' % (sha1[:29], sha1[30:])
- sha256 = certificate.digest('sha256').decode('utf-8')
+ sha256_bytes = cert.fingerprint(hashes.SHA256())
+ sha256 = ':'.join(f'{b:02X}' for b in sha256_bytes)
self._sha256 = '%s\n%s\n%s\n%s' % (
sha256[:23], sha256[24:47], sha256[48:71], sha256[72:])
diff --git a/test/gtk/certificate_dialog.py b/test/gtk/certificate_dialog.py
index 534fe5500..48faa7cd7 100644
--- a/test/gtk/certificate_dialog.py
+++ b/test/gtk/certificate_dialog.py
@@ -1,15 +1,15 @@
import gi
+gi.require_version('Gio', '2.0')
gi.require_version('Gtk', '3.0')
+from gi.repository import Gio
from gi.repository import Gtk
-import OpenSSL
-
from gajim import gui
gui.init('gtk')
from test.gtk import util
from gajim.common.const import CSSPriority
-from gajim.gui.dialogs import CertificateDialog
+from gajim.gui.certificate_dialog import CertificateDialog
util.load_style('gajim.css', CSSPriority.APPLICATION)
@@ -47,8 +47,8 @@ ejsJoYkpvcaiaLAyVymTY/n/oM2oQpv5Mqjit+18RB9c2P+ifH5iDKC/jTKn4NNz
8xSTlUlCBTCozjzscZVeVDIojmejWclT
-----END CERTIFICATE-----'''
-cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, cert)
-win = CertificateDialog(None, 'testacc', cert)
-win.connect("destroy", Gtk.main_quit)
+gio_cert = Gio.TlsCertificate.new_from_pem(cert, -1)
+win = CertificateDialog(None, 'testacc', gio_cert)
+win.connect('destroy', Gtk.main_quit)
win.show_all()
Gtk.main()
diff --git a/test/gtk/util.py b/test/gtk/util.py
index 9ecd50ece..06a949c5e 100644
--- a/test/gtk/util.py
+++ b/test/gtk/util.py
@@ -3,12 +3,15 @@ from pathlib import Path
from gi.repository import Gdk
from gi.repository import Gtk
+from gajim.common.const import CSSPriority
-def get_gajim_dir():
+
+def get_gajim_dir() -> Path:
gajim_path = Path(__file__) / '..' / '..' / '..' / 'gajim'
return gajim_path.resolve()
-def load_style(filename, priority):
+
+def load_style(filename: str, priority: CSSPriority) -> None:
path = get_gajim_dir() / 'data' / 'style' / filename
try:
with open(str(path), 'r', encoding='utf8') as file:
@@ -18,6 +21,8 @@ def load_style(filename, priority):
return
provider = Gtk.CssProvider()
provider.load_from_data(bytes(css.encode('utf-8')))
- Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(),
+ screen = Gdk.Screen.get_default()
+ assert screen is not None
+ Gtk.StyleContext.add_provider_for_screen(screen,
provider,
priority)