# This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. import re from firefox_puppeteer.base import BaseLib from firefox_puppeteer.errors import NoCertificateError class Security(BaseLib): """Low-level access to security (SSL, TLS) related information.""" # Security related helpers # def get_address_from_certificate(self, certificate): """Retrieves the address of the organization from the certificate information. The returned address may be `None` in case of no address found, or a dictionary with the following entries: `city`, `country`, `postal_code`, `state`, `street`. :param certificate: A JSON object representing the certificate, which can usually be retrieved via the current tab: `self.browser.tabbar.selected_tab.certificate`. :returns: Address details as dictionary """ regex = re.compile('.*?L=(?P.+?),ST=(?P.+?),C=(?P.+?)' ',postalCode=(?P.+?),STREET=(?P.+?)' ',serial') results = regex.search(certificate['subjectName']) return results.groupdict() if results else results def get_certificate_for_page(self, tab_element): """The SSL certificate assiciated with the loaded web page in the given tab. :param tab_element: The inner tab DOM element. :returns: Certificate details as JSON object. """ cert = self.marionette.execute_script(""" var securityUI = arguments[0].linkedBrowser.securityUI; var status = securityUI.QueryInterface(Components.interfaces.nsISSLStatusProvider) .SSLStatus; return status ? status.serverCert : null; """, script_args=[tab_element]) uri = self.marionette.execute_script(""" return arguments[0].linkedBrowser.currentURI.spec; """, script_args=[tab_element]) if cert is None: raise NoCertificateError('No certificate found for "{}"'.format(uri)) return cert def get_domain_from_common_name(self, common_name): """Retrieves the domain associated with a page's security certificate from the common name. :param certificate: A string containing the certificate's common name, which can usually be retrieved like so: `certificate['commonName']`. :returns: Domain as string """ return self.marionette.execute_script(""" return Services.eTLD.getBaseDomainFromHost(arguments[0]); """, script_args=[common_name])