Merge lp:~mandel/ubuntu-sso-client/pinned-certs into lp:ubuntu-sso-client

Proposed by Manuel de la Peña
Status: Rejected
Rejected by: Manuel de la Peña
Proposed branch: lp:~mandel/ubuntu-sso-client/pinned-certs
Merge into: lp:ubuntu-sso-client
Prerequisite: lp:~mandel/ubuntu-sso-client/libsoup-ssl-dialog
Diff against target: 480 lines (+304/-51)
6 files modified
ubuntu_sso/utils/webclient/common.py (+23/-10)
ubuntu_sso/utils/webclient/libsoup.py (+3/-13)
ubuntu_sso/utils/webclient/qtnetwork.py (+2/-22)
ubuntu_sso/utils/webclient/ssl_certs.py (+105/-0)
ubuntu_sso/utils/webclient/tests/test_ssl_certs.py (+151/-0)
ubuntu_sso/utils/webclient/tests/test_webclient.py (+20/-6)
To merge this branch: bzr merge lp:~mandel/ubuntu-sso-client/pinned-certs
Reviewer Review Type Date Requested Status
Manuel de la Peña (community) Disapprove
dobey (community) Approve
Roberto Alsina (community) Approve
Review via email: mp+97486@code.launchpad.net

Commit message

- Added a ssl cert vault that will allow to remember pinned ssl certificates (LP: #955339)

Description of the change

- Added a ssl cert vault that will allow to remember pinned ssl certificates (LP: #955339)

To post a comment you must log in.
Revision history for this message
Roberto Alsina (ralsina) wrote :

Looks good to me, but testing this IRL is a pain.

review: Approve
Revision history for this message
dobey (dobey) wrote :

Looks ok.

review: Approve
Revision history for this message
Manuel de la Peña (mandel) wrote :

Rejecting since we won't use this code.

review: Disapprove

Unmerged revisions

952. By Manuel de la Peña

Remove unused function.

951. By Manuel de la Peña

Merged libsoup-ssl-dialog into pinned-certs.

950. By Manuel de la Peña

Merged libsoup-ssl-dialog into pinned-certs.

949. By Manuel de la Peña

Added the required code to store the pinned certificates in order to not promp the ssl dialog constantly.

948. By Manuel de la Peña

Pass the cert pem from the child WebClient implementations to the base class.

947. By Manuel de la Peña

Reduced diff size.

946. By Manuel de la Peña

Reduced diff size.

945. By Manuel de la Peña

Merged with trunk.

944. By Manuel de la Peña

Added the required code to let the libsoup webclient implementation deal with ssl cert errors.

943. By Manuel de la Peña

Made changes to the tests so that they work correctly.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'ubuntu_sso/utils/webclient/common.py'
--- ubuntu_sso/utils/webclient/common.py 2012-03-15 11:43:19 +0000
+++ ubuntu_sso/utils/webclient/common.py 2012-03-15 11:43:19 +0000
@@ -21,6 +21,7 @@
2121
22from httplib2 import iri2uri22from httplib2 import iri2uri
23from oauth import oauth23from oauth import oauth
24from OpenSSL.crypto import load_certificate, FILETYPE_PEM
24from twisted.internet import defer25from twisted.internet import defer
25from urlparse import urlparse26from urlparse import urlparse
2627
@@ -28,6 +29,8 @@
28from ubuntu_sso.logger import setup_logging29from ubuntu_sso.logger import setup_logging
29from ubuntu_sso.utils.runner import spawn_program30from ubuntu_sso.utils.runner import spawn_program
30from ubuntu_sso.utils.ui import SSL_DETAILS_TEMPLATE31from ubuntu_sso.utils.ui import SSL_DETAILS_TEMPLATE
32from ubuntu_sso.utils.ui import SSL_DETAILS_TEMPLATE
33from ubuntu_sso.utils.webclient.ssl_certs import PinnedSSLCertsVault
31from ubuntu_sso.utils.webclient.timestamp import TimestampChecker34from ubuntu_sso.utils.webclient.timestamp import TimestampChecker
3235
33SSL_DIALOG = 'ubuntu-sso-ssl-certificate-qt'36SSL_DIALOG = 'ubuntu-sso-ssl-certificate-qt'
@@ -109,6 +112,7 @@
109 self.proxy_username = None112 self.proxy_username = None
110 self.proxy_password = None113 self.proxy_password = None
111 self.oauth_sign_plain = oauth_sign_plain114 self.oauth_sign_plain = oauth_sign_plain
115 self.ssl_vault = PinnedSSLCertsVault()
112116
113 def request(self, iri, method="GET", extra_headers=None,117 def request(self, iri, method="GET", extra_headers=None,
114 oauth_credentials=None, post_content=None):118 oauth_credentials=None, post_content=None):
@@ -238,9 +242,16 @@
238 return_code)242 return_code)
239 defer.returnValue(False)243 defer.returnValue(False)
240244
241 def format_ssl_details(self, details):245 def get_ssl_subject_details(self, cert):
242 """Return a formatted string with the details."""246 """Return a formatted string with the details."""
243 return SSL_DETAILS_TEMPLATE % details247 cert_subject = cert.get_subject()
248 details = dict(organization=cert_subject.O,
249 common_name=cert_subject.CN,
250 locality_name=cert_subject.L,
251 unit=cert_subject.OU,
252 country_name=cert_subject.C,
253 state_name=cert_subject.ST)
254 return details
244255
245 def _launch_ssl_dialog(self, domain, details):256 def _launch_ssl_dialog(self, domain, details):
246 """Launch a dialog used to approve the ssl cert."""257 """Launch a dialog used to approve the ssl cert."""
@@ -252,16 +263,18 @@
252 '--appname', self.appname)263 '--appname', self.appname)
253 return spawn_program(args)264 return spawn_program(args)
254265
255 def _was_ssl_accepted(self, cert_details):
256 """Return if the cert was already accepted."""
257 # TODO: Ensure that we look at pinned certs in a following branch
258 return False
259
260 @defer.inlineCallbacks266 @defer.inlineCallbacks
261 def request_ssl_cert_approval(self, domain, details):267 def request_ssl_cert_approval(self, cert_pem):
262 """Request the user for ssl approval."""268 """Request the user for ssl approval."""
263 if self._was_ssl_accepted(details):269 cert = load_certificate(FILETYPE_PEM, cert_pem)
270 if self.ssl_vault.is_certificate_pinned(cert):
264 defer.returnValue(True)271 defer.returnValue(True)
265272
266 return_code = yield self._launch_ssl_dialog(domain, details)273 subject_details = self.get_ssl_subject_details(cert)
274 details = SSL_DETAILS_TEMPLATE % subject_details
275 return_code = yield self._launch_ssl_dialog(
276 subject_details['common_name'],
277 details)
278 if return_code == USER_SUCCESS:
279 self.ssl_vault.store_certificate(cert)
267 defer.returnValue(return_code == USER_SUCCESS)280 defer.returnValue(return_code == USER_SUCCESS)
268281
=== modified file 'ubuntu_sso/utils/webclient/libsoup.py'
--- ubuntu_sso/utils/webclient/libsoup.py 2012-03-15 11:43:19 +0000
+++ ubuntu_sso/utils/webclient/libsoup.py 2012-03-15 11:43:19 +0000
@@ -17,7 +17,6 @@
1717
18import httplib18import httplib
1919
20from OpenSSL.crypto import load_certificate, FILETYPE_PEM
21from twisted.internet import defer20from twisted.internet import defer
2221
23from ubuntu_sso.logger import setup_logging22from ubuntu_sso.logger import setup_logging
@@ -67,17 +66,9 @@
67 if message.status_code == httplib.OK:66 if message.status_code == httplib.OK:
68 response = self._get_response(message)67 response = self._get_response(message)
69 if is_ssl and errors.real != 0:68 if is_ssl and errors.real != 0:
70 cert = load_certificate(FILETYPE_PEM,
71 raw_cert.props.certificate_pem)
72 cert_subject = cert.get_subject()
73 ssl_details = dict(organization=cert_subject.O,
74 common_name=cert_subject.CN,
75 locality_name=cert_subject.L,
76 unit=cert_subject.OU,
77 country_name=cert_subject.C,
78 state_name=cert_subject.ST)
79 e = SSLCertError(message.reason_phrase,69 e = SSLCertError(message.reason_phrase,
80 ssl_details=ssl_details, response=response)70 ssl_details=raw_cert.props.certificate_pem,
71 response=response)
81 d.errback(e)72 d.errback(e)
82 else:73 else:
83 d.callback(response)74 d.callback(response)
@@ -136,8 +127,7 @@
136 failure.trap(SSLCertError)127 failure.trap(SSLCertError)
137 logger.debug('SSL cert errors found.')128 logger.debug('SSL cert errors found.')
138 trust_cert = yield self.request_ssl_cert_approval(129 trust_cert = yield self.request_ssl_cert_approval(
139 failure.value.ssl_details['common_name'],130 failure.value.ssl_details)
140 self.format_ssl_details(failure.value.ssl_details))
141 if trust_cert:131 if trust_cert:
142 defer.returnValue(failure.value.response)132 defer.returnValue(failure.value.response)
143133
144134
=== modified file 'ubuntu_sso/utils/webclient/qtnetwork.py'
--- ubuntu_sso/utils/webclient/qtnetwork.py 2012-03-09 12:04:31 +0000
+++ ubuntu_sso/utils/webclient/qtnetwork.py 2012-03-15 11:43:19 +0000
@@ -30,7 +30,6 @@
30 QNetworkProxyFactory,30 QNetworkProxyFactory,
31 QNetworkReply,31 QNetworkReply,
32 QNetworkRequest,32 QNetworkRequest,
33 QSslCertificate,
34)33)
35from twisted.internet import defer34from twisted.internet import defer
3635
@@ -266,31 +265,12 @@
266 exception = WebClientError(error_string, content)265 exception = WebClientError(error_string, content)
267 d.errback(exception)266 d.errback(exception)
268267
269 def _get_certificate_details(self, cert):
270 """Return an string with the details of the certificate."""
271 detail_titles = {QSslCertificate.Organization: 'organization',
272 QSslCertificate.CommonName: 'common_name',
273 QSslCertificate.LocalityName: 'locality_name',
274 QSslCertificate.OrganizationalUnitName: 'unit',
275 QSslCertificate.CountryName: 'country_name',
276 QSslCertificate.StateOrProvinceName: 'state_name'}
277 details = {}
278 for info, title in detail_titles.iteritems():
279 details[title] = str(cert.issuerInfo(info))
280 return self.format_ssl_details(details)
281
282 def _get_certificate_host(self, cert):
283 """Return the host of the cert."""
284 return str(cert.issuerInfo(QSslCertificate.CommonName))
285
286 @defer.inlineCallbacks268 @defer.inlineCallbacks
287 def _handle_ssl_errors(self, reply, errors):269 def _handle_ssl_errors(self, reply, errors):
288 """Handle the case in which we got an ssl error."""270 """Handle the case in which we got an ssl error."""
289 # ask the user if the cer should be trusted271 # ask the user if the cer should be trusted
290 cert = errors[0].certificate()272 cert_pem = errors[0].certificate().toPem()
291 trust_cert = yield self.request_ssl_cert_approval(273 trust_cert = yield self.request_ssl_cert_approval(cert_pem)
292 self._get_certificate_host(cert),
293 self._get_certificate_details(cert))
294 if trust_cert:274 if trust_cert:
295 reply.ignoreSslErrors()275 reply.ignoreSslErrors()
296276
297277
=== added file 'ubuntu_sso/utils/webclient/ssl_certs.py'
--- ubuntu_sso/utils/webclient/ssl_certs.py 1970-01-01 00:00:00 +0000
+++ ubuntu_sso/utils/webclient/ssl_certs.py 2012-03-15 11:43:19 +0000
@@ -0,0 +1,105 @@
1# -*- coding: utf-8 -*-
2#
3# Copyright 2011 Canonical Ltd.
4#
5# This program is free software: you can redistribute it and/or modify it
6# under the terms of the GNU General Public License version 3, as published
7# by the Free Software Foundation.
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranties of
11# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
12# PURPOSE. See the GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program. If not, see <http://www.gnu.org/licenses/>.
16"""Store and retrieve certificates that have been pinned."""
17
18import base64
19import os
20import tempfile
21
22from ubuntu_sso import xdg_base_directory
23from ubuntu_sso.logger import setup_logging
24
25PINNED_CERT_LINE_FORMAT = ('%(domain)s:%(port)s\t%(hash_algorithm)s\t'
26 '%(fingerprint)s\t%(override_type)s\t'
27 '%(serial_number)s\n')
28HTTPS_PORT = 443
29HASH_ALGORITHM = ('sha1', 'OID.2.16.840.1.101.3.4.2.1')
30DEFAULT_OVERRIDE_TYPE = 'MUT'
31PINNED_CERT_DIR = os.path.join(xdg_base_directory.xdg_cache_home, 'sso',
32 'ssl-certs')
33
34logger = setup_logging("ubuntu_sso.utils.webclient.ssl_certs")
35
36
37class PinnedSSLCertsVault(object):
38 """Represents a vault that will store the pinned certs."""
39
40 def __init__(self, certs_path=PINNED_CERT_DIR):
41 """Create a new instance."""
42 self.certs_path = certs_path
43 if not os.path.exists(self.certs_path):
44 os.makedirs(self.certs_path)
45
46 def _get_pinned_certificate_line(self, cert):
47 """Return the line of a pinned cert.
48
49 The following format is used:
50 Fields are separated by a tab character. Each line is terminated
51 by a line feed character (UNIX format).
52
53 1. domainname:port : port 443 for HTTPS (SSL)
54 2. hash algorithm OID:
55 SHA1-256: OID.2.16.840.1.101.3.4.2.1 (most used)
56 SHA-384: OID.2.16.840.1.101.3.4.2.2
57 SHA-512: OID.2.16.840.1.101.3.4.2.3
58 3. Certificate fingerprint using previous hash algorithm
59 4. One or more characters for override type:
60 M : allow mismatches in the hostname
61 U : allow untrusted certs (whether it's self signed cert or
62 a missing or invalid issuer cert)
63 T : allow errors in the validity time, for example, for expired or
64 not yet valid certs
65 5. Certificate's serial number and the issuer name as a base64
66 encoded string
67
68 more details can be found at:
69 https://developer.mozilla.org/En/Cert_override.txt
70 """
71 cert_subject = cert.get_subject()
72 serial_number = '%s@%s' % (cert.get_serial_number(), cert.get_issuer())
73 details = dict(domain=cert_subject.CN,
74 port=HTTPS_PORT,
75 hash_algorithm=HASH_ALGORITHM[1],
76 fingerprint=cert.digest(HASH_ALGORITHM[0]),
77 override_type=DEFAULT_OVERRIDE_TYPE,
78 serial_number=base64.b64encode(serial_number))
79 return PINNED_CERT_LINE_FORMAT % details
80
81 def _get_cert_file_name(self, cert):
82 """Return the file name to use with the cert."""
83 fingerprint = cert.digest(HASH_ALGORITHM[0])
84 return fingerprint.replace(':', '-')
85
86 def store_certificate(self, cert):
87 """Store a new certificate."""
88 _, temp_path = tempfile.mkstemp(prefix='tmp-', dir=self.certs_path)
89 with open(temp_path, 'wb') as fd:
90 fd.write(self._get_pinned_certificate_line(cert))
91 logger.debug('Temp file %s written', temp_path)
92 fingerprint = self._get_cert_file_name(cert)
93 os.rename(temp_path, os.path.join(self.certs_path, fingerprint))
94 logger.debug('Cert with fingerprint %s added.', fingerprint)
95
96 def is_certificate_pinned(self, cert):
97 """Return if a certificate was already pinned."""
98 fingerprint = self._get_cert_file_name(cert)
99 return fingerprint in self.pinned_certificates
100
101 @property
102 def pinned_certificates(self):
103 """Return all the fingerprints of the stored certs."""
104 return [name for name in os.listdir(self.certs_path) if not
105 name.startswith('tmp-')]
0106
=== added file 'ubuntu_sso/utils/webclient/tests/test_ssl_certs.py'
--- ubuntu_sso/utils/webclient/tests/test_ssl_certs.py 1970-01-01 00:00:00 +0000
+++ ubuntu_sso/utils/webclient/tests/test_ssl_certs.py 2012-03-15 11:43:19 +0000
@@ -0,0 +1,151 @@
1# -*- coding: utf-8 -*-
2#
3# Copyright 2011 Canonical Ltd.
4#
5# This program is free software: you can redistribute it and/or modify it
6# under the terms of the GNU General Public License version 3, as published
7# by the Free Software Foundation.
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranties of
11# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
12# PURPOSE. See the GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program. If not, see <http://www.gnu.org/licenses/>.
16"""Tests for the ssl certs operations."""
17
18import os
19import tempfile
20
21from OpenSSL import crypto
22from socket import gethostname
23from twisted.internet import defer, reactor
24from twisted.trial.unittest import TestCase
25
26from ubuntu_sso.utils.webclient import ssl_certs
27
28
29class PinnedSSLCertsVaultTestCase(TestCase):
30 """Test the addition of a new pinned cert."""
31
32 @defer.inlineCallbacks
33 def setUp(self):
34 """Set the diff tests."""
35 yield super(PinnedSSLCertsVaultTestCase, self).setUp()
36 self.cert_details = dict(organization='Canonical',
37 common_name=gethostname(),
38 locality_name='London',
39 unit='Ubuntu One',
40 country_name='UK',
41 state_name='London',)
42 self.cert = self._generate_cert(self.cert_details)
43
44 self.certs_path = self.mktemp()
45 os.mkdir(self.certs_path)
46 self.vault = ssl_certs.PinnedSSLCertsVault(self.certs_path)
47
48 def _generate_cert(self, cert_details):
49 """Return a cert using the given details."""
50 # create a key pair
51 key = crypto.PKey()
52 key.generate_key(crypto.TYPE_RSA, 1024)
53
54 # create a self-signed cert
55 cert = crypto.X509()
56 cert.get_subject().C = cert_details['country_name']
57 cert.get_subject().ST = cert_details['state_name']
58 cert.get_subject().L = cert_details['locality_name']
59 cert.get_subject().O = cert_details['organization']
60 cert.get_subject().OU = cert_details['unit']
61 cert.get_subject().CN = cert_details['common_name']
62 cert.set_serial_number(1000)
63 cert.gmtime_adj_notBefore(0)
64 cert.gmtime_adj_notAfter(10 * 365 * 24 * 60 * 60)
65 cert.set_issuer(cert.get_subject())
66 cert.set_pubkey(key)
67 cert.sign(key, 'sha1')
68
69 return cert
70
71 def test_missing_dir(self):
72 """Test addind a pinned cert when the dir is missing."""
73 os.rmdir(self.certs_path)
74 self.vault = ssl_certs.PinnedSSLCertsVault(self.certs_path)
75 self.assertTrue(os.path.exists(self.certs_path))
76
77 def test_pinned_certificates(self):
78 """Test getting the list of pinned certificates."""
79 # create number of certs and ensure that the list is there.
80 added = []
81
82 for index in (1, 2, 3):
83 cert_details = self.cert_details.copy()
84 cert_details['common_name'] = \
85 cert_details['common_name'] + str(index)
86 cert = self._generate_cert(cert_details)
87 self.vault.store_certificate(cert)
88 added.append(
89 cert.digest(ssl_certs.HASH_ALGORITHM[0]).replace(':', '-'))
90
91 for fingerprint in added:
92 self.assertIn(fingerprint, self.vault.pinned_certificates)
93
94 def test_pinned_certificates_temp_files(self):
95 """Test getting the list of pinned certificates."""
96 # create a number of tmp files and assert that they are not returned.
97 tempfiles = []
98 added = []
99
100 for index in (1, 2, 3):
101 _, temp_path = tempfile.mkstemp(prefix='tmp-', dir=self.certs_path)
102 with open(temp_path, 'w') as fd:
103 fd.write("I'm a test!")
104 tempfiles.append(temp_path)
105
106 for index in (1, 2, 3):
107 cert_details = self.cert_details.copy()
108 cert_details['common_name'] = \
109 cert_details['common_name'] + str(index)
110 cert = self._generate_cert(cert_details)
111 self.vault.store_certificate(cert)
112 added.append(
113 cert.digest(ssl_certs.HASH_ALGORITHM[0]).replace(':', '-'))
114
115 for fingerprint in added:
116 self.assertIn(fingerprint, self.vault.pinned_certificates)
117
118 for temp in tempfiles:
119 self.assertNotIn(temp, self.vault.pinned_certificates)
120
121 def test_adding_certificated(self):
122 """Test adding a new certificate."""
123 self.vault.store_certificate(self.cert)
124 fingerprint = self.cert.digest(
125 ssl_certs.HASH_ALGORITHM[0]).replace(':', '-')
126 self.assertIn(fingerprint, os.listdir(self.certs_path))
127
128 def _assert_added(self):
129 """Assert the addition with multiple threads."""
130 vault = ssl_certs.PinnedSSLCertsVault(self.certs_path)
131 vault.store_certificate(self.cert)
132 fingerprint = self.cert.digest(
133 ssl_certs.HASH_ALGORITHM[0]).replace(':', '-')
134 self.assertIn(fingerprint, vault.pinned_certificates)
135 self.assertIn(fingerprint, os.listdir(self.certs_path))
136
137 def test_stepping_on_each_other(self):
138 """Test using several vaults in threads."""
139 # pylint: disable=E1101
140 for _ in (1, 2, 3, 4, 5):
141 reactor.callInThread(self._assert_added)
142 # pylint: enable=E1101
143
144 def test_get_cert_filename(self):
145 """Assert that the filename is correct."""
146 expected = self.cert.digest(
147 ssl_certs.HASH_ALGORITHM[0]).replace(':', '-')
148 # pylint: disable=W0212
149 filename = self.vault._get_cert_file_name(self.cert)
150 # pylint: enable=W0212
151 self.assertEqual(expected, filename)
0152
=== modified file 'ubuntu_sso/utils/webclient/tests/test_webclient.py'
--- ubuntu_sso/utils/webclient/tests/test_webclient.py 2012-03-15 11:43:19 +0000
+++ ubuntu_sso/utils/webclient/tests/test_webclient.py 2012-03-15 11:43:19 +0000
@@ -892,7 +892,7 @@
892 with open(key_path, 'wt') as fd:892 with open(key_path, 'wt') as fd:
893 fd.write(crypto.dump_privatekey(crypto.FILETYPE_PEM, key))893 fd.write(crypto.dump_privatekey(crypto.FILETYPE_PEM, key))
894894
895 return dict(key=key_path, cert=cert_path)895 return dict(key=key_path, cert=cert_path, cert_info=cert)
896896
897897
898class CorrectProxyTestCase(BaseSSLTestCase):898class CorrectProxyTestCase(BaseSSLTestCase):
@@ -1012,6 +1012,8 @@
1012 details = SSL_DETAILS_TEMPLATE % self.cert_details1012 details = SSL_DETAILS_TEMPLATE % self.cert_details
1013 self.assertIn(('_launch_ssl_dialog', gethostname(), details),1013 self.assertIn(('_launch_ssl_dialog', gethostname(), details),
1014 self.called)1014 self.called)
1015 self.assertTrue(self.wc.ssl_vault.is_certificate_pinned(
1016 self.ssl_settings['cert_info']))
10151017
1016 def test_ssl_fail_dialog_user_accepts(self):1018 def test_ssl_fail_dialog_user_accepts(self):
1017 """Test showing the dialog and accepting."""1019 """Test showing the dialog and accepting."""
@@ -1026,12 +1028,24 @@
1026 """Test showing the dialog and rejecting."""1028 """Test showing the dialog and rejecting."""
1027 self.failUnlessFailure(self.wc.request(self.base_iri + SIMPLERESOURCE),1029 self.failUnlessFailure(self.wc.request(self.base_iri + SIMPLERESOURCE),
1028 webclient.WebClientError)1030 webclient.WebClientError)
10291031 # assert the cert was not pinned
1030 def test_format_ssl_details(self):1032 self.assertFalse(self.wc.ssl_vault.is_certificate_pinned(
1033 self.ssl_settings['cert_info']))
1034
1035 @defer.inlineCallbacks
1036 def test_ssl_fail_pinned_cert(self):
1037 """Test when the cert is pinned."""
1038 self.patch(self.wc.ssl_vault, 'is_certificate_pinned', lambda _: True)
1039 result = yield self.wc.request(self.base_ssl_iri + SIMPLERESOURCE)
1040 details = SSL_DETAILS_TEMPLATE % self.cert_details
1041 self.assertNotIn(('_launch_ssl_dialog', gethostname(), details),
1042 self.called)
1043 self.assertEqual(SAMPLE_RESOURCE, result.content)
1044
1045 def test_get_ssl_subject_details(self):
1031 """Assert that details are correctly formatted"""1046 """Assert that details are correctly formatted"""
1032 details = SSL_DETAILS_TEMPLATE % self.cert_details1047 self.assertEqual(self.cert_details,
1033 self.assertEqual(details,1048 self.wc.get_ssl_subject_details(self.ssl_settings['cert_info']))
1034 self.wc.format_ssl_details(self.cert_details))
10351049
1036 if WEBCLIENT_MODULE_NAME.endswith(".txweb"):1050 if WEBCLIENT_MODULE_NAME.endswith(".txweb"):
1037 reason = 'SSL support has not yet been implemented.'1051 reason = 'SSL support has not yet been implemented.'

Subscribers

People subscribed via source and target branches