def test_140_cas_remove_self_signed(self): """Test CAs merge """ extra_path = PKIDATA + '/fra_w-chain.pem' extra = QgsAuthCertUtils.casFromFile(extra_path) filtered = QgsAuthCertUtils.casRemoveSelfSigned(extra) self.assertEqual(len(filtered), 1) self.assertEqual(len(extra), 2) self.assertTrue(extra[1].isSelfSigned()) for c in filtered: self.assertFalse(c.isSelfSigned())
def mkPEMBundle(self, client_cert, client_key, password, chain): return QgsPkiBundle.fromPemPaths(PKIDATA + '/' + client_cert, PKIDATA + '/' + client_key, password, QgsAuthCertUtils.certsFromFile( PKIDATA + '/' + chain ))
def test_130_cas_merge(self): """Test CAs merge """ trusted_path = PKIDATA + '/subissuer_ca_cert.pem' extra_path = PKIDATA + '/fra_w-chain.pem' trusted = QgsAuthCertUtils.casFromFile(trusted_path) extra = QgsAuthCertUtils.casFromFile(extra_path) merged = QgsAuthCertUtils.casMerge(trusted, extra) self.assertEqual(len(trusted), 1) self.assertEqual(len(extra), 2) self.assertEqual(len(merged), 3) for c in extra: self.assertTrue(c in merged) self.assertTrue(trusted[0] in merged)
def test_120_pem_cas_from_file(self): """Test if CAs can be read from a pem bundle""" path = PKIDATA + '/fra_w-chain.pem' cas = QgsAuthCertUtils.casFromFile(path) self.assertEqual(cas[0].issuerInfo(b'CN'), ['QGIS Test Root CA']) self.assertEqual(cas[0].subjectInfo(b'CN'), ['QGIS Test Issuer CA']) self.assertEqual(cas[0].serialNumber(), b'02') self.assertEqual(cas[1].issuerInfo(b'CN'), ['QGIS Test Root CA']) self.assertEqual(cas[1].subjectInfo(b'CN'), ['QGIS Test Root CA']) self.assertEqual(cas[1].serialNumber(), b'01')
def test_110_pkcs12_cas(self): """Test if CAs can be read from a pkcs12 bundle""" path = PKIDATA + '/fra_w-chain.p12' cas = QgsAuthCertUtils.pkcs12BundleCas(path, 'password') self.assertEqual(cas[0].issuerInfo(b'CN'), ['QGIS Test Root CA']) self.assertEqual(cas[0].subjectInfo(b'CN'), ['QGIS Test Issuer CA']) self.assertEqual(cas[0].serialNumber(), b'02') self.assertEqual(cas[1].issuerInfo(b'CN'), ['QGIS Test Root CA']) self.assertEqual(cas[1].subjectInfo(b'CN'), ['QGIS Test Root CA']) self.assertEqual(cas[1].serialNumber(), b'01')
def test_150_verify_keychain(self): """Test the verify keychain function""" def testChain(path): # Test that a chain with an untrusted CA is not valid self.assertTrue(len(QgsAuthCertUtils.validateCertChain(QgsAuthCertUtils.certsFromFile(path))) > 0) # Test that a chain with an untrusted CA is valid when the addRootCa argument is true self.assertTrue(len(QgsAuthCertUtils.validateCertChain(QgsAuthCertUtils.certsFromFile(path), None, True)) == 0) # Test that a chain with an untrusted CA is not valid when the addRootCa argument is true # and a wrong domainis true self.assertTrue(len(QgsAuthCertUtils.validateCertChain(QgsAuthCertUtils.certsFromFile(path), 'my.wrong.domain', True)) > 0) testChain(PKIDATA + '/chain_subissuer-issuer-root.pem') testChain(PKIDATA + '/localhost_ssl_w-chain.pem') testChain(PKIDATA + '/fra_w-chain.pem') path = PKIDATA + '/localhost_ssl_w-chain.pem' # Test that a chain with an untrusted CA is not valid when the addRootCa argument is true # and a wrong domain is set self.assertTrue(len(QgsAuthCertUtils.validateCertChain(QgsAuthCertUtils.certsFromFile(path), 'my.wrong.domain', True)) > 0) # Test that a chain with an untrusted CA is valid when the addRootCa argument is true # and a right domain is set self.assertTrue(len(QgsAuthCertUtils.validateCertChain(QgsAuthCertUtils.certsFromFile(path), 'localhost', True)) == 0) # Test that a chain with an untrusted CA is not valid when the addRootCa argument is false # and a right domain is set self.assertTrue(len(QgsAuthCertUtils.validateCertChain(QgsAuthCertUtils.certsFromFile(path), 'localhost', False)) > 0)
def testChain(path): # Test that a chain with an untrusted CA is not valid self.assertTrue(len(QgsAuthCertUtils.validateCertChain(QgsAuthCertUtils.certsFromFile(path))) > 0) # Test that a chain with an untrusted CA is valid when the addRootCa argument is true self.assertTrue(len(QgsAuthCertUtils.validateCertChain(QgsAuthCertUtils.certsFromFile(path), None, True)) == 0) # Test that a chain with an untrusted CA is not valid when the addRootCa argument is true # and a wrong domainis true self.assertTrue(len(QgsAuthCertUtils.validateCertChain(QgsAuthCertUtils.certsFromFile(path), 'my.wrong.domain', True)) > 0)
def test_040_authorities(self): def rebuild_caches(): m = 'Authorities cache could not be rebuilt' self.assertTrue(self.authm.rebuildCaCertsCache(), m) m = 'Authorities trust policy cache could not be rebuilt' self.assertTrue(self.authm.rebuildTrustedCaCertsCache(), m) def trusted_ca_certs(): tr_certs = self.authm.getTrustedCaCerts() m = 'Trusted authorities cache is empty' self.assertIsNotNone(tr_certs, m) return tr_certs msg = 'No system root CAs' self.assertIsNotNone(self.authm.getSystemRootCAs()) # TODO: add more tests full_chain = 'chains_subissuer-issuer-root_issuer2-root2.pem' full_chain_path = os.path.join(PKIDATA, full_chain) # load CA file authorities for later comaprison # noinspection PyTypeChecker # ca_certs = QSslCertificate.fromPath(full_chain_path) ca_certs = QgsAuthCertUtils.certsFromFile(full_chain_path) msg = 'Authorities file could not be parsed' self.assertIsNotNone(ca_certs, msg) msg = 'Authorities file parsed count is incorrect' self.assertEqual(len(ca_certs), 5, msg) # first test CA file can be set and loaded msg = 'Authority file path setting could not be stored' self.assertTrue( self.authm.storeAuthSetting('cafile', full_chain_path), msg) msg = "Authority file 'allow invalids' setting could not be stored" self.assertTrue( self.authm.storeAuthSetting('cafileallowinvalid', False), msg) rebuild_caches() trusted_certs = trusted_ca_certs() not_cached = any([ca not in trusted_certs for ca in ca_certs]) msg = 'Authorities not in trusted authorities cache' self.assertFalse(not_cached, msg) # test CA file can be unset msg = 'Authority file path setting could not be removed' self.assertTrue(self.authm.removeAuthSetting('cafile'), msg) msg = "Authority file 'allow invalids' setting could not be removed" self.assertTrue( self.authm.removeAuthSetting('cafileallowinvalid'), msg) rebuild_caches() trusted_certs = trusted_ca_certs() still_cached = any([ca in trusted_certs for ca in ca_certs]) msg = 'Authorities still in trusted authorities cache' self.assertFalse(still_cached, msg) # test CAs can be stored in database msg = "Authority certs could not be stored in database" self.assertTrue(self.authm.storeCertAuthorities(ca_certs)) rebuild_caches() trusted_certs = trusted_ca_certs() not_cached = any([ca not in trusted_certs for ca in ca_certs]) msg = 'Stored authorities not in trusted authorities cache' self.assertFalse(not_cached, msg)
def test_170_pki_key_encoding(self): """Test that a DER/PEM RSA/DSA/EC keys can be opened whatever the extension is""" self.assertFalse(QgsAuthCertUtils.keyFromFile(PKIDATA + '/' + 'ptolemy_key.pem').isNull()) self.assertFalse(QgsAuthCertUtils.keyFromFile(PKIDATA + '/' + 'ptolemy_key.der').isNull()) self.assertFalse(QgsAuthCertUtils.keyFromFile(PKIDATA + '/' + 'ptolemy_key_pem.key').isNull()) self.assertFalse(QgsAuthCertUtils.keyFromFile(PKIDATA + '/' + 'ptolemy_key_der.key').isNull()) self.assertFalse(QgsAuthCertUtils.keyFromFile(PKIDATA + '/' + 'donald_key_EC.pem').isNull()) self.assertFalse(QgsAuthCertUtils.keyFromFile(PKIDATA + '/' + 'donald_key_EC.der').isNull()) self.assertFalse(QgsAuthCertUtils.keyFromFile(PKIDATA + '/' + 'donald_key_DSA.pem').isNull()) self.assertFalse(QgsAuthCertUtils.keyFromFile(PKIDATA + '/' + 'donald_key_DSA.der').isNull()) self.assertFalse(QgsAuthCertUtils.keyFromFile(PKIDATA + '/' + 'donald_key_DSA_crlf.pem').isNull()) self.assertFalse(QgsAuthCertUtils.keyFromFile(PKIDATA + '/' + 'donald_key_DSA_nonl.pem').isNull()) donald_dsa = QgsAuthCertUtils.keyFromFile(PKIDATA + '/' + 'donald_key_DSA.pem').toPem() self.assertEqual(donald_dsa, QgsAuthCertUtils.keyFromFile(PKIDATA + '/' + 'donald_key_DSA.der').toPem()) self.assertEqual(donald_dsa, QgsAuthCertUtils.keyFromFile(PKIDATA + '/' + 'donald_key_DSA_crlf.pem').toPem()) self.assertEqual(donald_dsa, QgsAuthCertUtils.keyFromFile(PKIDATA + '/' + 'donald_key_DSA_nonl.pem').toPem()) self.assertEqual(QgsAuthCertUtils.validatePKIBundle(self.mkPEMBundle('ptolemy_cert.pem', 'ptolemy_key.pem', 'password', 'chain_subissuer-issuer-root.pem'), True, True), []) self.assertEqual(QgsAuthCertUtils.validatePKIBundle(self.mkPEMBundle('ptolemy_cert.pem', 'ptolemy_key.der', 'password', 'chain_subissuer-issuer-root.pem'), True, True), []) self.assertEqual(QgsAuthCertUtils.validatePKIBundle(self.mkPEMBundle('ptolemy_cert.pem', 'ptolemy_key_pem.key', 'password', 'chain_subissuer-issuer-root.pem'), True, True), []) self.assertEqual(QgsAuthCertUtils.validatePKIBundle(self.mkPEMBundle('ptolemy_cert.pem', 'ptolemy_key_der.key', 'password', 'chain_subissuer-issuer-root.pem'), True, True), [])
def test_070_servers(self): # return ssl_cert_path = os.path.join(PKIDATA, 'localhost_ssl_cert.pem') ssl_cert = QgsAuthCertUtils.certsFromFile(ssl_cert_path)[0] msg = 'SSL server certificate is null' self.assertFalse(ssl_cert.isNull(), msg) cert_sha = QgsAuthCertUtils.shaHexForCert(ssl_cert) hostport = 'localhost:8443' config = QgsAuthConfigSslServer() config.setSslCertificate(ssl_cert) config.setSslHostPort(hostport) config.setSslIgnoredErrorEnums([QSslError.SelfSignedCertificate]) config.setSslPeerVerifyMode(QSslSocket.VerifyNone) config.setSslPeerVerifyDepth(3) config.setSslProtocol(QSsl.TlsV1_1) msg = 'SSL config is null' self.assertFalse(config.isNull(), msg) msg = 'Could not store SSL config' self.assertTrue(self.authm.storeSslCertCustomConfig(config), msg) msg = 'Could not verify storage of SSL config' self.assertTrue( self.authm.existsSslCertCustomConfig(cert_sha, hostport), msg) msg = 'Could not verify SSL config in all configs' self.assertIsNotNone(self.authm.sslCertCustomConfigs(), msg) msg = 'Could not retrieve SSL config' config2 = self.authm.sslCertCustomConfig(cert_sha, hostport) """:type: QgsAuthConfigSslServer""" self.assertFalse(config2.isNull(), msg) msg = 'Certificate of retrieved SSL config does not match' self.assertEqual(config.sslCertificate(), config2.sslCertificate(), msg) msg = 'HostPort of retrieved SSL config does not match' self.assertEqual(config.sslHostPort(), config2.sslHostPort(), msg) msg = 'IgnoredErrorEnums of retrieved SSL config does not match' enums = config2.sslIgnoredErrorEnums() self.assertTrue(QSslError.SelfSignedCertificate in enums, msg) msg = 'PeerVerifyMode of retrieved SSL config does not match' self.assertEqual(config.sslPeerVerifyMode(), config2.sslPeerVerifyMode(), msg) msg = 'PeerVerifyDepth of retrieved SSL config does not match' self.assertEqual(config.sslPeerVerifyDepth(), config2.sslPeerVerifyDepth(), msg) msg = 'Protocol of retrieved SSL config does not match' self.assertEqual(config.sslProtocol(), config2.sslProtocol(), msg) # dlg = QgsAuthSslConfigDialog(None, ssl_cert, hostport) # dlg.exec_() msg = 'Could not remove SSL config' self.assertTrue( self.authm.removeSslCertCustomConfig(cert_sha, hostport), msg) msg = 'Could not verify removal of SSL config' self.assertFalse( self.authm.existsSslCertCustomConfig(cert_sha, hostport), msg)
def test_160_cert_viable(self): """Text the viability of a given certificate""" # null cert cert = QSslCertificate() self.assertFalse(QgsAuthCertUtils.certIsCurrent(cert)) res = QgsAuthCertUtils.certViabilityErrors(cert) self.assertTrue(len(res) == 0) self.assertFalse(QgsAuthCertUtils.certIsViable(cert)) cert.clear() res.clear() # valid cert cert = QgsAuthCertUtils.certFromFile(PKIDATA + '/gerardus_cert.pem') self.assertTrue(QgsAuthCertUtils.certIsCurrent(cert)) res = QgsAuthCertUtils.certViabilityErrors(cert) self.assertTrue(len(res) == 0) self.assertTrue(QgsAuthCertUtils.certIsViable(cert)) cert.clear() res.clear() # expired cert cert = QgsAuthCertUtils.certFromFile(PKIDATA + '/marinus_cert-EXPIRED.pem') self.assertFalse(QgsAuthCertUtils.certIsCurrent(cert)) res = QgsAuthCertUtils.certViabilityErrors(cert) self.assertTrue(len(res) > 0) self.assertTrue(QSslError(QSslError.CertificateExpired, cert) in res) self.assertFalse(QgsAuthCertUtils.certIsViable(cert))
def test_validate_pki_bundle(self): """Text the pki bundle validation""" # Valid bundle: bundle = self.mkPEMBundle('fra_cert.pem', 'fra_key.pem', 'password', 'chain_subissuer-issuer-root.pem') # Test valid bundle with intermediates and without trusted root self.assertEqual(QgsAuthCertUtils.validatePKIBundle(bundle), ['The root certificate of the certificate chain is self-signed, and untrusted']) # Test valid without intermediates self.assertEqual(QgsAuthCertUtils.validatePKIBundle(bundle, False), ['The issuer certificate of a locally looked up certificate could not be found', 'No certificates could be verified']) # Test valid with intermediates and trusted root self.assertEqual(QgsAuthCertUtils.validatePKIBundle(bundle, True, True), []) # Wrong chain bundle = self.mkPEMBundle('fra_cert.pem', 'fra_key.pem', 'password', 'chain_issuer2-root2.pem') # Test invalid bundle with intermediates and without trusted root self.assertEqual(QgsAuthCertUtils.validatePKIBundle(bundle), ['The issuer certificate of a locally looked up certificate could not be found', 'No certificates could be verified']) # Test valid without intermediates self.assertEqual(QgsAuthCertUtils.validatePKIBundle(bundle, False), ['The issuer certificate of a locally looked up certificate could not be found', 'No certificates could be verified']) # Test valid with intermediates and trusted root self.assertEqual(QgsAuthCertUtils.validatePKIBundle(bundle, True, True), ['The issuer certificate of a locally looked up certificate could not be found', 'No certificates could be verified']) # Wrong key bundle = self.mkPEMBundle('fra_cert.pem', 'ptolemy_key.pem', 'password', 'chain_subissuer-issuer-root.pem') # Test invalid bundle with intermediates and without trusted root self.assertEqual(QgsAuthCertUtils.validatePKIBundle(bundle), ['The root certificate of the certificate chain is self-signed, and untrusted', 'Private key does not match client certificate public key.']) # Test invalid without intermediates self.assertEqual(QgsAuthCertUtils.validatePKIBundle(bundle, False), ['The issuer certificate of a locally looked up certificate could not be found', 'No certificates could be verified', 'Private key does not match client certificate public key.']) # Test invalid with intermediates and trusted root self.assertEqual(QgsAuthCertUtils.validatePKIBundle(bundle, True, True), ['Private key does not match client certificate public key.']) # Expired root CA bundle = self.mkPEMBundle('piri_cert.pem', 'piri_key.pem', 'password', 'chain_issuer3-root3-EXPIRED.pem') self.assertEqual(QgsAuthCertUtils.validatePKIBundle(bundle), ['The root certificate of the certificate chain is self-signed, and untrusted', 'The certificate has expired']) self.assertEqual(QgsAuthCertUtils.validatePKIBundle(bundle, False), ['The issuer certificate of a locally looked up certificate could not be found', 'No certificates could be verified']) self.assertEqual(QgsAuthCertUtils.validatePKIBundle(bundle, True, True), ['The root certificate of the certificate chain is self-signed, and untrusted', 'The certificate has expired']) # Expired intermediate CA bundle = self.mkPEMBundle('marinus_cert-EXPIRED.pem', 'marinus_key_w-pass.pem', 'password', 'chain_issuer2-root2.pem') self.assertEqual(QgsAuthCertUtils.validatePKIBundle(bundle), ['The root certificate of the certificate chain is self-signed, and untrusted', 'The certificate has expired']) self.assertEqual(QgsAuthCertUtils.validatePKIBundle(bundle, False), ['The issuer certificate of a locally looked up certificate could not be found', 'No certificates could be verified']) self.assertEqual(QgsAuthCertUtils.validatePKIBundle(bundle, True, True), ['The certificate has expired']) # Expired client cert bundle = self.mkPEMBundle('henricus_cert.pem', 'henricus_key_w-pass.pem', 'password', 'chain_issuer4-EXPIRED-root2.pem') self.assertEqual(QgsAuthCertUtils.validatePKIBundle(bundle), ['The root certificate of the certificate chain is self-signed, and untrusted', 'The certificate has expired']) self.assertEqual(QgsAuthCertUtils.validatePKIBundle(bundle, False), ['The issuer certificate of a locally looked up certificate could not be found', 'No certificates could be verified']) self.assertEqual(QgsAuthCertUtils.validatePKIBundle(bundle, True, True), ['The certificate has expired']) # Untrusted root, positive test before untrust is applied bundle = self.mkPEMBundle('nicholas_cert.pem', 'nicholas_key.pem', 'password', 'chain_issuer2-root2.pem') # Test valid with intermediates and trusted root self.assertEqual(QgsAuthCertUtils.validatePKIBundle(bundle, True, True), []) # Untrust this root root2 = QgsAuthCertUtils.certFromFile(PKIDATA + '/' + 'root2_ca_cert.pem') QgsApplication.authManager().storeCertAuthority(root2) self.assertTrue(QgsApplication.authManager().storeCertTrustPolicy(root2, QgsAuthCertUtils.Untrusted)) QgsApplication.authManager().rebuildCaCertsCache() # Test valid with intermediates and untrusted root self.assertEqual(QgsAuthCertUtils.validatePKIBundle(bundle, True, True), ['The issuer certificate of a locally looked up certificate could not be found'])
def test_060_identities(self): client_cert_path = os.path.join(PKIDATA, 'fra_cert.pem') client_key_path = os.path.join(PKIDATA, 'fra_key_w-pass.pem') client_key_pass = '******' client_p12_path = os.path.join(PKIDATA, 'gerardus_w-chain.p12') client_p12_pass = '******' # store regular PEM cert/key and generate config # noinspection PyTypeChecker bundle1 = QgsPkiBundle.fromPemPaths(client_cert_path, client_key_path, client_key_pass) bundle1_cert = bundle1.clientCert() bundle1_key = bundle1.clientKey() bundle1_ca_chain = bundle1.caChain() bundle1_cert_sha = bundle1.certId() # with open(client_key_path, 'r') as f: # key_data = f.read() # # client_cert = QgsAuthCertUtils.certsFromFile(client_cert_path)[0] msg = 'Identity PEM certificate is null' self.assertFalse(bundle1_cert.isNull(), msg) # cert_sha = QgsAuthCertUtils.shaHexForCert(client_cert) # # client_key = QSslKey(key_data, QSsl.Rsa, QSsl.Pem, # QSsl.PrivateKey, client_key_pass) msg = 'Identity PEM key is null' self.assertFalse(bundle1_key.isNull(), msg) msg = 'Identity PEM certificate chain is not empty' self.assertEqual(len(bundle1_ca_chain), 0, msg) msg = "Identity PEM could not be stored in database" self.assertTrue( self.authm.storeCertIdentity(bundle1_cert, bundle1_key), msg) msg = "Identity PEM not found in database" self.assertTrue(self.authm.existsCertIdentity(bundle1_cert_sha), msg) config1 = QgsAuthMethodConfig() config1.setName('IdentityCert - PEM') config1.setMethod('Identity-Cert') config1.setConfig('certid', bundle1_cert_sha) msg = 'Could not store PEM identity config' self.assertTrue(self.authm.storeAuthenticationConfig(config1), msg) configid1 = config1.id() msg = 'Could not retrieve PEM identity config id from store op' self.assertIsNotNone(configid1, msg) config2 = QgsAuthMethodConfig() msg = 'Could not load PEM identity config' self.assertTrue( self.authm.loadAuthenticationConfig(configid1, config2, True), msg) # store PKCS#12 bundled cert/key and generate config # bundle = QgsPkcsBundle(client_p12_path, client_p12_pass) # noinspection PyTypeChecker bundle = QgsPkiBundle.fromPkcs12Paths(client_p12_path, client_p12_pass) bundle_cert = bundle.clientCert() bundle_key = bundle.clientKey() bundle_ca_chain = bundle.caChain() bundle_cert_sha = QgsAuthCertUtils.shaHexForCert(bundle_cert) msg = 'Identity bundle certificate is null' self.assertFalse(bundle_cert.isNull(), msg) msg = 'Identity bundle key is null' self.assertFalse(bundle_key.isNull(), msg) msg = 'Identity bundle CA chain is not correct depth' self.assertEqual(len(bundle_ca_chain), 3, msg) msg = "Identity bundle could not be stored in database" self.assertTrue(self.authm.storeCertIdentity(bundle_cert, bundle_key), msg) msg = "Identity bundle not found in database" self.assertTrue(self.authm.existsCertIdentity(bundle_cert_sha), msg) bundle_config = QgsAuthMethodConfig() bundle_config.setName('IdentityCert - Bundle') bundle_config.setMethod('Identity-Cert') bundle_config.setConfig('certid', bundle_cert_sha) msg = 'Could not store bundle identity config' self.assertTrue(self.authm.storeAuthenticationConfig(bundle_config), msg) bundle_configid = bundle_config.id() msg = 'Could not retrieve bundle identity config id from store op' self.assertIsNotNone(bundle_configid, msg) bundle_config2 = QgsAuthMethodConfig() msg = 'Could not load bundle identity config' self.assertTrue( self.authm.loadAuthenticationConfig(bundle_configid, bundle_config2, True), msg) # TODO: add more tests # self.show_editors_widget() msg = 'Could not remove PEM identity config' self.assertTrue(self.authm.removeAuthenticationConfig(configid1), msg) msg = 'Could not remove bundle identity config' self.assertTrue(self.authm.removeAuthenticationConfig(bundle_configid), msg)
def test_060_identities(self): client_cert_path = os.path.join(PKIDATA, 'fra_cert.pem') client_key_path = os.path.join(PKIDATA, 'fra_key_w-pass.pem') client_key_pass = '******' client_p12_path = os.path.join(PKIDATA, 'gerardus_w-chain.p12') client_p12_pass = '******' # store regular PEM cert/key and generate config # noinspection PyTypeChecker bundle1 = QgsPkiBundle.fromPemPaths(client_cert_path, client_key_path, client_key_pass) bundle1_cert = bundle1.clientCert() bundle1_key = bundle1.clientKey() bundle1_ca_chain = bundle1.caChain() bundle1_cert_sha = bundle1.certId() # with open(client_key_path, 'r') as f: # key_data = f.read() # # client_cert = QgsAuthCertUtils.certsFromFile(client_cert_path)[0] msg = 'Identity PEM certificate is null' self.assertFalse(bundle1_cert.isNull(), msg) # cert_sha = QgsAuthCertUtils.shaHexForCert(client_cert) # # client_key = QSslKey(key_data, QSsl.Rsa, QSsl.Pem, # QSsl.PrivateKey, client_key_pass) msg = 'Identity PEM key is null' self.assertFalse(bundle1_key.isNull(), msg) msg = 'Identity PEM certificate chain is not empty' self.assertEqual(len(bundle1_ca_chain), 0, msg) msg = "Identity PEM could not be stored in database" self.assertTrue( self.authm.storeCertIdentity(bundle1_cert, bundle1_key), msg) msg = "Identity PEM not found in database" self.assertTrue(self.authm.existsCertIdentity(bundle1_cert_sha), msg) config1 = QgsAuthMethodConfig() config1.setName('IdentityCert - PEM') config1.setMethod('Identity-Cert') config1.setConfig('certid', bundle1_cert_sha) msg = 'Could not store PEM identity config' self.assertTrue(self.authm.storeAuthenticationConfig(config1), msg) configid1 = config1.id() msg = 'Could not retrieve PEM identity config id from store op' self.assertIsNotNone(configid1, msg) config2 = QgsAuthMethodConfig() msg = 'Could not load PEM identity config' self.assertTrue( self.authm.loadAuthenticationConfig(configid1, config2, True), msg) # store PKCS#12 bundled cert/key and generate config # bundle = QgsPkcsBundle(client_p12_path, client_p12_pass) # noinspection PyTypeChecker bundle = QgsPkiBundle.fromPkcs12Paths(client_p12_path, client_p12_pass) bundle_cert = bundle.clientCert() bundle_key = bundle.clientKey() bundle_ca_chain = bundle.caChain() bundle_cert_sha = QgsAuthCertUtils.shaHexForCert(bundle_cert) msg = 'Identity bundle certificate is null' self.assertFalse(bundle_cert.isNull(), msg) msg = 'Identity bundle key is null' self.assertFalse(bundle_key.isNull(), msg) msg = 'Identity bundle CA chain is not correct depth' self.assertEqual(len(bundle_ca_chain), 3, msg) msg = "Identity bundle could not be stored in database" self.assertTrue( self.authm.storeCertIdentity(bundle_cert, bundle_key), msg) msg = "Identity bundle not found in database" self.assertTrue(self.authm.existsCertIdentity(bundle_cert_sha), msg) bundle_config = QgsAuthMethodConfig() bundle_config.setName('IdentityCert - Bundle') bundle_config.setMethod('Identity-Cert') bundle_config.setConfig('certid', bundle_cert_sha) msg = 'Could not store bundle identity config' self.assertTrue( self.authm.storeAuthenticationConfig(bundle_config), msg) bundle_configid = bundle_config.id() msg = 'Could not retrieve bundle identity config id from store op' self.assertIsNotNone(bundle_configid, msg) bundle_config2 = QgsAuthMethodConfig() msg = 'Could not load bundle identity config' self.assertTrue( self.authm.loadAuthenticationConfig(bundle_configid, bundle_config2, True), msg) # TODO: add more tests # self.show_editors_widget() msg = 'Could not remove PEM identity config' self.assertTrue(self.authm.removeAuthenticationConfig(configid1), msg) msg = 'Could not remove bundle identity config' self.assertTrue( self.authm.removeAuthenticationConfig(bundle_configid), msg)
def test_170_pki_key_encoding(self): """Test that a DER/PEM RSA/DSA/EC keys can be opened whatever the extension is""" self.assertFalse( QgsAuthCertUtils.keyFromFile(PKIDATA + '/' + 'ptolemy_key.pem').isNull()) self.assertFalse( QgsAuthCertUtils.keyFromFile(PKIDATA + '/' + 'ptolemy_key.der').isNull()) self.assertFalse( QgsAuthCertUtils.keyFromFile(PKIDATA + '/' + 'ptolemy_key_pem.key').isNull()) self.assertFalse( QgsAuthCertUtils.keyFromFile(PKIDATA + '/' + 'ptolemy_key_der.key').isNull()) self.assertFalse( QgsAuthCertUtils.keyFromFile(PKIDATA + '/' + 'donald_key_EC.pem').isNull()) self.assertFalse( QgsAuthCertUtils.keyFromFile(PKIDATA + '/' + 'donald_key_EC.der').isNull()) self.assertFalse( QgsAuthCertUtils.keyFromFile(PKIDATA + '/' + 'donald_key_DSA.pem').isNull()) self.assertFalse( QgsAuthCertUtils.keyFromFile(PKIDATA + '/' + 'donald_key_DSA.der').isNull()) self.assertFalse( QgsAuthCertUtils.keyFromFile(PKIDATA + '/' + 'donald_key_DSA_crlf.pem').isNull()) self.assertFalse( QgsAuthCertUtils.keyFromFile(PKIDATA + '/' + 'donald_key_DSA_nonl.pem').isNull()) donald_dsa = QgsAuthCertUtils.keyFromFile( PKIDATA + '/' + 'donald_key_DSA.pem').toPem() self.assertEqual( donald_dsa, QgsAuthCertUtils.keyFromFile(PKIDATA + '/' + 'donald_key_DSA.der').toPem()) self.assertEqual( donald_dsa, QgsAuthCertUtils.keyFromFile(PKIDATA + '/' + 'donald_key_DSA_crlf.pem').toPem()) self.assertEqual( donald_dsa, QgsAuthCertUtils.keyFromFile(PKIDATA + '/' + 'donald_key_DSA_nonl.pem').toPem()) self.assertEqual( QgsAuthCertUtils.validatePKIBundle( self.mkPEMBundle('ptolemy_cert.pem', 'ptolemy_key.pem', 'password', 'chain_subissuer-issuer-root.pem'), True, True), []) self.assertEqual( QgsAuthCertUtils.validatePKIBundle( self.mkPEMBundle('ptolemy_cert.pem', 'ptolemy_key.der', 'password', 'chain_subissuer-issuer-root.pem'), True, True), []) self.assertEqual( QgsAuthCertUtils.validatePKIBundle( self.mkPEMBundle('ptolemy_cert.pem', 'ptolemy_key_pem.key', 'password', 'chain_subissuer-issuer-root.pem'), True, True), []) self.assertEqual( QgsAuthCertUtils.validatePKIBundle( self.mkPEMBundle('ptolemy_cert.pem', 'ptolemy_key_der.key', 'password', 'chain_subissuer-issuer-root.pem'), True, True), [])
def mkPEMBundle(self, client_cert, client_key, password, chain): return QgsPkiBundle.fromPemPaths( PKIDATA + '/' + client_cert, PKIDATA + '/' + client_key, password, QgsAuthCertUtils.certsFromFile(PKIDATA + '/' + chain))
def test_validate_pki_bundle(self): """Text the pki bundle validation""" # Valid bundle: bundle = self.mkPEMBundle('fra_cert.pem', 'fra_key.pem', 'password', 'chain_subissuer-issuer-root.pem') # Test valid bundle with intermediates and without trusted root self.assertEqual(QgsAuthCertUtils.validatePKIBundle(bundle), [ 'The root certificate of the certificate chain is self-signed, and untrusted' ]) # Test valid without intermediates self.assertEqual(QgsAuthCertUtils.validatePKIBundle(bundle, False), [ 'The issuer certificate of a locally looked up certificate could not be found', 'No certificates could be verified' ]) # Test valid with intermediates and trusted root self.assertEqual( QgsAuthCertUtils.validatePKIBundle(bundle, True, True), []) # Wrong chain bundle = self.mkPEMBundle('fra_cert.pem', 'fra_key.pem', 'password', 'chain_issuer2-root2.pem') # Test invalid bundle with intermediates and without trusted root self.assertEqual(QgsAuthCertUtils.validatePKIBundle(bundle), [ 'The issuer certificate of a locally looked up certificate could not be found', 'No certificates could be verified' ]) # Test valid without intermediates self.assertEqual(QgsAuthCertUtils.validatePKIBundle(bundle, False), [ 'The issuer certificate of a locally looked up certificate could not be found', 'No certificates could be verified' ]) # Test valid with intermediates and trusted root self.assertEqual( QgsAuthCertUtils.validatePKIBundle(bundle, True, True), [ 'The issuer certificate of a locally looked up certificate could not be found', 'No certificates could be verified' ]) # Wrong key bundle = self.mkPEMBundle('fra_cert.pem', 'ptolemy_key.pem', 'password', 'chain_subissuer-issuer-root.pem') # Test invalid bundle with intermediates and without trusted root self.assertEqual(QgsAuthCertUtils.validatePKIBundle(bundle), [ 'The root certificate of the certificate chain is self-signed, and untrusted', 'Private key does not match client certificate public key.' ]) # Test invalid without intermediates self.assertEqual(QgsAuthCertUtils.validatePKIBundle(bundle, False), [ 'The issuer certificate of a locally looked up certificate could not be found', 'No certificates could be verified', 'Private key does not match client certificate public key.' ]) # Test invalid with intermediates and trusted root self.assertEqual( QgsAuthCertUtils.validatePKIBundle(bundle, True, True), ['Private key does not match client certificate public key.']) # Expired root CA bundle = self.mkPEMBundle('piri_cert.pem', 'piri_key.pem', 'password', 'chain_issuer3-root3-EXPIRED.pem') self.assertEqual(QgsAuthCertUtils.validatePKIBundle(bundle), [ 'The root certificate of the certificate chain is self-signed, and untrusted', 'The certificate has expired' ]) self.assertEqual(QgsAuthCertUtils.validatePKIBundle(bundle, False), [ 'The issuer certificate of a locally looked up certificate could not be found', 'No certificates could be verified' ]) self.assertEqual( QgsAuthCertUtils.validatePKIBundle(bundle, True, True), [ 'The root certificate of the certificate chain is self-signed, and untrusted', 'The certificate has expired' ]) # Expired intermediate CA bundle = self.mkPEMBundle('marinus_cert-EXPIRED.pem', 'marinus_key_w-pass.pem', 'password', 'chain_issuer2-root2.pem') self.assertEqual(QgsAuthCertUtils.validatePKIBundle(bundle), [ 'The root certificate of the certificate chain is self-signed, and untrusted', 'The certificate has expired' ]) self.assertEqual(QgsAuthCertUtils.validatePKIBundle(bundle, False), [ 'The issuer certificate of a locally looked up certificate could not be found', 'No certificates could be verified' ]) self.assertEqual( QgsAuthCertUtils.validatePKIBundle(bundle, True, True), ['The certificate has expired']) # Expired client cert bundle = self.mkPEMBundle('henricus_cert.pem', 'henricus_key_w-pass.pem', 'password', 'chain_issuer4-EXPIRED-root2.pem') self.assertEqual(QgsAuthCertUtils.validatePKIBundle(bundle), [ 'The root certificate of the certificate chain is self-signed, and untrusted', 'The certificate has expired' ]) self.assertEqual(QgsAuthCertUtils.validatePKIBundle(bundle, False), [ 'The issuer certificate of a locally looked up certificate could not be found', 'No certificates could be verified' ]) self.assertEqual( QgsAuthCertUtils.validatePKIBundle(bundle, True, True), ['The certificate has expired']) # Untrusted root, positive test before untrust is applied bundle = self.mkPEMBundle('nicholas_cert.pem', 'nicholas_key.pem', 'password', 'chain_issuer2-root2.pem') # Test valid with intermediates and trusted root self.assertEqual( QgsAuthCertUtils.validatePKIBundle(bundle, True, True), []) # Untrust this root root2 = QgsAuthCertUtils.certFromFile(PKIDATA + '/' + 'root2_ca_cert.pem') QgsApplication.authManager().storeCertAuthority(root2) self.assertTrue(QgsApplication.authManager().storeCertTrustPolicy( root2, QgsAuthCertUtils.Untrusted)) QgsApplication.authManager().rebuildCaCertsCache() # Test valid with intermediates and untrusted root self.assertEqual( QgsAuthCertUtils.validatePKIBundle(bundle, True, True), [ 'The issuer certificate of a locally looked up certificate could not be found' ])
def test_070_servers(self): # return ssl_cert_path = os.path.join(PKIDATA, 'localhost_ssl_cert.pem') ssl_cert = QgsAuthCertUtils.certsFromFile(ssl_cert_path)[0] msg = 'SSL server certificate is null' self.assertFalse(ssl_cert.isNull(), msg) cert_sha = QgsAuthCertUtils.shaHexForCert(ssl_cert) hostport = 'localhost:8443' config = QgsAuthConfigSslServer() config.setSslCertificate(ssl_cert) config.setSslHostPort(hostport) config.setSslIgnoredErrorEnums([QSslError.SelfSignedCertificate]) config.setSslPeerVerifyMode(QSslSocket.VerifyNone) config.setSslPeerVerifyDepth(3) config.setSslProtocol(QSsl.TlsV1) msg = 'SSL config is null' self.assertFalse(config.isNull(), msg) msg = 'Could not store SSL config' self.assertTrue(self.authm.storeSslCertCustomConfig(config), msg) msg = 'Could not verify storage of SSL config' self.assertTrue( self.authm.existsSslCertCustomConfig(cert_sha, hostport), msg) msg = 'Could not verify SSL config in all configs' self.assertIsNotNone(self.authm.getSslCertCustomConfigs(), msg) msg = 'Could not retrieve SSL config' config2 = self.authm.getSslCertCustomConfig(cert_sha, hostport) """:type: QgsAuthConfigSslServer""" self.assertFalse(config2.isNull(), msg) msg = 'Certificate of retrieved SSL config does not match' self.assertEqual(config.sslCertificate(), config2.sslCertificate(), msg) msg = 'HostPort of retrieved SSL config does not match' self.assertEqual(config.sslHostPort(), config2.sslHostPort(), msg) msg = 'IgnoredErrorEnums of retrieved SSL config does not match' enums = config2.sslIgnoredErrorEnums() self.assertTrue(QSslError.SelfSignedCertificate in enums, msg) msg = 'PeerVerifyMode of retrieved SSL config does not match' self.assertEqual(config.sslPeerVerifyMode(), config2.sslPeerVerifyMode(), msg) msg = 'PeerVerifyDepth of retrieved SSL config does not match' self.assertEqual(config.sslPeerVerifyDepth(), config2.sslPeerVerifyDepth(), msg) msg = 'Protocol of retrieved SSL config does not match' self.assertEqual(config.sslProtocol(), config2.sslProtocol(), msg) # dlg = QgsAuthSslConfigDialog(None, ssl_cert, hostport) # dlg.exec_() msg = 'Could not remove SSL config' self.assertTrue( self.authm.removeSslCertCustomConfig(cert_sha, hostport), msg) msg = 'Could not verify removal of SSL config' self.assertFalse( self.authm.existsSslCertCustomConfig(cert_sha, hostport), msg)
def test_040_authorities(self): def rebuild_caches(): m = 'Authorities cache could not be rebuilt' self.assertTrue(self.authm.rebuildCaCertsCache(), m) m = 'Authorities trust policy cache could not be rebuilt' self.assertTrue(self.authm.rebuildTrustedCaCertsCache(), m) def trusted_ca_certs(): tr_certs = self.authm.trustedCaCerts() m = 'Trusted authorities cache is empty' self.assertIsNotNone(tr_certs, m) return tr_certs msg = 'No system root CAs' self.assertIsNotNone(self.authm.systemRootCAs()) # TODO: add more tests full_chain = 'chains_subissuer-issuer-root_issuer2-root2.pem' full_chain_path = os.path.join(PKIDATA, full_chain) # load CA file authorities for later comaprison # noinspection PyTypeChecker # ca_certs = QSslCertificate.fromPath(full_chain_path) ca_certs = QgsAuthCertUtils.certsFromFile(full_chain_path) msg = 'Authorities file could not be parsed' self.assertIsNotNone(ca_certs, msg) msg = 'Authorities file parsed count is incorrect' self.assertEqual(len(ca_certs), 5, msg) # first test CA file can be set and loaded msg = 'Authority file path setting could not be stored' self.assertTrue(self.authm.storeAuthSetting('cafile', full_chain_path), msg) msg = "Authority file 'allow invalids' setting could not be stored" self.assertTrue( self.authm.storeAuthSetting('cafileallowinvalid', False), msg) rebuild_caches() trusted_certs = trusted_ca_certs() not_cached = any([ca not in trusted_certs for ca in ca_certs]) msg = 'Authorities not in trusted authorities cache' self.assertFalse(not_cached, msg) # test CA file can be unset msg = 'Authority file path setting could not be removed' self.assertTrue(self.authm.removeAuthSetting('cafile'), msg) msg = "Authority file 'allow invalids' setting could not be removed" self.assertTrue(self.authm.removeAuthSetting('cafileallowinvalid'), msg) rebuild_caches() trusted_certs = trusted_ca_certs() still_cached = any([ca in trusted_certs for ca in ca_certs]) msg = 'Authorities still in trusted authorities cache' self.assertFalse(still_cached, msg) # test CAs can be stored in database msg = "Authority certs could not be stored in database" self.assertTrue(self.authm.storeCertAuthorities(ca_certs)) rebuild_caches() trusted_certs = trusted_ca_certs() not_cached = any([ca not in trusted_certs for ca in ca_certs]) msg = 'Stored authorities not in trusted authorities cache' self.assertFalse(not_cached, msg)